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"
29f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie
30d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <inttypes.h>
31d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <math.h>
32d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
332110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie#include <AudioPolicyManagerInterface.h>
342110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie#include <AudioPolicyEngineInstance.h>
3505d19b08f3affa6fa8407e779f67e7ad1c1ca84fMathias Agopian#include <cutils/atomic.h>
36d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <cutils/properties.h>
37e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <utils/Log.h>
383b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h>
39e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent#include <media/AudioPolicyHelper.h>
40df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <soundtrigger/SoundTrigger.h>
41cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov#include <system/audio.h>
429ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov#include <audio_policy_conf.h>
43d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h"
44d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#ifndef USE_XML_AUDIO_POLICY_CONF
4553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <ConfigParsingUtils.h>
46d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <StreamDescriptor.h>
47f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#endif
48d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <Serializer.h>
49a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie#include "TypeConverter.h"
5053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <policy.h>
51e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
523b73df74357b33869b39a1d69427673c780bd805Eric Laurentnamespace android {
53e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
54dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent//FIXME: workaround for truncated touch sounds
55dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent// to be removed when the problem is handled by system UI
56dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent#define TOUCH_SOUND_FIXED_DELAY_MS 100
57e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
58e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation
59e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
60e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
61e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
62e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      audio_policy_dev_state_t state,
63e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      const char *device_address,
64e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      const char *device_name)
65e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
66e743a47f445f02a0612018fa5640301304844fbfPaul McLean    return setDeviceConnectionStateInt(device, state, device_address, device_name);
67c73ca6ef04136f28306784ad35f444538f081957Eric Laurent}
68c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
6944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffievoid AudioPolicyManager::broadcastDeviceConnectionState(audio_devices_t device,
7044481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                                        audio_policy_dev_state_t state,
7144481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                                        const String8 &device_address)
7244481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie{
7344481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    AudioParameter param(device_address);
7444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
75388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect);
7644481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    param.addInt(key, device);
7744481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie    mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
7844481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie}
7944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
80c73ca6ef04136f28306784ad35f444538f081957Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
81a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent                                                         audio_policy_dev_state_t state,
82e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                         const char *device_address,
83e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                         const char *device_name)
84c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{
85e743a47f445f02a0612018fa5640301304844fbfPaul McLean    ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
86e743a47f445f02a0612018fa5640301304844fbfPaul McLean-            device, state, device_address, device_name);
87e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
88e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // connect/disconnect only 1 device at a time
89e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
90e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
9153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    sp<DeviceDescriptor> devDesc =
9253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            mHwModules.getDeviceDescriptor(device, device_address, device_name);
93e743a47f445f02a0612018fa5640301304844fbfPaul McLean
94e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle output devices
95e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
96d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> outputs;
97d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
983a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
993a4311c68348f728558e87b5db67d47605783890Eric Laurent
100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // save a copy of the opened output descriptors before any output is opened or closed
101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device connection
1063ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
1073a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %x", device);
109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() connecting device %x", device);
112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // register new device as available
1143a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableOutputDevices.add(devDesc);
1153a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
11653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                sp<HwModule> module = mHwModules.getModuleForDevice(device);
117cf817a2330936947df94c11859f48771f5596a59Eric Laurent                if (module == 0) {
118cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
119cf817a2330936947df94c11859f48771f5596a59Eric Laurent                          device);
120cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    mAvailableOutputDevices.remove(devDesc);
121cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    return INVALID_OPERATION;
122cf817a2330936947df94c11859f48771f5596a59Eric Laurent                }
123e743a47f445f02a0612018fa5640301304844fbfPaul McLean                mAvailableOutputDevices[index]->attach(module);
1243a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
1253a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
12844481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
12944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // parameters on newly connected devices (instead of opening the outputs...)
13044481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
13144481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
132a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
1330fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                mAvailableOutputDevices.remove(devDesc);
13444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
13544481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
13644481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                               devDesc->mAddress);
1370fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                return INVALID_OPERATION;
1380fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            }
1392110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
1402110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
1412110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
1420fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            // outputs should never be empty here
1430fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
1440fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    "checkOutputsForDevice() returned no outputs but status OK");
1450fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
1460fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                  outputs.size());
1473ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
1483ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            } break;
149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device disconnection
1503b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
1513a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %x", device);
153e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
154e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1565c477aa6205e2ebafec237411900d89a510cc105Paul McLean            ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
1575c477aa6205e2ebafec237411900d89a510cc105Paul McLean
158e743a47f445f02a0612018fa5640301304844fbfPaul McLean            // Send Disconnect to HALs
15944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
1605c477aa6205e2ebafec237411900d89a510cc105Paul McLean
161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // remove device from available output devices
1623a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(devDesc);
1633a4311c68348f728558e87b5db67d47605783890Eric Laurent
164a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
1652110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
1662110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
1672110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } break;
169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1753a4311c68348f728558e87b5db67d47605783890Eric Laurent        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
1763a4311c68348f728558e87b5db67d47605783890Eric Laurent        // output is suspended before any tracks are moved to it
177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkA2dpSuspend();
178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForAllStrategies();
179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // outputs must be closed after checkOutputForAllStrategies() is executed
180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputs.isEmpty()) {
181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < outputs.size(); i++) {
182c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // close unused outputs after device disconnection or direct outputs that have been
184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // opened by checkOutputsForDevice() to query dynamic parameters
1853b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                         (desc->mDirectOpenCount == 0))) {
188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    closeOutput(outputs[i]);
189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1913a4311c68348f728558e87b5db67d47605783890Eric Laurent            // check again after closing A2DP output to reset mA2dpSuspended if needed
1923a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkA2dpSuspend();
193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
19687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
197c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
198c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            updateCallRouting(newDevice);
199c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
201c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
202c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
203c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
204c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // do not force device change on duplicated output because if device is 0, it will
205c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // also force a device 0 for the two outputs it is duplicated to which may override
206c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // a valid device selection on those outputs.
207c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                bool force = !desc->isDuplicated()
20853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                        && (!device_distinguishes_on_address(device)
209c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                // always force when disconnecting (a non-duplicated device)
210c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
211c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setOutputDevice(desc, newDevice, force, 0);
212c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            }
213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
215d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
216d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            cleanUpForDevice(devDesc);
217d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
218d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
21972aa32f7dbbfb658097930b57659d8e50f24a953Eric Laurent        mpClientInterface->onAudioPortListUpdate();
220b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent        return NO_ERROR;
221d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }  // end if is output device
222d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle input devices
224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_input_device(device)) {
225d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> inputs;
226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2273a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
228e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
229e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device connection
2313b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
2323a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %d", device);
234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
23653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<HwModule> module = mHwModules.getModuleForDevice(device);
2376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (module == NULL) {
2386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
2396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                      device);
2406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
2416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
24244481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
24344481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
24444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            // parameters on newly connected devices (instead of opening the inputs...)
24544481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
24644481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie
2479080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean            if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
24844481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
24944481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie                                               devDesc->mAddress);
250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                return INVALID_OPERATION;
251d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
252d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2533a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableInputDevices.add(devDesc);
2543a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
255e743a47f445f02a0612018fa5640301304844fbfPaul McLean                mAvailableInputDevices[index]->attach(module);
2563a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
2573a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
2583a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
2593ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
2602110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
2612110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
262d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device disconnection
2653b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
2663a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %d", device);
268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2705c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2715c477aa6205e2ebafec237411900d89a510cc105Paul McLean            ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
2725c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2735c477aa6205e2ebafec237411900d89a510cc105Paul McLean            // Set Disconnect to HALs
27444481e7a0d0a3dd2c0ec3195a693f5b373659dc6François Gaffie            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
2755c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2769080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean            checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
2773a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(devDesc);
2785c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2792110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
2802110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
281d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
284e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        closeAllInputs();
2895f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        // As the input device list can impact the output device selection, update
2905f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        // getDeviceForStrategy() cache
2915f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        updateDevicesAndOutputs();
292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
29387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
294c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
295c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            updateCallRouting(newDevice);
296c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
297c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
298d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
299d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            cleanUpForDevice(devDesc);
300d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
301d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
302b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mpClientInterface->onAudioPortListUpdate();
303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end if is input device
305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW("setDeviceConnectionState() invalid device: %x", device);
307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return BAD_VALUE;
308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
310e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
31153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                                      const char *device_address)
312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
313634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    sp<DeviceDescriptor> devDesc =
314634b71478742310960f3fdb4241e70a0735712c4Eric Laurent            mHwModules.getDeviceDescriptor(device, device_address, "",
315634b71478742310960f3fdb4241e70a0735712c4Eric Laurent                                           (strlen(device_address) != 0)/*matchAddress*/);
316634b71478742310960f3fdb4241e70a0735712c4Eric Laurent
317634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    if (devDesc == 0) {
318634b71478742310960f3fdb4241e70a0735712c4Eric Laurent        ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
319634b71478742310960f3fdb4241e70a0735712c4Eric Laurent              device, device_address);
320634b71478742310960f3fdb4241e70a0735712c4Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
321634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    }
32253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
3233a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector *deviceVector;
3243a4311c68348f728558e87b5db67d47605783890Eric Laurent
325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
3263a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableOutputDevices;
327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (audio_is_input_device(device)) {
3283a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableInputDevices;
3293a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3303a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
3313a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
333634b71478742310960f3fdb4241e70a0735712c4Eric Laurent
334634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
335634b71478742310960f3fdb4241e70a0735712c4Eric Laurent            AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
336a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent}
337a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent
338f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavovstatus_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
339f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                                      const char *device_address,
340f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                                      const char *device_name)
341f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov{
342f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    status_t status;
343f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
344f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
345f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov          device, device_address, device_name);
346f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
347c694ff449bef4ca1e45a6506f34e66c613757311Pavlin Radoslavov    // connect/disconnect only 1 device at a time
348c694ff449bef4ca1e45a6506f34e66c613757311Pavlin Radoslavov    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
349c694ff449bef4ca1e45a6506f34e66c613757311Pavlin Radoslavov
350f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    // Check if the device is currently connected
351f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    sp<DeviceDescriptor> devDesc =
352f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov            mHwModules.getDeviceDescriptor(device, device_address, device_name);
353f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
354f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    if (index < 0) {
355f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        // Nothing to do: device is not connected
356f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        return NO_ERROR;
357f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    }
358f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
359f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    // Toggle the device state: UNAVAILABLE -> AVAILABLE
360f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    // This will force reading again the device configuration
361f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    status = setDeviceConnectionState(device,
362f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
363f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      device_address, device_name);
364f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    if (status != NO_ERROR) {
365f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
366f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov              status);
367f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        return status;
368f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    }
369f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
370f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    status = setDeviceConnectionState(device,
371f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
372f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov                                      device_address, device_name);
373f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    if (status != NO_ERROR) {
374f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
375f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov              status);
376f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov        return status;
377f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    }
378f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
379f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov    return NO_ERROR;
380f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov}
381f862bc6a7a35054e38cb50fa16ae7a07f683ee01Pavlin Radoslavov
382dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurentuint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
383c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{
384c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    bool createTxPatch = false;
385c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    status_t status;
386c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    audio_patch_handle_t afPatchHandle;
387c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    DeviceVector deviceList;
388dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t muteWaitMs = 0;
389c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
390a76c7de622e6e29f8559921d8d2e9ef93eb37d1fAndy Hung    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
391dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        return muteWaitMs;
39287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    }
393c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
394c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
395c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
396c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // release existing RX patch if any
397c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (mCallRxPatch != 0) {
398c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
399c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mCallRxPatch.clear();
400c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
401c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // release TX patch if any
402c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (mCallTxPatch != 0) {
403c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
404c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mCallTxPatch.clear();
405c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
406c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
407c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // If the RX device is on the primary HW module, then use legacy routing method for voice calls
408c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // via setOutputDevice() on primary output.
409c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // Otherwise, create two audio patches for TX and RX path.
410c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (availablePrimaryOutputDevices() & rxDevice) {
411dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        muteWaitMs = setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
412c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // If the TX device is also on the primary HW module, setOutputDevice() will take care
413c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // of it due to legacy implementation. If not, create a patch.
414c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
415c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                == AUDIO_DEVICE_NONE) {
416c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            createTxPatch = true;
417c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
4188ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    } else { // create RX path audio patch
4198ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        struct audio_patch patch;
4208ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent
4218ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        patch.num_sources = 1;
4228ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        patch.num_sinks = 1;
423c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
424c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
425c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() selected device not in output device list");
426c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
427c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
428c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
429c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() no telephony RX device");
430c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
431c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
432c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
433c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
434c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
435c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // request to reuse existing output stream if one is already opened to reach the RX device
436c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        SortedVector<audio_io_handle_t> outputs =
437c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                getOutputsForDevice(rxDevice, mOutputs);
4388838a3895c365d443ee22e169ccf45956780c081Eric Laurent        audio_io_handle_t output = selectOutput(outputs,
4398838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_OUTPUT_FLAG_NONE,
4408838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_FORMAT_INVALID);
441c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (output != AUDIO_IO_HANDLE_NONE) {
442c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
443c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
444c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                        "updateCallRouting() RX device output is duplicated");
445c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            outputDesc->toAudioPortConfig(&patch.sources[1]);
4463bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent            patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
447c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            patch.num_sources = 2;
448c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
449c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
450c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
451dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
452c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
453c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                               status);
454c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (status == NO_ERROR) {
45598cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie            mCallRxPatch = new AudioPatch(&patch, mUidCached);
456c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallRxPatch->mAfPatchHandle = afPatchHandle;
457c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallRxPatch->mUid = mUidCached;
458c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
459c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        createTxPatch = true;
460c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
4618ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    if (createTxPatch) { // create TX path audio patch
462c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        struct audio_patch patch;
4638ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent
464c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        patch.num_sources = 1;
465c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        patch.num_sinks = 1;
466c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
467c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
468c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() selected device not in input device list");
469c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
470c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
471c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
472c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
473c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() no telephony TX device");
474c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
475c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
476c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
477c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        SortedVector<audio_io_handle_t> outputs =
478c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
4798838a3895c365d443ee22e169ccf45956780c081Eric Laurent        audio_io_handle_t output = selectOutput(outputs,
4808838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_OUTPUT_FLAG_NONE,
4818838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_FORMAT_INVALID);
482c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // request to reuse existing output stream if one is already opened to reach the TX
483c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // path output device
484c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (output != AUDIO_IO_HANDLE_NONE) {
485c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
486c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
487c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                        "updateCallRouting() RX device output is duplicated");
488c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            outputDesc->toAudioPortConfig(&patch.sources[1]);
4893bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent            patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
490c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            patch.num_sources = 2;
491c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
492c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
493c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // terminate active capture if on the same HW module as the call TX source device
494c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // FIXME: would be better to refine to only inputs whose profile connects to the
495c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // call TX device but this information is not in the audio patch and logic here must be
496c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // symmetric to the one in startInput()
497fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
498fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        for (size_t i = 0; i < activeInputs.size(); i++) {
499fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            sp<AudioInputDescriptor> activeDesc = activeInputs[i];
500fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
501fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                AudioSessionCollection activeSessions =
502fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                        activeDesc->getAudioSessions(true /*activeOnly*/);
503fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                for (size_t j = 0; j < activeSessions.size(); j++) {
504fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    audio_session_t activeSession = activeSessions.keyAt(j);
505fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    stopInput(activeDesc->mIoHandle, activeSession);
506fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    releaseInput(activeDesc->mIoHandle, activeSession);
507fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                }
508c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent            }
509c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        }
510c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent
511c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
512dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
513c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
514c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                               status);
515c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (status == NO_ERROR) {
51698cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie            mCallTxPatch = new AudioPatch(&patch, mUidCached);
517c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallTxPatch->mAfPatchHandle = afPatchHandle;
518c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallTxPatch->mUid = mUidCached;
519c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
520c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
521dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
522dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    return muteWaitMs;
523c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent}
524c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
525e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state)
526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setPhoneState() state %d", state);
5282110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    // store previous phone state for management of sonification strategy below
5292110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    int oldState = mEngine->getPhoneState();
530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5312110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->setPhoneState(state) != NO_ERROR) {
5322110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        ALOGW("setPhoneState() invalid or same state %d", state);
533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5352110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    /// Opens: can these line be executed after the switch of volume curves???
536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if leaving call state, handle special case of active streams
537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
53863dea1d5334acf3baa9448086dd504ead57d814bEric Laurent    if (isStateInCall(oldState)) {
539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
540794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
5413b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, false, true);
542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5432cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent
54463dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        // force reevaluating accessibility routing when call stops
5452cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5482110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    /**
5492110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     * Switching to or from incall state or switching between telephony and VoIP lead to force
5502110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     * routing command.
5512110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     */
5522110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
5532110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                  || (is_state_in_call(state) && (state != oldState)));
554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new phone state
556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int delayMs = 0;
561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        nsecs_t sysTime = systemTime();
563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
564c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // mute media and sonification strategies and delay device switch by the largest
566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // latency of any output where either strategy is active.
567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // This avoid sending the ring tone or music tail into the earpiece or headset.
568ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if ((isStrategyActive(desc, STRATEGY_MEDIA,
569ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  SONIFICATION_HEADSET_MUSIC_DELAY,
570ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  sysTime) ||
571ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                 isStrategyActive(desc, STRATEGY_SONIFICATION,
572ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  SONIFICATION_HEADSET_MUSIC_DELAY,
573ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  sysTime)) &&
574c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    (delayMs < (int)desc->latency()*2)) {
575c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                delayMs = desc->latency()*2;
576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
577c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_MEDIA, true, desc);
578c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
580c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, true, desc);
581c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
58687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if (hasPrimaryOutput()) {
58787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // Note that despite the fact that getNewOutputDevice() is called on the primary output,
58887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // the device returned is not necessarily reachable via this output
58987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
59087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // force routing command to audio hardware when ending call
59187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // even if no device change is needed
59287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
59387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            rxDevice = mPrimaryOutput->device();
594c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
59587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent
59687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (state == AUDIO_MODE_IN_CALL) {
59787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            updateCallRouting(rxDevice, delayMs);
59887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        } else if (oldState == AUDIO_MODE_IN_CALL) {
59987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (mCallRxPatch != 0) {
60087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
60187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mCallRxPatch.clear();
60287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            }
60387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (mCallTxPatch != 0) {
60487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
60587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mCallTxPatch.clear();
60687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            }
60787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
60887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        } else {
60987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
610c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
611c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if entering in call state, handle special case of active streams
613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
616794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
6173b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, true, true);
618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
61963dea1d5334acf3baa9448086dd504ead57d814bEric Laurent
62063dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        // force reevaluating accessibility routing when call starts
62163dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
6253b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_MODE_RINGTONE &&
6263b73df74357b33869b39a1d69427673c780bd805Eric Laurent        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = true;
628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = false;
630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
633887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Triviaudio_mode_t AudioPolicyManager::getPhoneState() {
634887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi    return mEngine->getPhoneState();
635887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi}
636887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi
637e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
6383b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                         audio_policy_forced_cfg_t config)
639e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
6402110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
6418dc87a60e69f462e0382d025c335e45699025b48Eric Laurent    if (config == mEngine->getForceUse(usage)) {
6428dc87a60e69f462e0382d025c335e45699025b48Eric Laurent        return;
6438dc87a60e69f462e0382d025c335e45699025b48Eric Laurent    }
6442110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
6452110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->setForceUse(usage, config) != NO_ERROR) {
6462110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
6472110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        return;
648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
6492110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
6502110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
6512110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new force usage
654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
65709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
658dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    //FIXME: workaround for truncated touch sounds
659dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    // to be removed when the problem is handled by system UI
660dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t delayMs = 0;
661dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t waitMs = 0;
662dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    if (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) {
663dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
664dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    }
66587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
666c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
667dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        waitMs = updateCallRouting(newDevice, delayMs);
668c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
670c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
671c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
672c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
673dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
674dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                                     delayMs);
675c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
677dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            applyStreamVolumes(outputDesc, newDevice, waitMs, true);
678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
681fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
682fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    for (size_t i = 0; i < activeInputs.size(); i++) {
683fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        sp<AudioInputDescriptor> activeDesc = activeInputs[i];
684fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        audio_devices_t newDevice = getNewInputDevice(activeDesc);
685c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        // Force new input selection if the new device can not be reached via current input
686fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if (activeDesc->mProfile->getSupportedDevices().types() &
687fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
688fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            setInputDevice(activeDesc->mIoHandle, newDevice);
689c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        } else {
690fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            closeInput(activeDesc->mIoHandle);
691c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        }
692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
695e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value)
696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setSystemProperty() property %s, value %s", property, value);
698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do
701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output
70256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_devices_t device,
704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               uint32_t samplingRate,
705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_format_t format,
706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_channel_mask_t channelMask,
707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_output_flags_t flags)
708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
709861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    // only retain flags that will drive the direct output profile selection
710861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    // if explicitly requested
711861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    static const uint32_t kRelevantFlags =
712861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
713861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    flags =
714861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
715861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
716861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    sp<IOProfile> profile;
717861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
723861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
724861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            if (!curProfile->isCompatibleProfile(device, String8(""),
725f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    samplingRate, NULL /*updatedSamplingRate*/,
726f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    format, NULL /*updatedFormat*/,
727f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    channelMask, NULL /*updatedChannelMask*/,
728861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                    flags)) {
729861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
730861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
731861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            // reject profiles not corresponding to a device currently available
732a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((mAvailableOutputDevices.types() & curProfile->getSupportedDevicesType()) == 0) {
733861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
734861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
735861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            // if several profiles are compatible, give priority to one with offload capability
736a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
737861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
738861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
739861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            profile = curProfile;
740a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
741861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                break;
7423a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
745861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    return profile;
746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
748e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
74953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                uint32_t samplingRate,
75053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                audio_format_t format,
75153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                audio_channel_mask_t channelMask,
75253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                audio_output_flags_t flags,
75353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                const audio_offload_info_t *offloadInfo)
754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
7553b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(stream);
756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          device, stream, samplingRate, format, channelMask, flags);
759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
760169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard    return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE, stream, samplingRate, format,
761169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                              channelMask, flags, offloadInfo);
762e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
763e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
764e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentstatus_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
765e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_io_handle_t *output,
766e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_session_t session,
767e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_stream_type_t *stream,
7688c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                              uid_t uid,
76920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                              const audio_config_t *config,
770e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_output_flags_t flags,
771aa9811945f575614b3482d09e4d969792701cebbPaul McLean                                              audio_port_handle_t selectedDeviceId,
77220b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                              audio_port_handle_t *portId)
773e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent{
774e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    audio_attributes_t attributes;
775e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (attr != NULL) {
776e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (!isValidAttributes(attr)) {
777e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
778e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                  attr->usage, attr->content_type, attr->flags,
779e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                  attr->tags);
780e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            return BAD_VALUE;
781e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        }
782e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        attributes = *attr;
783e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    } else {
784e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
785e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            ALOGE("getOutputForAttr():  invalid stream type");
786e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            return BAD_VALUE;
787e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        }
788e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        stream_type_to_audio_attributes(*stream, &attributes);
7895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
79020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
79120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    // TODO: check for existing client for this port ID
79220b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    if (*portId == AUDIO_PORT_HANDLE_NONE) {
79320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        *portId = AudioPort::getNextUniqueId();
79420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    }
79520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
796c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc;
797e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi    if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
798036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
79920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        if (!audio_has_proportional_frames(config->format)) {
800036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie            return BAD_VALUE;
801275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
802036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        *stream = streamTypefromAttributesInt(&attributes);
803036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        *output = desc->mIoHandle;
804036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        ALOGV("getOutputForAttr() returns output %d", *output);
805036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        return NO_ERROR;
806275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
807275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
808275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
809275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        return BAD_VALUE;
810275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
811275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
8128c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
8138c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            " session %d selectedDeviceId %d",
8148c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
8158c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            session, selectedDeviceId);
8168c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
8178c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    *stream = streamTypefromAttributesInt(&attributes);
8188c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
8198c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Explicit routing?
8208c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    sp<DeviceDescriptor> deviceDesc;
8218c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
8228c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (mAvailableOutputDevices[i]->getId() == selectedDeviceId) {
8238c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            deviceDesc = mAvailableOutputDevices[i];
8248c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            break;
8258c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
8268c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
8278c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
8285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
829e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
8305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
83193c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent
832e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
83393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
83493c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    }
83593c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent
836fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi    ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
83720b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent          device, config->sample_rate, config->format, config->channel_mask, flags);
8385bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
839169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard    *output = getOutputForDevice(device, session, *stream,
84020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                 config->sample_rate, config->format, config->channel_mask,
84120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                 flags, &config->offload_info);
842e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (*output == AUDIO_IO_HANDLE_NONE) {
8438c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        mOutputRoutes.removeRoute(session);
844e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return INVALID_OPERATION;
845e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
846aa9811945f575614b3482d09e4d969792701cebbPaul McLean
847e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return NO_ERROR;
8485bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
8495bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
8505bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForDevice(
8515bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_devices_t device,
852169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard        audio_session_t session,
8535bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_stream_type_t stream,
8545bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        uint32_t samplingRate,
8555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_format_t format,
8565bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_channel_mask_t channelMask,
8575bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_output_flags_t flags,
8585bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        const audio_offload_info_t *offloadInfo)
8595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{
860cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
861cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    status_t status;
8625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mCurOutput != 0) {
865e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
866e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTestOutputs[mCurOutput] == 0) {
869e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() opening test output");
870c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
871c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                               mpClientInterface);
872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mDevice = mTestDevice;
873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mLatency = mTestLatencyMs;
8743b73df74357b33869b39a1d69427673c780bd805Eric Laurent            outputDesc->mFlags =
8753b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mRefCount[stream] = 0;
877cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
878cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.sample_rate = mTestSamplingRate;
879cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.channel_mask = mTestChannels;
880cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.format = mTestFormat;
88177cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk            if (offloadInfo != NULL) {
88277cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk                config.offload_info = *offloadInfo;
88377cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk            }
884cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            status = mpClientInterface->openOutput(0,
885cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &mTestOutputs[mCurOutput],
886cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &config,
887cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &outputDesc->mDevice,
888cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  String8(""),
889cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &outputDesc->mLatency,
890cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  outputDesc->mFlags);
891cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
892cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                outputDesc->mSamplingRate = config.sample_rate;
893cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                outputDesc->mFormat = config.format;
894cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                outputDesc->mChannelMask = config.channel_mask;
895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioParameter outputCmd = AudioParameter();
896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputCmd.addInt(String8("set_id"),mCurOutput);
897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                addOutput(mTestOutputs[mCurOutput], outputDesc);
899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mTestOutputs[mCurOutput];
902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a direct output if required by specified parameters
906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
9103b73df74357b33869b39a1d69427673c780bd805Eric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
91293c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
91393c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
91493c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    }
915e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // only allow deep buffering for music stream type
916e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (stream != AUDIO_STREAM_MUSIC) {
917e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
918439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda    } else if (/* stream == AUDIO_STREAM_MUSIC && */
919439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda            flags == AUDIO_OUTPUT_FLAG_NONE &&
920439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda            property_get_bool("audio.deep_buffer.media", false /* default_value */)) {
921439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda        // use DEEP_BUFFER as default output for music stream type
922439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda        flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
923e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
924c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda    if (stream == AUDIO_STREAM_TTS) {
925c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda        flags = AUDIO_OUTPUT_FLAG_TTS;
926c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda    }
927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
928b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    sp<IOProfile> profile;
929b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
930b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    // skip direct output selection if the request can obviously be attached to a mixed output
931c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent    // and not explicitly requested
932c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent    if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
93305ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten            audio_is_linear_pcm(format) && samplingRate <= SAMPLE_RATE_HZ_MAX &&
934b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent            audio_channel_count_from_out_mask(channelMask) <= 2) {
935b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent        goto non_direct_output;
936b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    }
937b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
9382ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
9392ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // This prevents creating an offloaded track and tearing it down immediately after start
9402ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // when audioflinger detects there is an active non offloadable effect.
941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
942e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
944b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
9462ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile = getProfileForDirectOutput(device,
948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           samplingRate,
949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           format,
950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           (audio_output_flags_t)flags);
952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
9541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (profile != 0) {
955c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = NULL;
956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
958c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc = desc;
961551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                // reuse direct output if currently open by the same client
962551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                // and configured with same parameters
963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((samplingRate == outputDesc->mSamplingRate) &&
964551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                    audio_formats_match(format, outputDesc->mFormat) &&
965551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                    (channelMask == outputDesc->mChannelMask)) {
966169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                  if (session == outputDesc->mDirectClientSession) {
967551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                      outputDesc->mDirectOpenCount++;
968169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                      ALOGV("getOutput() reusing direct output %d for session %d",
969169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                            mOutputs.keyAt(i), session);
970551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                      return mOutputs.keyAt(i);
971551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                  } else {
972169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                      ALOGV("getOutput() do not reuse direct output because current client (%d) "
973169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                            "is not the same as requesting client (%d)",
974169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard                            outputDesc->mDirectClientSession, session);
975551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                      goto non_direct_output;
976551061ab211e1da0f060d7c895617814618da5c2Kevin Rocard                  }
977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // close direct output if currently open and configured with different parameters
981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc != NULL) {
9821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            closeOutput(outputDesc->mIoHandle);
983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
984861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
985861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        // if the selected profile is offloaded and no offload info was specified,
986861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        // create a default one
987861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
988a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
989861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
990861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.sample_rate = samplingRate;
991861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.channel_mask = channelMask;
992861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.format = format;
993861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.stream_type = stream;
994861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.bit_rate = 0;
995861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.duration_us = -1;
996861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.has_video = true; // conservative
997861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.is_streaming = true; // likely
998861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            offloadInfo = &defaultOffloadInfo;
999861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        }
1000861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
1001c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
1002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mLatency = 0;
1004861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
1005cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1006cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        config.sample_rate = samplingRate;
1007cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        config.channel_mask = channelMask;
1008cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        config.format = format;
100977cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk        if (offloadInfo != NULL) {
101077cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk            config.offload_info = *offloadInfo;
101177cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk        }
1012e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent        DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
1013e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent        String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
1014e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent                : String8("");
1015322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        status = mpClientInterface->openOutput(profile->getModuleHandle(),
1016cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &output,
1017cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &config,
1018cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &outputDesc->mDevice,
1019e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent                                               address,
1020cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &outputDesc->mLatency,
1021cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               outputDesc->mFlags);
1022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // only accept an output with the requested parameters
1024cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        if (status != NO_ERROR ||
1025cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            (samplingRate != 0 && samplingRate != config.sample_rate) ||
1026e693002b0fb25099540588245892ed98103749baEric Laurent            (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) ||
1027cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            (channelMask != 0 && channelMask != config.channel_mask)) {
1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    "format %d %d, channelMask %04x %04x", output, samplingRate,
1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mChannelMask);
1032cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (output != AUDIO_IO_HANDLE_NONE) {
1033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->closeOutput(output);
1034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1035a82797faddb37adb2d441737884576684c8515cbEric Laurent            // fall back to mixer output if possible when the direct output could not be open
103605ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten            if (audio_is_linear_pcm(format) && samplingRate <= SAMPLE_RATE_HZ_MAX) {
103756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                goto non_direct_output;
103856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
1039cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            return AUDIO_IO_HANDLE_NONE;
1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1041cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mSamplingRate = config.sample_rate;
1042cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mChannelMask = config.channel_mask;
1043cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mFormat = config.format;
1044cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mRefCount[stream] = 0;
1045cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mStopTime[stream] = 0;
1046cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mDirectOpenCount = 1;
1047169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard        outputDesc->mDirectClientSession = session;
1048169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard
1049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        addOutput(output, outputDesc);
1050e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
1051e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() returns new direct output %d", output);
1052b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mpClientInterface->onAudioPortListUpdate();
1053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return output;
1054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1056b732cf5af93c33fa183769210ce9954521fb68cdEric Laurentnon_direct_output:
105714cbfcae68582eca97f1a8168c584254515879eeEric Laurent
105814cbfcae68582eca97f1a8168c584254515879eeEric Laurent    // A request for HW A/V sync cannot fallback to a mixed output because time
105914cbfcae68582eca97f1a8168c584254515879eeEric Laurent    // stamps are embedded in audio data
106014cbfcae68582eca97f1a8168c584254515879eeEric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
106114cbfcae68582eca97f1a8168c584254515879eeEric Laurent        return AUDIO_IO_HANDLE_NONE;
106214cbfcae68582eca97f1a8168c584254515879eeEric Laurent    }
106314cbfcae68582eca97f1a8168c584254515879eeEric Laurent
1064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // ignoring channel mask due to downmix capability in mixer
1065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1066e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a non direct output
1067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // for non direct outputs, only PCM is supported
1069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_linear_pcm(format)) {
1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // get which output is suitable for the specified stream. The actual
1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing change will happen when startOutput() will be called
1072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
10748838a3895c365d443ee22e169ccf45956780c081Eric Laurent        // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
10758838a3895c365d443ee22e169ccf45956780c081Eric Laurent        flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
10768838a3895c365d443ee22e169ccf45956780c081Eric Laurent        output = selectOutput(outputs, flags, format);
1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1081aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("  getOutputForDevice() returns output %d", output);
1082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
1084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1085e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1086e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
10878838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                       audio_output_flags_t flags,
10888838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                       audio_format_t format)
1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several that provide a path to a particular device or set of
1091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // devices (the list was previously build by getOutputsForDevice()).
1092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
1093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the output with the highest number of requested policy flags
1094e693002b0fb25099540588245892ed98103749baEric Laurent    // 2: the output with the bit depth the closest to the requested one
1095e693002b0fb25099540588245892ed98103749baEric Laurent    // 3: the primary output
1096e693002b0fb25099540588245892ed98103749baEric Laurent    // 4: the first output in the list
1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 1) {
1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputs[0];
1103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int maxCommonFlags = 0;
1106e693002b0fb25099540588245892ed98103749baEric Laurent    audio_io_handle_t outputForFlags = 0;
1107e693002b0fb25099540588245892ed98103749baEric Laurent    audio_io_handle_t outputForPrimary = 0;
1108e693002b0fb25099540588245892ed98103749baEric Laurent    audio_io_handle_t outputForFormat = 0;
1109e693002b0fb25099540588245892ed98103749baEric Laurent    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
1110e693002b0fb25099540588245892ed98103749baEric Laurent    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
1111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
1113c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
1114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated()) {
11158838a3895c365d443ee22e169ccf45956780c081Eric Laurent            // if a valid format is specified, skip output if not compatible
11168838a3895c365d443ee22e169ccf45956780c081Eric Laurent            if (format != AUDIO_FORMAT_INVALID) {
11178838a3895c365d443ee22e169ccf45956780c081Eric Laurent                if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1118e693002b0fb25099540588245892ed98103749baEric Laurent                    if (!audio_formats_match(format, outputDesc->mFormat)) {
11198838a3895c365d443ee22e169ccf45956780c081Eric Laurent                        continue;
11208838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    }
11218838a3895c365d443ee22e169ccf45956780c081Eric Laurent                } else if (!audio_is_linear_pcm(format)) {
11228838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    continue;
11238838a3895c365d443ee22e169ccf45956780c081Eric Laurent                }
1124e693002b0fb25099540588245892ed98103749baEric Laurent                if (AudioPort::isBetterFormatMatch(
1125e693002b0fb25099540588245892ed98103749baEric Laurent                        outputDesc->mFormat, bestFormat, format)) {
1126e693002b0fb25099540588245892ed98103749baEric Laurent                    outputForFormat = outputs[i];
1127e693002b0fb25099540588245892ed98103749baEric Laurent                    bestFormat = outputDesc->mFormat;
1128e693002b0fb25099540588245892ed98103749baEric Laurent                }
11298838a3895c365d443ee22e169ccf45956780c081Eric Laurent            }
11308838a3895c365d443ee22e169ccf45956780c081Eric Laurent
1131a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
1132e693002b0fb25099540588245892ed98103749baEric Laurent            if (commonFlags >= maxCommonFlags) {
1133e693002b0fb25099540588245892ed98103749baEric Laurent                if (commonFlags == maxCommonFlags) {
1134e693002b0fb25099540588245892ed98103749baEric Laurent                    if (AudioPort::isBetterFormatMatch(
1135e693002b0fb25099540588245892ed98103749baEric Laurent                            outputDesc->mFormat, bestFormatForFlags, format)) {
1136e693002b0fb25099540588245892ed98103749baEric Laurent                        outputForFlags = outputs[i];
1137e693002b0fb25099540588245892ed98103749baEric Laurent                        bestFormatForFlags = outputDesc->mFormat;
1138e693002b0fb25099540588245892ed98103749baEric Laurent                    }
1139e693002b0fb25099540588245892ed98103749baEric Laurent                } else {
1140e693002b0fb25099540588245892ed98103749baEric Laurent                    outputForFlags = outputs[i];
1141e693002b0fb25099540588245892ed98103749baEric Laurent                    maxCommonFlags = commonFlags;
1142e693002b0fb25099540588245892ed98103749baEric Laurent                    bestFormatForFlags = outputDesc->mFormat;
1143e693002b0fb25099540588245892ed98103749baEric Laurent                }
1144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
1145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1146a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
1147e693002b0fb25099540588245892ed98103749baEric Laurent                outputForPrimary = outputs[i];
1148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1151e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1152e693002b0fb25099540588245892ed98103749baEric Laurent    if (outputForFlags != 0) {
1153e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForFlags;
1154e693002b0fb25099540588245892ed98103749baEric Laurent    }
1155e693002b0fb25099540588245892ed98103749baEric Laurent    if (outputForFormat != 0) {
1156e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForFormat;
1157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1158e693002b0fb25099540588245892ed98103749baEric Laurent    if (outputForPrimary != 0) {
1159e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForPrimary;
1160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
1163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1165e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output,
11663b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                             audio_stream_type_t stream,
1167e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                             audio_session_t session)
1168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1169aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("startOutput() output %d, stream %d, session %d",
1170aa9811945f575614b3482d09e4d969792701cebbPaul McLean          output, stream, session);
1171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startOutput() unknown output %d", output);
1174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1177c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1178c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
11798c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Routing?
11808c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mOutputRoutes.incRouteActivity(session);
11818c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
1182c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    audio_devices_t newDevice;
1183c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    AudioMix *policyMix = NULL;
1184c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    const char *address = NULL;
1185c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mPolicyMix != NULL) {
1186c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        policyMix = outputDesc->mPolicyMix;
1187c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        address = policyMix->mDeviceAddress.string();
1188c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
1189c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            newDevice = policyMix->mDeviceType;
1190c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        } else {
1191c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1192c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        }
1193493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    } else if (mOutputRoutes.hasRouteChanged(session)) {
1194493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent        newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
11958c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        checkStrategyRoute(getStrategy(stream), output);
1196c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
1197c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        newDevice = AUDIO_DEVICE_NONE;
1198c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1199c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1200c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    uint32_t delayMs = 0;
1201c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1202c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    status_t status = startSource(outputDesc, stream, newDevice, address, &delayMs);
1203c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1204c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (status != NO_ERROR) {
1205c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mOutputRoutes.decRouteActivity(session);
12068c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        return status;
1207c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1208c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // Automatically enable the remote submix input when output is started on a re routing mix
1209c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // of type MIX_TYPE_RECORDERS
1210c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    if (audio_is_remote_submix_device(newDevice) && policyMix != NULL &&
1211c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            policyMix->mMixType == MIX_TYPE_RECORDERS) {
1212c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1213c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1214c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                    address,
1215c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    "remote-submix");
1216c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1217c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1218c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (delayMs != 0) {
1219c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        usleep(delayMs * 1000);
1220c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1221c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1222c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return status;
1223c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
1224c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1225e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::startSource(const sp<AudioOutputDescriptor>& outputDesc,
1226c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_stream_type_t stream,
1227c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_devices_t device,
1228c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                             const char *address,
1229c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             uint32_t *delayMs)
1230c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
1231d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // cannot start playback of STREAM_TTS if any other output is being used
1232d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    uint32_t beaconMuteLatency = 0;
1233c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1234c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    *delayMs = 0;
1235d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (stream == AUDIO_STREAM_TTS) {
1236d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        ALOGV("\t found BEACON stream");
12379459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
1238d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            return INVALID_OPERATION;
1239d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        } else {
1240d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
1241d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
1242d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    } else {
1243d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // some playback other than beacon starts
1244d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
1245d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
1246d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
124777305a67301c74438ee09fdb8f80b89a43712951Eric Laurent    // force device change if the output is inactive and no audio patch is already present.
12487c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent    // check active before incrementing usage count
124977305a67301c74438ee09fdb8f80b89a43712951Eric Laurent    bool force = !outputDesc->isActive() &&
125077305a67301c74438ee09fdb8f80b89a43712951Eric Laurent            (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
12517c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent
1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // increment usage count for this stream on the requested output:
1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // NOTE that the usage count is the same for duplicated output and hardware output which is
1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    outputDesc->changeRefCount(stream, 1);
1256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
125736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    if (stream == AUDIO_STREAM_MUSIC) {
125836829f97c0c547d9c6c918e248071cc616818616Eric Laurent        selectOutputForMusicEffects();
125936829f97c0c547d9c6c918e248071cc616818616Eric Laurent    }
126036829f97c0c547d9c6c918e248071cc616818616Eric Laurent
1261493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
1262275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        // starting an output being rerouted?
1263c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (device == AUDIO_DEVICE_NONE) {
1264c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            device = getNewOutputDevice(outputDesc, false /*fromCache*/);
1265275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
126636829f97c0c547d9c6c918e248071cc616818616Eric Laurent
1267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        routing_strategy strategy = getStrategy(stream);
1268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
1269d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
1270d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                            (beaconMuteLatency > 0);
1271d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        uint32_t waitMs = beaconMuteLatency;
1272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
12731f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc != outputDesc) {
127577305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // force a device change if any other output is:
127677305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - managed by the same hw module
127777305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - has a current device selection that differs from selected device.
127877305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - supports currently selected device
127977305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - has an active audio patch
1280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // In this case, the audio HAL must receive the new device selection so that it can
1281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // change the device currently selected by the other active output.
1282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->sharesHwModuleWith(desc) &&
128377305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->device() != device &&
128477305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->supportedDevices() & device &&
128577305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
1286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    force = true;
1287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // wait for audio on other active outputs to be presented when starting
1289d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                // a notification so that audio focus effect can propagate, or that a mute/unmute
1290d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                // event occurred for beacon
1291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                uint32_t latency = desc->latency();
1292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    waitMs = latency;
1294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1297dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force, 0, NULL, address);
1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle special case for sonification while in call
1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleIncallSonification(stream, true, false);
1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // apply volume rules for current stream and device if necessary
1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkAndSetVolume(stream,
1306d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                          mVolumeCurves->getVolumeIndex(stream, device),
1307c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          outputDesc,
1308c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          device);
1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // update the outputs if starting an output with a stream that can affect notification
1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing
1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleNotificationRoutingForStream(stream);
1313c722f30eef03e77054395ae122470cf8dba93937Eric Laurent
13142cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        // force reevaluating accessibility routing when ringtone or alarm starts
13152cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        if (strategy == STRATEGY_SONIFICATION) {
13162cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent            mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
13172cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        }
1318dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
1319dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        if (waitMs > muteWaitMs) {
1320dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            *delayMs = waitMs - muteWaitMs;
1321dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        }
1322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1323dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1328e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
13293b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                            audio_stream_type_t stream,
1330e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                            audio_session_t session)
1331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() unknown output %d", output);
1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1339c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1340c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1341c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mRefCount[stream] == 1) {
1342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // Automatically disable the remote submix input when output is stopped on a
1343c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // re routing mix of type MIX_TYPE_RECORDERS
1344c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1345c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                outputDesc->mPolicyMix != NULL &&
1346c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1347c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1348c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
13497638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    outputDesc->mPolicyMix->mDeviceAddress,
1350c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    "remote-submix");
1351c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        }
1352c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1353c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1354c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // Routing?
13558c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    bool forceDeviceUpdate = false;
1356c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
13578c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        int activityCount = mOutputRoutes.decRouteActivity(session);
13588c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        forceDeviceUpdate = (mOutputRoutes.hasRoute(session) && (activityCount == 0));
13598c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
13608c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (forceDeviceUpdate) {
13618c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
13628c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
1363c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
13658c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    return stopSource(outputDesc, stream, forceDeviceUpdate);
1366c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
1367c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1368e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
13698c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            audio_stream_type_t stream,
13708c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            bool forceDeviceUpdate)
1371c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
1372d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // always handle stream stop, check which stream type is stopping
1373d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
1374d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
1375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle special case for sonification while in call
1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleIncallSonification(stream, false, false);
1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // decrement usage count of this stream on the output
1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->changeRefCount(stream, -1);
1383aa9811945f575614b3482d09e4d969792701cebbPaul McLean
1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // store time at which the stream was stopped - see isStreamActive()
13858c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
1386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStopTime[stream] = systemTime();
1387c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
1388e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // delay the device switch by twice the latency because stopOutput() is executed when
1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the track stop() command is received and at that time the audio track buffer can
1390e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // still contain data that needs to be drained. The latency only covers the audio HAL
1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and kernel buffers. Also the latency does not always include additional delay in the
1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // audio path (audio DSP, CODEC ...)
1393c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // force restoring the device selection on other active outputs if it differs from the
1396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // one being selected for this output
139757de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent            uint32_t delayMs = outputDesc->latency()*2;
1398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
13991f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1400c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                if (desc != outputDesc &&
1401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->isActive() &&
1402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputDesc->sharesHwModuleWith(desc) &&
1403e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (newDevice != desc->device())) {
140411c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                    audio_devices_t newDevice2 = getNewOutputDevice(desc, false /*fromCache*/);
140511c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                    bool force = desc->device() != newDevice2;
1406c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    setOutputDevice(desc,
140711c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                                    newDevice2,
140811c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                                    force,
140957de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                                    delayMs);
141057de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    // re-apply device specific volume if not done by setOutputDevice()
141157de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    if (!force) {
141257de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                        applyStreamVolumes(desc, newDevice2, delayMs);
141357de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    }
1414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // update the outputs if stopping one with a stream that can affect notification routing
1417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleNotificationRoutingForStream(stream);
1418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
141936829f97c0c547d9c6c918e248071cc616818616Eric Laurent        if (stream == AUDIO_STREAM_MUSIC) {
142036829f97c0c547d9c6c918e248071cc616818616Eric Laurent            selectOutputForMusicEffects();
142136829f97c0c547d9c6c918e248071cc616818616Eric Laurent        }
1422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
1423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1424c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGW("stopOutput() refcount is already 0");
1425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1429e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output,
1430caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                       audio_stream_type_t stream __unused,
1431caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                       audio_session_t session __unused)
1432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseOutput() %d", output);
1434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseOutput() releasing unknown output %d", output);
1437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int testIndex = testOutputIndex(output);
1442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (testIndex != 0) {
14431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->isActive()) {
1445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(output);
144653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            removeOutput(output);
1447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[testIndex] = 0;
1448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1453aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // Routing
1454aa9811945f575614b3482d09e4d969792701cebbPaul McLean    mOutputRoutes.removeRoute(session);
1455aa9811945f575614b3482d09e4d969792701cebbPaul McLean
1456c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
14573b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (desc->mDirectOpenCount <= 0) {
1459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("releaseOutput() invalid open count %d for output %d",
1460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                              desc->mDirectOpenCount, output);
1461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
1462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--desc->mDirectOpenCount == 0) {
1464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            closeOutput(output);
1465b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent            mpClientInterface->onAudioPortListUpdate();
1466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1471caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurentstatus_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
1472caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_io_handle_t *input,
1473caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_session_t session,
14748c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                             uid_t uid,
147520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                             const audio_config_base_t *config,
147697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                                             audio_input_flags_t flags,
1477466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean                                             audio_port_handle_t selectedDeviceId,
147820b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                             input_type_t *inputType,
147920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                                             audio_port_handle_t *portId)
1480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1481caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
1482caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent            "session %d, flags %#x",
148320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent          attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
1484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1485caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    *input = AUDIO_IO_HANDLE_NONE;
148697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi    *inputType = API_INPUT_INVALID;
1487fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1488275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    audio_devices_t device;
1489275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    // handle legacy remote submix case where the address was not always specified
1490275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    String8 address = String8("");
1491c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    audio_source_t inputSource = attr->source;
1492c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    audio_source_t halInputSource;
1493c722f30eef03e77054395ae122470cf8dba93937Eric Laurent    AudioMix *policyMix = NULL;
1494275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
1495c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    if (inputSource == AUDIO_SOURCE_DEFAULT) {
1496c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent        inputSource = AUDIO_SOURCE_MIC;
1497c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    }
1498c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    halInputSource = inputSource;
1499c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent
150020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    // TODO: check for existing client for this port ID
150120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    if (*portId == AUDIO_PORT_HANDLE_NONE) {
150220b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        *portId = AudioPort::getNextUniqueId();
150320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent    }
150420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
1505466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Explicit routing?
1506466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    sp<DeviceDescriptor> deviceDesc;
1507466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
1508466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean        if (mAvailableInputDevices[i]->getId() == selectedDeviceId) {
1509466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean            deviceDesc = mAvailableInputDevices[i];
1510466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean            break;
1511466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean        }
1512466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    }
15138c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
1514466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1515c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
1516275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
1517dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi        status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
1518036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        if (ret != NO_ERROR) {
1519036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie            return ret;
1520c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
152197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi        *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
1522036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1523036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        address = String8(attr->tags + strlen("addr="));
1524275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    } else {
1525c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent        device = getDeviceAndMixForInputSource(inputSource, &policyMix);
1526275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        if (device == AUDIO_DEVICE_NONE) {
1527c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent            ALOGW("getInputForAttr() could not find device for source %d", inputSource);
1528275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            return BAD_VALUE;
1529275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
1530c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        if (policyMix != NULL) {
15317638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            address = policyMix->mDeviceAddress;
153297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
153397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // there is an external policy, but this input is attached to a mix of recorders,
153497bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // meaning it receives audio injected into the framework, so the recorder doesn't
153597bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // know about it and is therefore considered "legacy"
153697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                *inputType = API_INPUT_LEGACY;
153797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            } else {
153897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // recording a mix of players defined by an external policy, we're rerouting for
153997bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // an external policy
154097bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
154197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            }
1542c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        } else if (audio_is_remote_submix_device(device)) {
1543c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            address = String8("0");
154497bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            *inputType = API_INPUT_MIX_CAPTURE;
154582db269d4797cb9909988b723d91fa2094a74b38Eric Laurent        } else if (device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
154682db269d4797cb9909988b723d91fa2094a74b38Eric Laurent            *inputType = API_INPUT_TELEPHONY_RX;
154797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi        } else {
154897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            *inputType = API_INPUT_LEGACY;
1549c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
1550b367f5b2de343bfd9040028b00acb96567f30beaRavi Kumar Alamanda
1551599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1552599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1553599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    *input = getInputForDevice(device, address, session, uid, inputSource,
155420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                               config->sample_rate, config->format, config->channel_mask, flags,
1555599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                               policyMix);
1556599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (*input == AUDIO_IO_HANDLE_NONE) {
1557599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        mInputRoutes.removeRoute(session);
1558599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return INVALID_OPERATION;
1559599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
156020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent
1561599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("getInputForAttr() returns input type = %d", *inputType);
1562599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
1563599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
1564599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1565599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1566599c758b258cc5da0dba9b530425381facc37d77Eric Laurentaudio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
1567599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        String8 address,
1568599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_session_t session,
1569599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        uid_t uid,
1570599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_source_t inputSource,
1571599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        uint32_t samplingRate,
1572599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_format_t format,
1573599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_channel_mask_t channelMask,
1574599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_input_flags_t flags,
1575599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        AudioMix *policyMix)
1576599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
1577599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
1578599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audio_source_t halInputSource = inputSource;
1579599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    bool isSoundTrigger = false;
1580599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1581599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (inputSource == AUDIO_SOURCE_HOTWORD) {
1582599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1583599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (index >= 0) {
1584599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            input = mSoundTriggerSessions.valueFor(session);
1585599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            isSoundTrigger = true;
1586599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1587599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            ALOGV("SoundTrigger capture on session %d input %d", session, input);
1588599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        } else {
1589599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
15905dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent        }
15915dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent    }
15925dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent
1593f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // find a compatible input profile (not necessarily identical in parameters)
1594f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    sp<IOProfile> profile;
1595f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // samplingRate and flags may be updated by getInputProfile
159605ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    uint32_t profileSamplingRate = (samplingRate == 0) ? SAMPLE_RATE_HZ_DEFAULT : samplingRate;
1597f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_format_t profileFormat = format;
1598f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_channel_mask_t profileChannelMask = channelMask;
1599f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_input_flags_t profileFlags = flags;
1600f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    for (;;) {
1601275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        profile = getInputProfile(device, address,
1602f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                  profileSamplingRate, profileFormat, profileChannelMask,
1603f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                  profileFlags);
1604f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        if (profile != 0) {
1605f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung            break; // success
1606050677873c10d4da308ac222f8533c96cca3207eEric Laurent        } else if (profileFlags & AUDIO_INPUT_FLAG_RAW) {
1607050677873c10d4da308ac222f8533c96cca3207eEric Laurent            profileFlags = (audio_input_flags_t) (profileFlags & ~AUDIO_INPUT_FLAG_RAW); // retry
1608f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
1609f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung            profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
1610f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        } else { // fail
1611599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            ALOGW("getInputForDevice() could not find profile for device 0x%X,"
1612599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                  "samplingRate %u, format %#x, channelMask 0x%X, flags %#x",
1613f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    device, samplingRate, format, channelMask, flags);
1614599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            return input;
16155dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent        }
1616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
161705ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    // Pick input sampling rate if not specified by client
161805ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    if (samplingRate == 0) {
161905ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten        samplingRate = profileSamplingRate;
162005ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    }
1621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1622322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    if (profile->getModuleHandle() == 0) {
1623322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        ALOGE("getInputForAttr(): HW module %s not opened", profile->getModuleName());
1624599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return input;
1625cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    }
1626cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
1627599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = new AudioSession(session,
1628599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              inputSource,
1629599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              format,
1630599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              samplingRate,
1631599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              channelMask,
1632599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              flags,
1633599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              uid,
16342f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                              isSoundTrigger,
16352f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                              policyMix, mpClientInterface);
1636599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
163774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent// FIXME: disable concurrent capture until UI is ready
163874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#if 0
1639599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    // reuse an open input if possible
1640555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent    sp<AudioInputDescriptor> reusedInputDesc;
1641599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1642599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
1643fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // reuse input if:
1644fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // - it shares the same profile
1645fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //      AND
1646fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // - it is not a reroute submix input
1647fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //      AND
1648fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        // - it is: not used for sound trigger
1649fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //                OR
1650fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //          used for sound trigger and all clients use the same session ID
1651fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        //
1652fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if ((profile == desc->mProfile) &&
1653fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            (isSoundTrigger == desc->isSoundTrigger()) &&
1654fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            !is_virtual_input_device(device)) {
1655599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1656599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            sp<AudioSession> as = desc->getAudioSession(session);
1657599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            if (as != 0) {
1658599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                // do not allow unmatching properties on same session
1659599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                if (as->matches(audioSession)) {
1660599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    as->changeOpenCount(1);
1661599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                } else {
1662599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    ALOGW("getInputForDevice() record with different attributes"
1663599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                          " exists for session %d", session);
1664555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                    continue;
1665fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                }
1666fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            } else if (isSoundTrigger) {
1667555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                continue;
1668fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            }
1669bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent
1670555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // Reuse the already opened input stream on this profile if:
1671555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // - the new capture source is background OR
1672555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // - the path requested configurations match OR
1673555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // - the new source priority is less than the highest source priority on this input
1674555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // If the input stream cannot be reused, close it before opening a new stream
1675555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // on the same profile for the new client so that the requested path configuration
1676555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            // can be selected.
1677555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            if (!isConcurrentSource(inputSource) &&
1678bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent                    ((desc->mSamplingRate != samplingRate ||
1679fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    desc->mChannelMask != channelMask ||
1680e693002b0fb25099540588245892ed98103749baEric Laurent                    !audio_formats_match(desc->mFormat, format)) &&
1681fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                    (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
1682bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent                     source_priority(inputSource)))) {
1683555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                reusedInputDesc = desc;
1684555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent                continue;
1685599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            } else {
1686599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                desc->addAudioSession(session, audioSession);
1687fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
1688fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                return mInputs.keyAt(i);
1689599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            }
1690599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
1691599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1692599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1693555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent    if (reusedInputDesc != 0) {
1694555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent        AudioSessionCollection sessions = reusedInputDesc->getAudioSessions(false /*activeOnly*/);
1695555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent        for (size_t j = 0; j < sessions.size(); j++) {
1696555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            audio_session_t currentSession = sessions.keyAt(j);
1697555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            stopInput(reusedInputDesc->mIoHandle, currentSession);
1698555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent            releaseInput(reusedInputDesc->mIoHandle, currentSession);
1699555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent        }
1700555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent    }
170174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#endif
1702555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent
1703cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1704f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    config.sample_rate = profileSamplingRate;
1705f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    config.channel_mask = profileChannelMask;
1706f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    config.format = profileFormat;
1707df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
1708e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent    if (address == "") {
1709e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent        DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(device);
1710e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent        //   the inputs vector must be of size 1, but we don't want to crash here
1711e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent        address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
1712e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent    }
1713e301410b8495a3702e21019e92d44ade2a3f81d1Eric Laurent
1714322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
1715599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                   &input,
1716cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                   &config,
1717cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                   &device,
1718fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi                                                   address,
17191c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent                                                   halInputSource,
1720f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                   profileFlags);
1721cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
1722cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    // only accept input with the exact requested set of parameters
1723599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
1724f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        (profileSamplingRate != config.sample_rate) ||
1725e693002b0fb25099540588245892ed98103749baEric Laurent        !audio_formats_match(profileFormat, config.format) ||
1726f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        (profileChannelMask != config.channel_mask)) {
1727599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("getInputForAttr() failed opening input: samplingRate %d"
1728599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              ", format %d, channelMask %x",
1729cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                samplingRate, format, channelMask);
1730599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (input != AUDIO_IO_HANDLE_NONE) {
1731599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            mpClientInterface->closeInput(input);
1732cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        }
1733599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return AUDIO_IO_HANDLE_NONE;
1734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
17361f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
1737f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    inputDesc->mSamplingRate = profileSamplingRate;
1738f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    inputDesc->mFormat = profileFormat;
1739f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    inputDesc->mChannelMask = profileChannelMask;
1740cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    inputDesc->mDevice = device;
1741c722f30eef03e77054395ae122470cf8dba93937Eric Laurent    inputDesc->mPolicyMix = policyMix;
1742599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    inputDesc->addAudioSession(session, audioSession);
1743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1744599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    addInput(input, inputDesc);
1745b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPortListUpdate();
1746466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1747599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return input;
1748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1750bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent//static
1751bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurentbool AudioPolicyManager::isConcurrentSource(audio_source_t source)
1752bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent{
1753bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent    return (source == AUDIO_SOURCE_HOTWORD) ||
1754bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent            (source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
1755bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent            (source == AUDIO_SOURCE_FM_TUNER);
1756bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent}
1757bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent
1758fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentbool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
1759fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        const sp<AudioSession>& audioSession)
1760fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent{
1761fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // Do not allow capture if an active voice call is using a software patch and
1762fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // the call TX source device is on the same HW module.
1763fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // FIXME: would be better to refine to only inputs whose profile connects to the
1764fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // call TX device but this information is not in the audio patch
1765fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (mCallTxPatch != 0 &&
1766fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
1767fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return false;
1768fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1769fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1770fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // starting concurrent capture is enabled if:
1771fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 1) capturing for re-routing
1772fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 2) capturing for HOTWORD source
1773fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 3) capturing for FM TUNER source
1774fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    // 3) All other active captures are either for re-routing or HOTWORD
1775fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1776fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (is_virtual_input_device(inputDesc->mDevice) ||
1777bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent            isConcurrentSource(audioSession->inputSource())) {
1778fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return true;
1779fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1780fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1781fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
1782fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    for (size_t i = 0; i <  activeInputs.size(); i++) {
1783fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        sp<AudioInputDescriptor> activeInput = activeInputs[i];
1784bb9480975322b0d1a09f76ef14f3285fc8af4e5fEric Laurent        if (!isConcurrentSource(activeInput->inputSource(true)) &&
1785fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                !is_virtual_input_device(activeInput->mDevice)) {
1786fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            return false;
1787fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        }
1788fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1789fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1790fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    return true;
1791fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent}
1792fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1793fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
17944dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input,
1795fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                                        audio_session_t session,
1796fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                                        concurrency_type__mask_t *concurrency)
1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("startInput() input %d", input);
1799fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    *concurrency = API_INPUT_CONCURRENCY_NONE;
1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startInput() unknown input %d", input);
1803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
18051f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1807599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
1808599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession == 0) {
18094dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("startInput() unknown session %d on input %d", session, input);
18104dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return BAD_VALUE;
18114dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
18124dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
181374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent// FIXME: disable concurrent capture until UI is ready
181474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#if 0
1815fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
1816fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        ALOGW("startInput(%d) failed: other input already started", input);
1817fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return INVALID_OPERATION;
1818fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1819c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent
1820fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (isInCall()) {
1821fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        *concurrency |= API_INPUT_CONCURRENCY_CALL;
1822fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
1823f7c50104b07091880019f4ecc70d977961148268Eric Laurent    if (mInputs.activeInputsCountOnDevices() != 0) {
1824fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
1825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
182674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#else
182774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent    if (!is_virtual_input_device(inputDesc->mDevice)) {
182874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        if (mCallTxPatch != 0 &&
182974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
183074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            ALOGW("startInput(%d) failed: call in progress", input);
183174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            return INVALID_OPERATION;
183274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        }
183374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
183474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
183574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        for (size_t i = 0; i < activeInputs.size(); i++) {
183674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            sp<AudioInputDescriptor> activeDesc = activeInputs[i];
183774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
183874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            if (is_virtual_input_device(activeDesc->mDevice)) {
183974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                continue;
184074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
184174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
184274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            audio_source_t activeSource = activeDesc->inputSource(true);
184374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            if (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) {
184474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                if (activeSource == AUDIO_SOURCE_HOTWORD) {
184574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    if (activeDesc->hasPreemptedSession(session)) {
184674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                        ALOGW("startInput(%d) failed for HOTWORD: "
184774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                                "other input %d already started for HOTWORD",
184874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                              input, activeDesc->mIoHandle);
184974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                        return INVALID_OPERATION;
185074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    }
185174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                } else {
185274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    ALOGV("startInput(%d) failed for HOTWORD: other input %d already started",
185374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                          input, activeDesc->mIoHandle);
185474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    return INVALID_OPERATION;
185574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                }
185674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            } else {
185774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                if (activeSource != AUDIO_SOURCE_HOTWORD) {
185874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    ALOGW("startInput(%d) failed: other input %d already started",
185974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                          input, activeDesc->mIoHandle);
186074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                    return INVALID_OPERATION;
186174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                }
186274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
186374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        }
186474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
186574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        // if capture is allowed, preempt currently active HOTWORD captures
186674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        for (size_t i = 0; i < activeInputs.size(); i++) {
186774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            sp<AudioInputDescriptor> activeDesc = activeInputs[i];
186874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
186974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            if (is_virtual_input_device(activeDesc->mDevice)) {
187074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                continue;
187174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
187274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent
187374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            audio_source_t activeSource = activeDesc->inputSource(true);
187474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            if (activeSource == AUDIO_SOURCE_HOTWORD) {
187574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                AudioSessionCollection activeSessions =
187674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                        activeDesc->getAudioSessions(true /*activeOnly*/);
187774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                audio_session_t activeSession = activeSessions.keyAt(0);
187874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                audio_io_handle_t activeHandle = activeDesc->mIoHandle;
187974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
188074708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                sessions.add(activeSession);
188174708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                inputDesc->setPreemptedSessions(sessions);
188274708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                stopInput(activeHandle, activeSession);
188374708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                releaseInput(activeHandle, activeSession);
188474708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                ALOGV("startInput(%d) for HOTWORD preempting HOTWORD input %d",
188574708e7c4622d65a7798d5fa9347c55583d347feEric Laurent                      input, activeDesc->mIoHandle);
188674708e7c4622d65a7798d5fa9347c55583d347feEric Laurent            }
188774708e7c4622d65a7798d5fa9347c55583d347feEric Laurent        }
188874708e7c4622d65a7798d5fa9347c55583d347feEric Laurent    }
188974708e7c4622d65a7798d5fa9347c55583d347feEric Laurent#endif
1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1891313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent    // increment activity count before calling getNewInputDevice() below as only active sessions
1892313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent    // are considered for device selection
1893313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent    audioSession->changeActiveCount(1);
1894313d1e7dfb4bf8e0a2f09a9adb287062dd64410cEric Laurent
18958c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Routing?
18968c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mInputRoutes.incRouteActivity(session);
18978c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
1898eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi    if (audioSession->activeCount() == 1 || mInputRoutes.hasRouteChanged(session)) {
1899271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // indicate active capture to sound trigger service if starting capture from a mic on
1900271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // primary HW module
1901f7c50104b07091880019f4ecc70d977961148268Eric Laurent        audio_devices_t device = getNewInputDevice(inputDesc);
1902271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        setInputDevice(input, device, true /* force */);
1903eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
1904eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi        if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
1905eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // if input maps to a dynamic policy with an activity listener, notify of state change
1906eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if ((inputDesc->mPolicyMix != NULL)
1907eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
1908eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
1909eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                        MIX_STATE_MIXING);
1910c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
1911eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
1912f7c50104b07091880019f4ecc70d977961148268Eric Laurent            audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
1913f7c50104b07091880019f4ecc70d977961148268Eric Laurent            if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
191405b345e504a0affd24eefa12686812c554b294ffEric Laurent                    mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1) {
1915eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                SoundTrigger::setCaptureState(true);
1916eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            }
1917eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
1918eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // automatically enable the remote submix output when input is started if not
1919eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // used by a policy mix of type MIX_TYPE_RECORDERS
1920eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // For remote submix (a virtual device), we open only one input per capture request.
1921eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1922eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                String8 address = String8("");
1923eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (inputDesc->mPolicyMix == NULL) {
1924eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = String8("0");
1925eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1926eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = inputDesc->mPolicyMix->mDeviceAddress;
1927eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
1928eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (address != "") {
1929eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1930eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                            AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1931eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                            address, "remote-submix");
1932eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
1933c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
193474a8e2533561f04029873446206ab407cd2e033bGlenn Kasten        }
1935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1937599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("AudioPolicyManager::startInput() input source = %d", audioSession->inputSource());
1938e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
19424dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input,
19434dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent                                       audio_session_t session)
1944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopInput() input %d", input);
1946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() unknown input %d", input);
1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
19511f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1953599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
19544dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    if (index < 0) {
19554dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("stopInput() unknown session %d on input %d", session, input);
19564dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return BAD_VALUE;
19574dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
19584dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
1959599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->activeCount() == 0) {
1960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() input %d already stopped", input);
1961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
19626a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
19636a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten
1964599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audioSession->changeActiveCount(-1);
1965466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1966466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Routing?
1967466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    mInputRoutes.decRouteActivity(session);
1968466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1969eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi    if (audioSession->activeCount() == 0) {
1970232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent
1971eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi        if (inputDesc->isActive()) {
1972eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
1973eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi        } else {
1974eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // if input maps to a dynamic policy with an activity listener, notify of state change
1975eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if ((inputDesc->mPolicyMix != NULL)
1976eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
1977eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
1978eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                        MIX_STATE_IDLE);
1979c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
1980eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi
1981eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // automatically disable the remote submix output when input is stopped if not
1982eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            // used by a policy mix of type MIX_TYPE_RECORDERS
1983eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi            if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1984eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                String8 address = String8("");
1985eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (inputDesc->mPolicyMix == NULL) {
1986eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = String8("0");
1987eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1988eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    address = inputDesc->mPolicyMix->mDeviceAddress;
1989eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
1990eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                if (address != "") {
1991eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                    setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1992eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                                             AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1993eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                                             address, "remote-submix");
1994eb6421d78c15b8a15455473150ff0deff50b483aJean-Michel Trivi                }
1995c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
1996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1997f7c50104b07091880019f4ecc70d977961148268Eric Laurent            audio_devices_t device = inputDesc->mDevice;
1998fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            resetInputDevice(input);
1999df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
2000f7c50104b07091880019f4ecc70d977961148268Eric Laurent            // indicate inactive capture to sound trigger service if stopping capture from a mic on
2001f7c50104b07091880019f4ecc70d977961148268Eric Laurent            // primary HW module
2002f7c50104b07091880019f4ecc70d977961148268Eric Laurent            audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
2003f7c50104b07091880019f4ecc70d977961148268Eric Laurent            if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
2004f7c50104b07091880019f4ecc70d977961148268Eric Laurent                    mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
2005fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                SoundTrigger::setCaptureState(false);
2006fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            }
2007fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            inputDesc->clearPreemptedSessions();
2008df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        }
2009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
20106a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    return NO_ERROR;
2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
20134dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input,
20144dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent                                      audio_session_t session)
2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
20162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() %d", input);
2018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseInput() releasing unknown input %d", input);
2021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2023466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
2024466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Routing
2025466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    mInputRoutes.removeRoute(session);
2026466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
20276a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
20286a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    ALOG_ASSERT(inputDesc != 0);
20294dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
2030599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
2031587b8dfdbc3d3b1dd9ffc1996b9a07cd9b284833vivek mehta    if (audioSession == 0) {
20324dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("releaseInput() unknown session %d on input %d", session, input);
20334dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return;
20344dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
2035599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
2036599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->openCount() == 0) {
2037599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("releaseInput() invalid open count %d on session %d",
2038599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              audioSession->openCount(), session);
20396a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        return;
20406a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
2041599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
2042599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->changeOpenCount(-1) == 0) {
2043599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        inputDesc->removeAudioSession(session);
2044599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
2045599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
204665bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Trivi    if (inputDesc->getOpenRefCount() > 0) {
20476a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        ALOGV("releaseInput() exit > 0");
20486a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        return;
20496a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
20506a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten
205105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    closeInput(input);
2052b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPortListUpdate();
2053e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() exit");
2054e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2055e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2056d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() {
205705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    bool patchRemoved = false;
205805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
2059d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
206005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
20618c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
206205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        if (patch_index >= 0) {
206305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
2064fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten            (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
206505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            mAudioPatches.removeItemsAt(patch_index);
206605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            patchRemoved = true;
206705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        }
2068d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        mpClientInterface->closeInput(mInputs.keyAt(input_index));
2069d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
2070d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    mInputs.clear();
207152785f3df24fe817af4f1c3c2cddfb30ab5450eeChris Thornton    SoundTrigger::setCaptureState(false);
20726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
207305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
207405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (patchRemoved) {
207505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
207605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
2077d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
2078d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2079e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
2080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMin,
2081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMax)
2082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
2084d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
208528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent
208628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // initialize other private stream volumes which follow this one
2087794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2088794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
208928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
209028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
209128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
2092223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
2093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2095e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
209653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  int index,
209753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_devices_t device)
2098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2100d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if ((index < mVolumeCurves->getVolumeIndexMin(stream)) ||
2101d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            (index > mVolumeCurves->getVolumeIndexMax(stream))) {
2102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2104e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
2105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Force max volume if stream cannot be muted
2109d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
2110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
21111fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
2112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, device, index);
2113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
211428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // update other private stream volumes which follow this one
2115794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2116794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
211728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
211828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
211928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
2120223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
2121e04e62bc05316d9682688f87053be5cf47e9c707Eric Laurent
21221fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // update volume on all outputs and streams matching the following:
21231fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - The requested stream (or a stream matching for volume control) is active on the output
21241fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - The device (or devices) selected by the strategy corresponding to this stream includes
21251fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // the requested device
21261fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - For non default requested device, currently selected device on the output is either the
21271fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // requested device or one of the devices selected by the strategy
21285a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
21295a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // no specific device volume value exists for currently selected device.
2130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NO_ERROR;
2131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
2132c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
2133c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
2134794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2135794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
213628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                continue;
213728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            }
2138d3926fe68ffd8d156e7c019277bbeb32ca786d8eEric Laurent            if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
2139d3926fe68ffd8d156e7c019277bbeb32ca786d8eEric Laurent                    (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
21401fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                continue;
21411fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
2142794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
2143e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, false /*fromCache*/);
2144e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
2145e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                    ((curStreamDevice & device) == 0)) {
21461fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                continue;
21471fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
2148e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            bool applyVolume;
21495a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
21501fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                curStreamDevice |= device;
2151e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                applyVolume = (curDevice & curStreamDevice) != 0;
2152e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            } else {
2153e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
2154e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                        stream, Volume::getDeviceForVolume(curStreamDevice));
21551fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
21561fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent
2157e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            if (applyVolume) {
2158dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                //FIXME: workaround for truncated touch sounds
2159dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // delayed volume change for system stream to be removed when the problem is
2160dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // handled by system UI
216128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                status_t volStatus =
2162dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                        checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice,
2163dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                            (stream == AUDIO_STREAM_SYSTEM) ? TOUCH_SOUND_FIXED_DELAY_MS : 0);
216428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                if (volStatus != NO_ERROR) {
216528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                    status = volStatus;
216628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                }
2167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2168223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        }
2169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return status;
2171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2173e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
2174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int *index,
2175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
2176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index == NULL) {
2178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
2181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
2182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
21835a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
2184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the strategy the stream belongs to.
21855a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
2186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
2187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2188dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    device = Volume::getDeviceForVolume(device);
2189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2190d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    *index =  mVolumeCurves->getVolumeIndex(stream, device);
2191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
2192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
219536829f97c0c547d9c6c918e248071cc616818616Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
2196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several suitable for global effects.
2198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
2199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: An offloaded output. If the effect ends up not being offloadable,
2200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    AudioFlinger will invalidate the track and the offloaded output
2201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    will be closed causing the effect to be moved to a PCM output.
2202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: A deep buffer output
220336829f97c0c547d9c6c918e248071cc616818616Eric Laurent    // 3: The primary output
220436829f97c0c547d9c6c918e248071cc616818616Eric Laurent    // 4: the first output in the list
220536829f97c0c547d9c6c918e248071cc616818616Eric Laurent
220636829f97c0c547d9c6c918e248071cc616818616Eric Laurent    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
220736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
220836829f97c0c547d9c6c918e248071cc616818616Eric Laurent    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
2209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
221136829f97c0c547d9c6c918e248071cc616818616Eric Laurent        return AUDIO_IO_HANDLE_NONE;
2212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
221436829f97c0c547d9c6c918e248071cc616818616Eric Laurent    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
221536829f97c0c547d9c6c918e248071cc616818616Eric Laurent    bool activeOnly = true;
2216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
221736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    while (output == AUDIO_IO_HANDLE_NONE) {
221836829f97c0c547d9c6c918e248071cc616818616Eric Laurent        audio_io_handle_t outputOffloaded = AUDIO_IO_HANDLE_NONE;
221936829f97c0c547d9c6c918e248071cc616818616Eric Laurent        audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
222036829f97c0c547d9c6c918e248071cc616818616Eric Laurent        audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;
222136829f97c0c547d9c6c918e248071cc616818616Eric Laurent
222236829f97c0c547d9c6c918e248071cc616818616Eric Laurent        for (size_t i = 0; i < outputs.size(); i++) {
222336829f97c0c547d9c6c918e248071cc616818616Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
222436829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
222536829f97c0c547d9c6c918e248071cc616818616Eric Laurent                continue;
222636829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
222736829f97c0c547d9c6c918e248071cc616818616Eric Laurent            ALOGV("selectOutputForMusicEffects activeOnly %d outputs[%zu] flags 0x%08x",
222836829f97c0c547d9c6c918e248071cc616818616Eric Laurent                  activeOnly, i, desc->mFlags);
222936829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
223036829f97c0c547d9c6c918e248071cc616818616Eric Laurent                outputOffloaded = outputs[i];
223136829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
223236829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
223336829f97c0c547d9c6c918e248071cc616818616Eric Laurent                outputDeepBuffer = outputs[i];
223436829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
223536829f97c0c547d9c6c918e248071cc616818616Eric Laurent            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
223636829f97c0c547d9c6c918e248071cc616818616Eric Laurent                outputPrimary = outputs[i];
223736829f97c0c547d9c6c918e248071cc616818616Eric Laurent            }
2238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
223936829f97c0c547d9c6c918e248071cc616818616Eric Laurent        if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
224036829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputOffloaded;
224136829f97c0c547d9c6c918e248071cc616818616Eric Laurent        } else if (outputDeepBuffer != AUDIO_IO_HANDLE_NONE) {
224236829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputDeepBuffer;
224336829f97c0c547d9c6c918e248071cc616818616Eric Laurent        } else if (outputPrimary != AUDIO_IO_HANDLE_NONE) {
224436829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputPrimary;
224536829f97c0c547d9c6c918e248071cc616818616Eric Laurent        } else {
224636829f97c0c547d9c6c918e248071cc616818616Eric Laurent            output = outputs[0];
2247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
224836829f97c0c547d9c6c918e248071cc616818616Eric Laurent        activeOnly = false;
2249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
225136829f97c0c547d9c6c918e248071cc616818616Eric Laurent    if (output != mMusicEffectOutput) {
225236829f97c0c547d9c6c918e248071cc616818616Eric Laurent        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
225336829f97c0c547d9c6c918e248071cc616818616Eric Laurent        mMusicEffectOutput = output;
2254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
225636829f97c0c547d9c6c918e248071cc616818616Eric Laurent    ALOGV("selectOutputForMusicEffects selected output %d", output);
225736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    return output;
2258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
226036829f97c0c547d9c6c918e248071cc616818616Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc __unused)
2261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
226236829f97c0c547d9c6c918e248071cc616818616Eric Laurent    return selectOutputForMusicEffects();
2263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2265e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
2266e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                audio_io_handle_t io,
2267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                uint32_t strategy,
2268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int session,
2269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int id)
2270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(io);
2272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
2273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index = mInputs.indexOfKey(io);
2274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (index < 0) {
2275e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("registerEffect() unknown io %d", io);
2276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
2277e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
227945ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return mEffects.registerEffect(desc, io, strategy, session, id);
2280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2282c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
2283c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
228428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    bool active = false;
2285794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT && !active; curStream++) {
2286794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
228728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
228828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
228928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs);
229028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    }
229128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    return active;
2292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
2293c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
2294c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
2295c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
2296c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return mOutputs.isStreamActiveRemotely(stream, inPastMs);
2297c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
2298c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
2299e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const
2300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
23021f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent        const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
2303599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (inputDescriptor->isSourceActive(source)) {
2304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
2305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
2308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2310275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// Register a list of custom mixes with their attributes and format.
2311275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a mix is registered, corresponding input and output profiles are
2312275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// added to the remote submix hw module. The profile contains only the
2313275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// parameters (sampling rate, format...) specified by the mix.
2314275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// The corresponding input remote submix device is also connected.
2315275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2316275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a remote submix device is connected, the address is checked to select the
2317275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// appropriate profile and the corresponding input or output stream is opened.
2318275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2319275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When capture starts, getInputForAttr() will:
2320275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 1 look for a mix matching the address passed in attribtutes tags if any
2321275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 2 if none found, getDeviceForInputSource() will:
2322275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//     - 2.1 look for a mix matching the attributes source
2323275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//     - 2.2 if none found, default to device selection by policy rules
2324275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// At this time, the corresponding output remote submix device is also connected
2325275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// and active playback use cases can be transferred to this mix if needed when reconnecting
2326275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// after AudioTracks are invalidated
2327275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2328275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When playback starts, getOutputForAttr() will:
2329275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 1 look for a mix matching the address passed in attribtutes tags if any
2330275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 2 if none found, look for a mix matching the attributes usage
2331275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 3 if none found, default to device and output selection by policy rules.
2332275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2333e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::registerPolicyMixes(const Vector<AudioMix>& mixes)
2334275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{
23357638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    ALOGV("registerPolicyMixes() %zu mix(es)", mixes.size());
23367638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    status_t res = NO_ERROR;
23377638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
23387638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    sp<HwModule> rSubmixModule;
23397638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    // examine each mix's route type
23407638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    for (size_t i = 0; i < mixes.size(); i++) {
23417638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        // we only support MIX_ROUTE_FLAG_LOOP_BACK or MIX_ROUTE_FLAG_RENDER, not the combination
23427638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_ALL) == MIX_ROUTE_FLAG_ALL) {
23437638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            res = INVALID_OPERATION;
2344275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            break;
2345275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
23467638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
23477638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // Loop back through "remote submix"
23487638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
23497638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                for (size_t j = 0; i < mHwModules.size(); j++) {
23507638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
23517638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                            && mHwModules[j]->mHandle != 0) {
23527638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        rSubmixModule = mHwModules[j];
23537638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        break;
23547638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
23557638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
23567638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2357275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
23587638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
2359275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
23607638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
23617638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                ALOGE(" Unable to find audio module for submix, aborting mix %zu registration", i);
23627638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
23637638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
23647638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2365275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
23667638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
2367036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
23687638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.registerMix(address, mixes[i], 0 /*output desc*/) != NO_ERROR) {
23695ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                ALOGE(" Error registering mix %zu for address %s", i, address.string());
23707638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
23717638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
23727638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
23737638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_config_t outputConfig = mixes[i].mFormat;
23747638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_config_t inputConfig = mixes[i].mFormat;
23757638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
23767638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // stereo and let audio flinger do the channel conversion if needed.
23777638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
23787638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
23797638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->addOutputProfile(address, &outputConfig,
23807638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address);
23817638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->addInputProfile(address, &inputConfig,
23827638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
23837638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
23847638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
23857638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
23867638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
23877638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
23887638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            } else {
23897638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
23907638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
23917638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
23927638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
23937638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        } else if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
23947638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
23957638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_devices_t device = mixes[i].mDeviceType;
23965ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            ALOGV(" registerPolicyMixes() mix %zu of %zu is RENDER, dev=0x%X addr=%s",
23975ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                    i, mixes.size(), device, address.string());
23987638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
23995ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            bool foundOutput = false;
24007638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            for (size_t j = 0 ; j < mOutputs.size() ; j++) {
24017638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(j);
24027638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                sp<AudioPatch> patch = mAudioPatches.valueFor(desc->getPatchHandle());
24037638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                if ((patch != 0) && (patch->mPatch.num_sinks != 0)
24047638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        && (patch->mPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE)
24057638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        && (patch->mPatch.sinks[0].ext.device.type == device)
24065ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        && (strncmp(patch->mPatch.sinks[0].ext.device.address, address.string(),
24075ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                                AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
24087638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (mPolicyMixes.registerMix(address, mixes[i], desc) != NO_ERROR) {
24097638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        res = INVALID_OPERATION;
24105ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                    } else {
24115ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        foundOutput = true;
24127638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
24137638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    break;
24147638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
24157638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
24167638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
24177638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (res != NO_ERROR) {
24187638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                ALOGE(" Error registering mix %zu for device 0x%X addr %s",
24195ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        i, device, address.string());
24205ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                res = INVALID_OPERATION;
24215ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                break;
24225ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            } else if (!foundOutput) {
24235ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                ALOGE(" Output not found for mix %zu for device 0x%X addr %s",
24245ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        i, device, address.string());
24257638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
24267638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
24277638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2428c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
2429275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
24307638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    if (res != NO_ERROR) {
24317638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        unregisterPolicyMixes(mixes);
24327638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    }
24337638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    return res;
2434275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent}
2435275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2436275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
2437275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{
24387b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent    ALOGV("unregisterPolicyMixes() num mixes %zu", mixes.size());
24397638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    status_t res = NO_ERROR;
24407638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    sp<HwModule> rSubmixModule;
24417638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    // examine each mix's route type
2442275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    for (size_t i = 0; i < mixes.size(); i++) {
24437638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
24447638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
24457638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
24467638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                for (size_t j = 0; i < mHwModules.size(); j++) {
24477638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
24487638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                            && mHwModules[j]->mHandle != 0) {
24497638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        rSubmixModule = mHwModules[j];
24507638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        break;
24517638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
24527638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
24537638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
24547638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
24557638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
24567638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
24577638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2458036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
24597638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
2460275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
24617638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
24627638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
24637638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
24647638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2465275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
24667638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
24677638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
24687638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
24697638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
24707638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
24717638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
24727638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
24737638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
24747638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
24757638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
24767638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
24777638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
24787638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->removeOutputProfile(address);
24797638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->removeInputProfile(address);
24807638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
24817638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        } if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
24827638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.unregisterMix(mixes[i].mDeviceAddress) != NO_ERROR) {
24837638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
24847638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
24857638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2486275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
2487275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
24887638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    return res;
2489275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent}
2490275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2492e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd)
2493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
2495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
2496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
2497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
2499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
2500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
250187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    snprintf(buffer, SIZE, " Primary Output: %d\n",
250287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent             hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
2503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25040d6a03301d77724c00c7a9ce7b8c123092d07a19Mikhail Naganov    std::string stateLiteral;
25050d6a03301d77724c00c7a9ce7b8c123092d07a19Mikhail Naganov    AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
25060d6a03301d77724c00c7a9ce7b8c123092d07a19Mikhail Naganov    snprintf(buffer, SIZE, " Phone state: %s\n", stateLiteral.c_str());
2507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25083b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for communications %d\n",
25092110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
2510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25112110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
2512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25132110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
2514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25152110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
2516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25172110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
2518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
25197b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang    snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
25202110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
25217b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang    result.append(buffer);
252209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    snprintf(buffer, SIZE, " Force use for encoded surround output %d\n",
252309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND));
252409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    result.append(buffer);
25259459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
25269459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    result.append(buffer);
25272ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
25282ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    result.append(buffer);
25299459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
25302110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    write(fd, result.string(), result.size());
2531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2532112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    mAvailableOutputDevices.dump(fd, String8("Available output"));
2533112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    mAvailableInputDevices.dump(fd, String8("Available input"));
253453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mHwModules.dump(fd);
253553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mOutputs.dump(fd);
253653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mInputs.dump(fd);
2537d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->dump(fd);
253845ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mEffects.dump(fd);
253953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mAudioPatches.dump(fd);
254044344b05261cb9ad46a43e635f637b89aecc7afeMikhail Naganov    mPolicyMixes.dump(fd);
2541e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2543e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded.
2546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy
2547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system.
2548e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
2549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
2551d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent     " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
2552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.sample_rate, offloadInfo.channel_mask,
2553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.format,
2554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
2555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.has_video);
2556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
25572ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono) {
25582ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        return false; // no offloading if mono is set.
25592ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
25602ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
2561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if offload has been disabled
2562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char propValue[PROPERTY_VALUE_MAX];
2563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.disable", propValue, "0")) {
2564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (atoi(propValue) != 0) {
2565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
2566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if stream type is music, then only allow offload as of now.
2571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
2572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
2573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
2574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //TODO: enable audio offloading with video when ready
257808945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung    const bool allowOffloadWithVideo =
257908945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung            property_get_bool("audio.offload.video", false /* default_value */);
258008945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung    if (offloadInfo.has_video && !allowOffloadWithVideo) {
2581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: has_video == true, returning false");
2582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //If duration is less than minimum value defined in property, return false
2586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
2587e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
2588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
2589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
2592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
2593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
2597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
2598e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
2599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
2600e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
2601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
260245ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (mEffects.isNonOffloadableEffectEnabled()) {
2603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // See if there is a profile to support this.
2607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // AUDIO_DEVICE_NONE
26081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
2609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.sample_rate,
2610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.format,
2611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.channel_mask,
2612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
26131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
26141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return (profile != 0);
2615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
26176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
26186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            audio_port_type_t type,
26196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            unsigned int *num_ports,
26206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            struct audio_port *ports,
26216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            unsigned int *generation)
26226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
26236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
26246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            generation == NULL) {
26256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
26266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
26276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
26286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (ports == NULL) {
26296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        *num_ports = 0;
26306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
26316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
26326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    size_t portsWritten = 0;
26336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    size_t portsMax = *num_ports;
26346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *num_ports = 0;
26356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
26365a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
26375a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        // as they are used by stub HALs by convention
26386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
26395a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
26405a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
26415a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    continue;
26425a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
26435a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (portsWritten < portsMax) {
26445a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
26455a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
26465a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                (*num_ports)++;
26476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
26496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
26505a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
26515a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
26525a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    continue;
26535a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
26545a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (portsWritten < portsMax) {
26555a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
26565a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
26575a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                (*num_ports)++;
26586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
26606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
26616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
26626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
26636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
26646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                mInputs[i]->toAudioPort(&ports[portsWritten++]);
26656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            *num_ports += mInputs.size();
26676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
26686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
266984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            size_t numOutputs = 0;
267084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
267184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                if (!mOutputs[i]->isDuplicated()) {
267284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    numOutputs++;
267384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    if (portsWritten < portsMax) {
267484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        mOutputs[i]->toAudioPort(&ports[portsWritten++]);
267584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    }
267684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                }
26776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
267884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            *num_ports += numOutputs;
26796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
26806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
26816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *generation = curAudioPortGeneration();
2682beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn    ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
26836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
26846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
26856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
26866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
26876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
26886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
26896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
26906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
26916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
26926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               audio_patch_handle_t *handle,
26936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               uid_t uid)
26946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
26956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch()");
26966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
26976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (handle == NULL || patch == NULL) {
26986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
26996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
27016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
2702874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2703874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2704874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        return BAD_VALUE;
2705874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
2706874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    // only one source per audio patch supported for now
2707874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->num_sources > 1) {
27086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
27096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
2710874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2711874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
27126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
27136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
2714874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    for (size_t i = 0; i < patch->num_sinks; i++) {
2715874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2716874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            return INVALID_OPERATION;
2717874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        }
2718874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
27196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp<AudioPatch> patchDesc;
27216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index = mAudioPatches.indexOfKey(*handle);
27226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
27246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                           patch->sources[0].role,
27256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                           patch->sources[0].type);
2726874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#if LOG_NDEBUG == 0
2727874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    for (size_t i = 0; i < patch->num_sinks; i++) {
27287b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent        ALOGV("createAudioPatch sink %zu: id %d role %d type %d", i, patch->sinks[i].id,
2729874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                             patch->sinks[i].role,
2730874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                             patch->sinks[i].type);
2731874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
2732874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#endif
27336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
27356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        patchDesc = mAudioPatches.valueAt(index);
27366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
27376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  mUidCached, patchDesc->mUid, uid);
27386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
27396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
27406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
2742a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten        *handle = AUDIO_PATCH_HANDLE_NONE;
27436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
2746c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
27476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (outputDesc == NULL) {
27486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
27496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
27506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
275184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent        ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
275284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                                                outputDesc->mIoHandle);
27536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc != 0) {
27546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
27556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
27566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                          patchDesc->mPatch.sources[0].id, patch->sources[0].id);
27576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
27586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
2760874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        DeviceVector devices;
2761874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        for (size_t i = 0; i < patch->num_sinks; i++) {
2762874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // Only support mix to devices connection
2763874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // TODO add support for mix to mix connection
2764874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2765874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                ALOGV("createAudioPatch() source mix but sink is not a device");
2766874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2767874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
2768874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            sp<DeviceDescriptor> devDesc =
2769874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2770874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (devDesc == 0) {
2771874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2772874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return BAD_VALUE;
2773874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
27746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
277553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
2776275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                           devDesc->mAddress,
2777874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                           patch->sources[0].sample_rate,
277853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           NULL,  // updatedSamplingRate
277953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           patch->sources[0].format,
2780f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                           NULL,  // updatedFormat
278153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           patch->sources[0].channel_mask,
2782f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                           NULL,  // updatedChannelMask
278353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
2784f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                ALOGV("createAudioPatch() profile not supported for device %08x",
2785f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                        devDesc->type());
2786874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2787874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
2788874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            devices.add(devDesc);
2789874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        }
2790874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        if (devices.size() == 0) {
27916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
27926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
2793874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
27946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        // TODO: reconfigure output format and channels here
27956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        ALOGV("createAudioPatch() setting device %08x on output %d",
2796874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent              devices.types(), outputDesc->mIoHandle);
2797c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        setOutputDevice(outputDesc, devices.types(), true, 0, handle);
27986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*handle);
27996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (index >= 0) {
28006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
28016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
28026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            patchDesc = mAudioPatches.valueAt(index);
28046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            patchDesc->mUid = uid;
28056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() success");
28066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
28076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
28086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
28096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
28106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
28116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
28126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // input device to input mix connection
2813874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // only one sink supported when connecting an input device to a mix
2814874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (patch->num_sinks > 1) {
2815874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2816874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
281753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
28186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (inputDesc == NULL) {
28196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
28206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0) {
28226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
28236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    return BAD_VALUE;
28246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
28256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp<DeviceDescriptor> devDesc =
28276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
28286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (devDesc == 0) {
28296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
28306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
283253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
2833275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          devDesc->mAddress,
2834275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].sample_rate,
2835275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          NULL, /*updatedSampleRate*/
2836275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].format,
2837f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                          NULL, /*updatedFormat*/
2838275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].channel_mask,
2839f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                          NULL, /*updatedChannelMask*/
2840275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          // FIXME for the parameter type,
2841275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          // and the NONE
2842275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          (audio_output_flags_t)
28436a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten                                                            AUDIO_INPUT_FLAG_NONE)) {
28446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
28456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // TODO: reconfigure output format and channels here
28476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() setting device %08x on output %d",
284853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  devDesc->type(), inputDesc->mIoHandle);
284953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
28506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            index = mAudioPatches.indexOfKey(*handle);
28516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
28526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
28536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
28546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
28556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
28566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mUid = uid;
28576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("createAudioPatch() success");
28586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
28596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
28606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
28616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
28636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // device to device connection
28646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0) {
2865874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
28666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    return BAD_VALUE;
28676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
28686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
28696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp<DeviceDescriptor> srcDeviceDesc =
28706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
287158f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent            if (srcDeviceDesc == 0) {
287258f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent                return BAD_VALUE;
287358f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent            }
2874874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
28756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            //update source and sink with our own data as the data passed in the patch may
28766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // be incomplete.
28776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            struct audio_patch newPatch = *patch;
28786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
2879874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2880874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            for (size_t i = 0; i < patch->num_sinks; i++) {
2881874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2882874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    ALOGV("createAudioPatch() source device but one sink is not a device");
2883874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    return INVALID_OPERATION;
2884874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                }
2885874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2886874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                sp<DeviceDescriptor> sinkDeviceDesc =
2887874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2888874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (sinkDeviceDesc == 0) {
2889874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    return BAD_VALUE;
2890874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                }
2891874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
2892874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
28933bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // create a software bridge in PatchPanel if:
28943bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // - source and sink devices are on differnt HW modules OR
28953bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // - audio HAL version is < 3.0
2896fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
28979ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov                        (srcDeviceDesc->mModule->getHalVersionMajor() < 3)) {
28983bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                    // support only one sink device for now to simplify output selection logic
2899874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    if (patch->num_sinks > 1) {
290083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                        return INVALID_OPERATION;
290183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                    }
2902874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    SortedVector<audio_io_handle_t> outputs =
290353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                            getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
2904874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    // if the sink device is reachable via an opened output stream, request to go via
2905874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    // this output stream by adding a second source to the patch description
29068838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    audio_io_handle_t output = selectOutput(outputs,
29078838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                            AUDIO_OUTPUT_FLAG_NONE,
29088838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                            AUDIO_FORMAT_INVALID);
2909874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    if (output != AUDIO_IO_HANDLE_NONE) {
2910874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2911874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        if (outputDesc->isDuplicated()) {
2912874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                            return INVALID_OPERATION;
2913874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        }
2914874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
29153bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                        newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
2916874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        newPatch.num_sources = 2;
2917874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    }
291883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                }
29196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // TODO: check from routing capabilities in config file and other conflicting patches
29216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
29226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
29236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
29246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
29256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
29276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            status_t status = mpClientInterface->createAudioPatch(&newPatch,
29286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  &afPatchHandle,
29296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  0);
29306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
29316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  status, afPatchHandle);
29326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (status == NO_ERROR) {
29336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
293498cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&newPatch, uid);
29356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
29366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
29376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = newPatch;
29386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
29396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
29406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                *handle = patchDesc->mHandle;
29416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
2942b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
29436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
29446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
29456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                status);
29466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
29476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
29496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
29506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
29516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
29526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
29536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
29546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
29556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
29566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
29576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
29586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                  uid_t uid)
29596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
29606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("releaseAudioPatch() patch %d", handle);
29616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
29626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index = mAudioPatches.indexOfKey(handle);
29636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
29646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
29656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
29666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
29676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
29686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
29696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent          mUidCached, patchDesc->mUid, uid);
29706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
29716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
29726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
29736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
29746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    struct audio_patch *patch = &patchDesc->mPatch;
29756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    patchDesc->mUid = mUidCached;
29766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
2977c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
29786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (outputDesc == NULL) {
29796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
29806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
29816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
29826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
2983c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        setOutputDevice(outputDesc,
2984c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        getNewOutputDevice(outputDesc, true /*fromCache*/),
29856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       true,
29866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       0,
29876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       NULL);
29886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
29896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
299053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
29916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (inputDesc == NULL) {
29926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
29936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
29946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
29956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            setInputDevice(inputDesc->mIoHandle,
2996fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                           getNewInputDevice(inputDesc),
29976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                           true,
29986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                           NULL);
29996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
30006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
30016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
30026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                              status, patchDesc->mAfPatchHandle);
30036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            removeAudioPatch(patchDesc->mHandle);
30046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            nextAudioPortGeneration();
3005b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent            mpClientInterface->onAudioPatchListUpdate();
30066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
30076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
30086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
30096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
30106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
30116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
30126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
30136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
30146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
30156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
30166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              struct audio_patch *patches,
30176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              unsigned int *generation)
30186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
301953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    if (generation == NULL) {
30206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
30216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
30226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *generation = curAudioPortGeneration();
302353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return mAudioPatches.listAudioPatches(num_patches, patches);
30246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
30256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
3026e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
30276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
3028e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("setAudioPortConfig()");
3029e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3030e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    if (config == NULL) {
3031e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        return BAD_VALUE;
3032e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3033e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("setAudioPortConfig() on port handle %d", config->id);
3034e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    // Only support gain configuration for now
3035a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
3036a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        return INVALID_OPERATION;
3037e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3038e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3039a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    sp<AudioPortConfig> audioPortConfig;
3040e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    if (config->type == AUDIO_PORT_TYPE_MIX) {
3041e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
3042c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
3043e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            if (outputDesc == NULL) {
3044e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                return BAD_VALUE;
3045e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            }
304684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
304784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        "setAudioPortConfig() called on duplicated output %d",
304884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        outputDesc->mIoHandle);
3049a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent            audioPortConfig = outputDesc;
3050e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
305153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(config->id);
3052e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            if (inputDesc == NULL) {
3053e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                return BAD_VALUE;
3054e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            }
3055a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent            audioPortConfig = inputDesc;
3056e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else {
3057e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
3058e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
3059e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
3060e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        sp<DeviceDescriptor> deviceDesc;
3061e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
3062e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
3063e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
3064e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
3065e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else {
3066e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
3067e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
3068e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (deviceDesc == NULL) {
3069e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
3070e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
3071a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig = deviceDesc;
3072e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    } else {
3073e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        return BAD_VALUE;
3074e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3075e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3076a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    struct audio_port_config backupConfig;
3077a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
3078a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (status == NO_ERROR) {
3079a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        struct audio_port_config newConfig;
3080a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig->toAudioPortConfig(&newConfig, config);
3081a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
3082e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3083a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (status != NO_ERROR) {
3084a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig->applyAudioPortConfig(&backupConfig);
3085e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
3086e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
3087e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return status;
30886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
30896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
30908c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::releaseResourcesForUid(uid_t uid)
30918c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
3092d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    clearAudioSources(uid);
30938c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    clearAudioPatches(uid);
30948c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    clearSessionRoutes(uid);
30958c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
30968c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
30976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::clearAudioPatches(uid_t uid)
30986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
30990add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {
31006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
31016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid == uid) {
31020add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent            releaseAudioPatch(mAudioPatches.keyAt(i), uid);
31036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
31046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
31056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
31066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
31078c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
31088c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            audio_io_handle_t ouptutToSkip)
31098c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
31108c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
31118c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
31128c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t j = 0; j < mOutputs.size(); j++) {
31138c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (mOutputs.keyAt(j) == ouptutToSkip) {
31148c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            continue;
31158c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
31168c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
31178c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
31188c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            continue;
31198c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
31208c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // If the default device for this strategy is on another output mix,
31218c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // invalidate all tracks in this strategy to force re connection.
31228c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // Otherwise select new device on the output mix.
31238c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
3124794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
31258c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                if (getStrategy((audio_stream_type_t)stream) == strategy) {
31268c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                    mpClientInterface->invalidateStream((audio_stream_type_t)stream);
31278c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                }
31288c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
31298c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        } else {
31308c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
31318c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            setOutputDevice(outputDesc, newDevice, false);
31328c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
31338c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
31348c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
31358c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
31368c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::clearSessionRoutes(uid_t uid)
31378c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
31388c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // remove output routes associated with this uid
31398c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<routing_strategy> affectedStrategies;
31408c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (ssize_t i = (ssize_t)mOutputRoutes.size() - 1; i >= 0; i--)  {
31418c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SessionRoute> route = mOutputRoutes.valueAt(i);
31428c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (route->mUid == uid) {
31438c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mOutputRoutes.removeItemsAt(i);
31448c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            if (route->mDeviceDescriptor != 0) {
31458c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                affectedStrategies.add(getStrategy(route->mStreamType));
31468c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
31478c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
31488c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
31498c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // reroute outputs if necessary
31508c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < affectedStrategies.size(); i++) {
31518c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        checkStrategyRoute(affectedStrategies[i], AUDIO_IO_HANDLE_NONE);
31528c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
31538c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
31548c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // remove input routes associated with this uid
31558c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_source_t> affectedSources;
31568c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (ssize_t i = (ssize_t)mInputRoutes.size() - 1; i >= 0; i--)  {
31578c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SessionRoute> route = mInputRoutes.valueAt(i);
31588c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (route->mUid == uid) {
31598c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mInputRoutes.removeItemsAt(i);
31608c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            if (route->mDeviceDescriptor != 0) {
31618c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                affectedSources.add(route->mSource);
31628c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
31638c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
31648c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
31658c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // reroute inputs if necessary
31668c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_io_handle_t> inputsToClose;
31678c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
31688c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
3169599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (affectedSources.indexOf(inputDesc->inputSource()) >= 0) {
31708c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            inputsToClose.add(inputDesc->mIoHandle);
31718c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
31728c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
31738c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < inputsToClose.size(); i++) {
31748c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        closeInput(inputsToClose[i]);
31758c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
31768c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
31778c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
3178d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid AudioPolicyManager::clearAudioSources(uid_t uid)
3179d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3180d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
3181d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3182d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceDesc->mUid == uid) {
3183d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            stopAudioSource(mAudioSources.keyAt(i));
3184d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3185d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3186d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
31878c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
3188df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
3189df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                                       audio_io_handle_t *ioHandle,
3190df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                                       audio_devices_t *device)
3191df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{
3192f0c6d7d940314dbec47c9b53cb99da79eb022787Glenn Kasten    *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
3193f0c6d7d940314dbec47c9b53cb99da79eb022787Glenn Kasten    *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
3194c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
3195df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
3196df37269852ea92bafd939fe793209d0581c4a574François Gaffie    return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
3197df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent}
3198df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
3199d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
3200d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  const audio_attributes_t *attributes,
3201559d439c6fe8679e3c52f1cf265d46d7d2e65b68Glenn Kasten                                  audio_patch_handle_t *handle,
3202d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  uid_t uid)
3203554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent{
3204d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s source %p attributes %p handle %p", __FUNCTION__, source, attributes, handle);
3205d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (source == NULL || attributes == NULL || handle == NULL) {
3206d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3207d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3208d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3209559d439c6fe8679e3c52f1cf265d46d7d2e65b68Glenn Kasten    *handle = AUDIO_PATCH_HANDLE_NONE;
3210d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3211d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (source->role != AUDIO_PORT_ROLE_SOURCE ||
3212d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            source->type != AUDIO_PORT_TYPE_DEVICE) {
3213d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s INVALID_OPERATION source->role %d source->type %d", __FUNCTION__, source->role, source->type);
3214d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return INVALID_OPERATION;
3215d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3216d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3217d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> srcDeviceDesc =
3218d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mAvailableInputDevices.getDevice(source->ext.device.type,
3219d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                              String8(source->ext.device.address));
3220d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (srcDeviceDesc == 0) {
3221d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
3222d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3223d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3224d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> sourceDesc =
3225d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            new AudioSourceDescriptor(srcDeviceDesc, attributes, uid);
3226d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3227d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    struct audio_patch dummyPatch;
3228d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
3229d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sourceDesc->mPatchDesc = patchDesc;
3230d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3231d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    status_t status = connectAudioSource(sourceDesc);
3232d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (status == NO_ERROR) {
3233d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        mAudioSources.add(sourceDesc->getHandle(), sourceDesc);
3234d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        *handle = sourceDesc->getHandle();
3235d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3236d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return status;
3237d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3238d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3239d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3240d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3241d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3242d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3243d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    // make sure we only have one patch per source.
3244d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    disconnectAudioSource(sourceDesc);
3245d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3246d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
324728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
3248d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
3249d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3250d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
3251d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> sinkDeviceDesc =
3252d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mAvailableOutputDevices.getDevice(sinkDevice, String8(""));
3253d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3254d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
3255d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    struct audio_patch *patch = &sourceDesc->mPatchDesc->mPatch;
3256d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3257d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
3258d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
32599ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov            srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
3260d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
3261d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
3262d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        //   create patch between src device and output device
3263d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        //   create Hwoutput and add to mHwOutputs
3264d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    } else {
3265d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
3266d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        audio_io_handle_t output =
3267d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
3268d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (output == AUDIO_IO_HANDLE_NONE) {
3269d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
3270d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3271d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3272d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
3273d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (outputDesc->isDuplicated()) {
3274d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s output for device %08x is duplicated", __FUNCTION__, sinkDevice);
3275d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3276d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3277d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // create a special patch with no sink and two sources:
3278d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // - the second source indicates to PatchPanel through which output mix this patch should
3279d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // be connected as well as the stream type for volume control
3280d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // - the sink is defined by whatever output device is currently selected for the output
3281d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // though which this patch is routed.
3282d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->num_sinks = 0;
3283d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->num_sources = 2;
3284d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        srcDeviceDesc->toAudioPortConfig(&patch->sources[0], NULL);
3285d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        outputDesc->toAudioPortConfig(&patch->sources[1], NULL);
3286d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->sources[1].ext.mix.usecase.stream = stream;
3287d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        status_t status = mpClientInterface->createAudioPatch(patch,
3288d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              &afPatchHandle,
3289d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              0);
3290d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
3291d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              status, afPatchHandle);
3292d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (status != NO_ERROR) {
3293d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGW("%s patch panel could not connect device patch, error %d",
3294d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                  __FUNCTION__, status);
3295d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3296d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3297d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        uint32_t delayMs = 0;
3298c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
3299d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3300d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (status != NO_ERROR) {
3301d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
3302d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return status;
3303d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3304d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sourceDesc->mSwOutput = outputDesc;
3305d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (delayMs != 0) {
3306d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            usleep(delayMs * 1000);
3307d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3308d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3309d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3310d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sourceDesc->mPatchDesc->mAfPatchHandle = afPatchHandle;
3311d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    addAudioPatch(sourceDesc->mPatchDesc->mHandle, sourceDesc->mPatchDesc);
3312d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3313d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
3314554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent}
3315554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent
3316559d439c6fe8679e3c52f1cf265d46d7d2e65b68Glenn Kastenstatus_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle __unused)
3317554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent{
3318d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
3319d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, handle);
3320d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (sourceDesc == 0) {
3321d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGW("%s unknown source for handle %d", __FUNCTION__, handle);
3322d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3323d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3324d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    status_t status = disconnectAudioSource(sourceDesc);
3325d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3326d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    mAudioSources.removeItem(handle);
3327d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return status;
3328d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3329d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
33302ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hungstatus_t AudioPolicyManager::setMasterMono(bool mono)
33312ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung{
33322ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono == mono) {
33332ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        return NO_ERROR;
33342ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
33352ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mMasterMono = mono;
33362ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // if enabling mono we close all offloaded devices, which will invalidate the
33372ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // corresponding AudioTrack. The AudioTrack client/MediaPlayer is responsible
33382ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // for recreating the new AudioTrack as non-offloaded PCM.
33392ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    //
33402ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // If disabling mono, we leave all tracks as is: we don't know which clients
33412ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // and tracks are able to be recreated as offloaded. The next "song" should
33422ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // play back offloaded.
33432ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono) {
33442ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        Vector<audio_io_handle_t> offloaded;
33452ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        for (size_t i = 0; i < mOutputs.size(); ++i) {
33462ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
33472ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            if (desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
33482ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung                offloaded.push(desc->mIoHandle);
33492ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            }
33502ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        }
33512ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        for (size_t i = 0; i < offloaded.size(); ++i) {
33522ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            closeOutput(offloaded[i]);
33532ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        }
33542ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
33552ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // update master mono for all remaining outputs
33562ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    for (size_t i = 0; i < mOutputs.size(); ++i) {
33572ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        updateMono(mOutputs.keyAt(i));
33582ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
33592ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    return NO_ERROR;
33602ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung}
33612ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
33622ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hungstatus_t AudioPolicyManager::getMasterMono(bool *mono)
33632ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung{
33642ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    *mono = mMasterMono;
33652ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    return NO_ERROR;
33662ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung}
33672ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
3368d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3369d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3370d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3371d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3372d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->mPatchDesc->mHandle);
3373d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (patchDesc == 0) {
3374d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGW("%s source has no patch with handle %d", __FUNCTION__,
3375d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent              sourceDesc->mPatchDesc->mHandle);
3376d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3377d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3378d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
3379d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
338028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
3381d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
3382d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (swOutputDesc != 0) {
3383d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        stopSource(swOutputDesc, stream, false);
3384d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3385d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    } else {
3386d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->mHwOutput.promote();
3387d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (hwOutputDesc != 0) {
3388d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent          //   release patch between src device and output device
3389d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent          //   close Hwoutput and remove from mHwOutputs
3390d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        } else {
3391d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGW("%s source has neither SW nor HW output", __FUNCTION__);
3392d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3393d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3394d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
3395d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3396d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3397d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentsp<AudioSourceDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
3398d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        audio_io_handle_t output, routing_strategy strategy)
3399d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3400d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> source;
3401d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (size_t i = 0; i < mAudioSources.size(); i++)  {
3402d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3403d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        routing_strategy sourceStrategy =
3404d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
3405d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->mSwOutput.promote();
3406d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
3407d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            source = sourceDesc;
3408d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            break;
3409d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3410d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3411d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return source;
3412554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent}
3413554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent
3414e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
3415e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager
3416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
34176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentuint32_t AudioPolicyManager::nextAudioPortGeneration()
34186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
34196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return android_atomic_inc(&mAudioPortGeneration);
34206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
34216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
34220d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok#ifdef USE_XML_AUDIO_POLICY_CONF
34230d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
34240d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seokstatic const char *kConfigLocationList[] =
34250d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        {"/odm/etc", "/vendor/etc", "/system/etc"};
34260d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seokstatic const int kConfigLocationListSize =
34270d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
34280d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok
34290d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seokstatic status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
34300d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
34310d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    status_t ret;
34320d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok
34330d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    for (int i = 0; i < kConfigLocationListSize; i++) {
34340d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        PolicySerializer serializer;
34350d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        snprintf(audioPolicyXmlConfigFile,
34360d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok                 sizeof(audioPolicyXmlConfigFile),
34370d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok                 "%s/%s",
34380d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok                 kConfigLocationList[i],
34390d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok                 AUDIO_POLICY_XML_CONFIG_FILE_NAME);
34400d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
34410d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        if (ret == NO_ERROR) {
34420d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok            break;
34430d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok        }
34440d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    }
34450d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    return ret;
34460d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok}
34470d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok#endif
34480d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok
3449e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
3450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :
3451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    Thread(false),
3453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
34553a4311c68348f728558e87b5db67d47605783890Eric Laurent    mA2dpSuspended(false),
3456d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mAudioPortGeneration(1),
3457d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mBeaconMuteRefCount(0),
3458d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mBeaconPlayingRefCount(0),
34599459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    mBeaconMuted(false),
34602ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mTtsOutputAvailable(false),
346136829f97c0c547d9c6c918e248071cc616818616Eric Laurent    mMasterMono(false),
346236829f97c0c547d9c6c918e248071cc616818616Eric Laurent    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
34646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    mUidCached = getuid();
3465e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface = clientInterface;
3466e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3467d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
3468d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
3469d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Note: remove also speaker_drc_enabled from global configuration of XML config file.
3470d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    bool speakerDrcEnabled = false;
3471a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
3472f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#ifdef USE_XML_AUDIO_POLICY_CONF
3473d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves = new VolumeCurvesCollection();
3474d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3475d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                             mDefaultOutputDevice, speakerDrcEnabled,
3476d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
34770d4a6aff271586161a1fcd273572a00d2e01fe80Jaekyun Seok    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
3478f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#else
3479d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves = new StreamDescriptorCollection();
3480d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3481d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                             mDefaultOutputDevice, speakerDrcEnabled);
3482a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
3483f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
3484f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#endif
3485a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        ALOGE("could not load audio policy configuration file, setting defaults");
3486a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        config.setDefault();
3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
34882110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
3489d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
3490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3491d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
3492d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
3493d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (!engineInstance) {
3494d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
3495d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        return;
3496d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
3497d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Retrieve the Policy Manager Interface
3498d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
3499d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (mEngine == NULL) {
3500d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
3501d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        return;
3502d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
3503d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mEngine->setObserver(this);
3504d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    status_t status = mEngine->initCheck();
3505fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten    (void) status;
3506d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
3507d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
3508d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open all output streams needed to access attached devices
35103a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
35113a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
3513a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
3515a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            ALOGW("could not open HW module %s", mHwModules[i]->getName());
3516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
3517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3518e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open all output streams needed to access attached devices
3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except for direct output streams that are only opened when they are actually
3520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // required by an app.
35213a4311c68348f728558e87b5db67d47605783890Eric Laurent        // This also validates mAvailableOutputDevices list
3522e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
35241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3526a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!outProfile->hasSupportedDevices()) {
3527a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
35283a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
35293a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
3530a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
35319459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent                mTtsOutputAvailable = true;
35329459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent            }
35333a4311c68348f728558e87b5db67d47605783890Eric Laurent
3534a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
3535d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
3536d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
3537a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            audio_devices_t profileType = outProfile->getSupportedDevicesType();
353853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
353953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                profileType = mDefaultOutputDevice->type();
354083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            } else {
3541a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                // chose first device present in profile's SupportedDevices also part of
3542d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                // outputDeviceTypes
3543a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
3544d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
3545d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if ((profileType & outputDeviceTypes) == 0) {
3546d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
3547d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
3548c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
3549c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                                 mpClientInterface);
3550c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
3551c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
3552c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
3553c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                    : String8("");
3554d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3555d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            outputDesc->mDevice = profileType;
3556d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3557d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.sample_rate = outputDesc->mSamplingRate;
3558d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.channel_mask = outputDesc->mChannelMask;
3559d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.format = outputDesc->mFormat;
3560d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3561322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
3562d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &output,
3563d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &config,
3564d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &outputDesc->mDevice,
3565c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                                            address,
3566d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &outputDesc->mLatency,
3567d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            outputDesc->mFlags);
3568d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3569d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if (status != NO_ERROR) {
3570d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                ALOGW("Cannot open output stream for device %08x on hw module %s",
3571d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                      outputDesc->mDevice,
3572a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                      mHwModules[i]->getName());
3573d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            } else {
3574d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                outputDesc->mSamplingRate = config.sample_rate;
3575d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                outputDesc->mChannelMask = config.channel_mask;
3576d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                outputDesc->mFormat = config.format;
3577d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3578a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                for (size_t k = 0; k  < supportedDevices.size(); k++) {
3579a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                    ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
3580d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                    // give a valid ID to an attached device once confirmed it is reachable
3581e743a47f445f02a0612018fa5640301304844fbfPaul McLean                    if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
3582e743a47f445f02a0612018fa5640301304844fbfPaul McLean                        mAvailableOutputDevices[index]->attach(mHwModules[i]);
3583e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3585d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                if (mPrimaryOutput == 0 &&
3586a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                        outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
3587c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mPrimaryOutput = outputDesc;
3588d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                }
3589d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                addOutput(output, outputDesc);
3590c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setOutputDevice(outputDesc,
3591d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                outputDesc->mDevice,
3592c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                true,
3593c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                0,
3594c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                NULL,
3595c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                address.string());
3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
35983a4311c68348f728558e87b5db67d47605783890Eric Laurent        // open input streams needed to access attached devices to validate
35993a4311c68348f728558e87b5db67d47605783890Eric Laurent        // mAvailableInputDevices list
36003a4311c68348f728558e87b5db67d47605783890Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
36013a4311c68348f728558e87b5db67d47605783890Eric Laurent        {
36021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
36033a4311c68348f728558e87b5db67d47605783890Eric Laurent
3604a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!inProfile->hasSupportedDevices()) {
3605a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
36063a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
36073a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
3608a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            // chose first device present in profile's SupportedDevices also part of
3609d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            // inputDeviceTypes
3610a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
3611a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
3612d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if ((profileType & inputDeviceTypes) == 0) {
3613d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
3614d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
36152f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi            sp<AudioInputDescriptor> inputDesc =
36162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    new AudioInputDescriptor(inProfile);
3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3618d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            inputDesc->mDevice = profileType;
3619d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3620fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            // find the address
3621fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
3622fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            //   the inputs vector must be of size 1, but we don't want to crash here
3623fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
3624fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi                    : String8("");
3625fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            ALOGV("  for input device 0x%x using address %s", profileType, address.string());
3626fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
3627fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi
3628d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3629d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.sample_rate = inputDesc->mSamplingRate;
3630d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.channel_mask = inputDesc->mChannelMask;
3631d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.format = inputDesc->mFormat;
3632d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
3633322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
3634d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           &input,
3635d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           &config,
3636d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           &inputDesc->mDevice,
3637fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi                                                           address,
3638d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           AUDIO_SOURCE_MIC,
3639d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           AUDIO_INPUT_FLAG_NONE);
3640d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3641d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if (status == NO_ERROR) {
3642a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
3643a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                for (size_t k = 0; k  < supportedDevices.size(); k++) {
3644a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                    ssize_t index =  mAvailableInputDevices.indexOf(supportedDevices[k]);
3645d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                    // give a valid ID to an attached device once confirmed it is reachable
364645aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                    if (index >= 0) {
364745aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
364845aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        if (!devDesc->isAttached()) {
364945aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                            devDesc->attach(mHwModules[i]);
365045aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                            devDesc->importAudioPort(inProfile);
365145aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        }
36523a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
36533a4311c68348f728558e87b5db67d47605783890Eric Laurent                }
3654d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                mpClientInterface->closeInput(input);
3655d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            } else {
3656d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                ALOGW("Cannot open input stream for device %08x on hw module %s",
3657d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                      inputDesc->mDevice,
3658a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                      mHwModules[i]->getName());
36593a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
36603a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
36613a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
36623a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure all attached devices have been allocated a unique ID
36633a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
3664e743a47f445f02a0612018fa5640301304844fbfPaul McLean        if (!mAvailableOutputDevices[i]->isAttached()) {
3665a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
36663a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
36673a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
36683a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
36692110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        // The device is now validated and can be appended to the available devices of the engine
36702110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
36712110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
36723a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
36733a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
36743a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
3675e743a47f445f02a0612018fa5640301304844fbfPaul McLean        if (!mAvailableInputDevices[i]->isAttached()) {
367653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
36773a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
36783a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
36793a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
36802110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        // The device is now validated and can be appended to the available devices of the engine
36812110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
36822110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
36833a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
36843a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
36853a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure default device is reachable
3686a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
368753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
36883a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
3689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
3691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3692e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
3693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mPrimaryOutput != 0) {
3696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter outputCmd = AudioParameter();
3697e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputCmd.addInt(String8("set_id"), 0);
3698c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString());
3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
3701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestSamplingRate = 44100;
37023b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
37033b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestChannels =  AUDIO_CHANNEL_OUT_STEREO;
3704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestLatencyMs = 0;
3705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mCurOutput = 0;
3706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDirectOutput = false;
3707e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
3708e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[i] = 0;
3709e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3710e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const size_t SIZE = 256;
3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        char buffer[SIZE];
3713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        run(buffer, ANDROID_PRIORITY_AUDIO);
3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3716e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3719e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager()
3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    exit();
3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mOutputs.size(); i++) {
3725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeOutput(mOutputs.keyAt(i));
3726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mInputs.size(); i++) {
3728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeInput(mInputs.keyAt(i));
3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
37303a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableOutputDevices.clear();
37313a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableInputDevices.clear();
37321f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mOutputs.clear();
37331f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mInputs.clear();
37341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mHwModules.clear();
3735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3736e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3737e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck()
3738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
373987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3741e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3743e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop()
3744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3745e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("entering threadLoop()");
3746e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (!exitPending())
3747e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
3748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 command;
3749e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        int valueInt;
3750e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 value;
3751e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3752e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        Mutex::Autolock _l(mLock);
3753e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
3754e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3755e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
3756e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter param = AudioParameter(command);
3757e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3758e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
3759e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            valueInt != 0) {
3760e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Test command %s received", command.string());
3761e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            String8 target;
3762e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("target"), target) != NO_ERROR) {
3763e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                target = "Manager";
3764e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3765e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
3766e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_output"));
3767e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput = valueInt;
3768e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3769e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
3770e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_direct"));
3771e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "false") {
3772e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = false;
3773e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "true") {
3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = true;
3775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3777e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
3778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_input"));
3779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mTestInput = valueInt;
3780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3782e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
3783e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_format"));
37843b73df74357b33869b39a1d69427673c780bd805Eric Laurent                int format = AUDIO_FORMAT_INVALID;
3785e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "PCM 16 bits") {
37863b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_16_BIT;
3787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "PCM 8 bits") {
37883b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_8_BIT;
3789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Compressed MP3") {
37903b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_MP3;
3791e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
37923b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if (format != AUDIO_FORMAT_INVALID) {
3793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
3794e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestFormat = format;
3795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
3796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
3797388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                        outputParam.addInt(String8(AudioParameter::keyStreamSupportedFormats), format);
3798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
3803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_channels"));
3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int channels = 0;
3805e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "Channels Stereo") {
38073b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_STEREO;
3808e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Channels Mono") {
38093b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_MONO;
3810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3811e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (channels != 0) {
3812e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
3813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestChannels = channels;
3814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
3815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
3816388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                        outputParam.addInt(String8(AudioParameter::keyStreamSupportedChannels), channels);
3817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3818e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3821e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
3822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_sampleRate"));
3823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (valueInt >= 0 && valueInt <= 96000) {
3824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    int samplingRate = valueInt;
3825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
3826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestSamplingRate = samplingRate;
3827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
3828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
3829388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                        outputParam.addInt(String8(AudioParameter::keyStreamSupportedSamplingRates), samplingRate);
3830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
3836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_reopen"));
3837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3838c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                mpClientInterface->closeOutput(mpClientInterface->closeOutput(mPrimaryOutput););
3839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3840c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_module_handle_t moduleHandle = mPrimaryOutput->getModuleHandle();
3841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3842c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                removeOutput(mPrimaryOutput->mIoHandle);
3843c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                sp<SwAudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL,
3844c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                               mpClientInterface);
3845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
3846cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3847cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                config.sample_rate = outputDesc->mSamplingRate;
3848cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                config.channel_mask = outputDesc->mChannelMask;
3849cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                config.format = outputDesc->mFormat;
3850c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_io_handle_t handle;
3851cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                status_t status = mpClientInterface->openOutput(moduleHandle,
3852c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                &handle,
3853cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                &config,
3854cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                &outputDesc->mDevice,
3855cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                String8(""),
3856cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                &outputDesc->mLatency,
3857cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                outputDesc->mFlags);
3858cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                if (status != NO_ERROR) {
3859cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    ALOGE("Failed to reopen hardware output stream, "
3860cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        "samplingRate: %d, format %d, channels %d",
3861cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
3862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
3863cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    outputDesc->mSamplingRate = config.sample_rate;
3864cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    outputDesc->mChannelMask = config.channel_mask;
3865cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    outputDesc->mFormat = config.format;
3866c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mPrimaryOutput = outputDesc;
3867e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    AudioParameter outputCmd = AudioParameter();
3868e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputCmd.addInt(String8("set_id"), 0);
3869c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mpClientInterface->setParameters(handle, outputCmd.toString());
3870c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    addOutput(handle, outputDesc);
3871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
3876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3881e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit()
3882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
3884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AutoMutex _l(mLock);
3885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        requestExit();
3886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.signal();
3887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    requestExitAndWait();
3889e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3891e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
3892e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
3894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (output == mTestOutputs[i]) return i;
3895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
3897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---
3901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3902e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyManager::addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc)
3903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
390498cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie    outputDesc->setIoHandle(output);
39051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mOutputs.add(output, outputDesc);
39062ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    updateMono(output); // update mono status when adding to output list
390736829f97c0c547d9c6c918e248071cc616818616Eric Laurent    selectOutputForMusicEffects();
39086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
3909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
391153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffievoid AudioPolicyManager::removeOutput(audio_io_handle_t output)
391253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
391353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mOutputs.removeItem(output);
391436829f97c0c547d9c6c918e248071cc616818616Eric Laurent    selectOutputForMusicEffects();
391553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
391653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
3917e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyManager::addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc)
3918d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
391998cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie    inputDesc->setIoHandle(input);
39201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mInputs.add(input, inputDesc);
39216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
3922d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
3923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3924e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyManager::findIoHandlesByAddress(const sp<SwAudioOutputDescriptor>& desc /*in*/,
39253190e67d5c80c1e39e3be91784110af1180cd182keunyoung        const audio_devices_t device /*in*/,
3926e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const String8& address /*in*/,
39270fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi        SortedVector<audio_io_handle_t>& outputs /*out*/) {
39283190e67d5c80c1e39e3be91784110af1180cd182keunyoung    sp<DeviceDescriptor> devDesc =
3929a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        desc->mProfile->getSupportedDeviceByAddress(device, address);
39303190e67d5c80c1e39e3be91784110af1180cd182keunyoung    if (devDesc != 0) {
39313190e67d5c80c1e39e3be91784110af1180cd182keunyoung        ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
39323190e67d5c80c1e39e3be91784110af1180cd182keunyoung              desc->mIoHandle, address.string());
39333190e67d5c80c1e39e3be91784110af1180cd182keunyoung        outputs.add(desc->mIoHandle);
39340fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi    }
39350fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi}
39360fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi
3937e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& devDesc,
393853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   audio_policy_dev_state_t state,
393953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   SortedVector<audio_io_handle_t>& outputs,
3940e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                   const String8& address)
3941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
394253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_devices_t device = devDesc->type();
3943c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc;
3944cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
3945cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    if (audio_device_is_digital(device)) {
3946cc750d3604b33a92374253b12dd739dc06440aadEric Laurent        // erase all current sample rates, formats and channel masks
394720eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        devDesc->clearAudioProfiles();
3948cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    }
3949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
39503b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
3951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // first list already open outputs that can be routed to this device
3952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
3953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
3954c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
395553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (!device_distinguishes_on_address(device)) {
39560fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
39570fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    outputs.add(mOutputs.keyAt(i));
39580fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                } else {
39590fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("  checking address match due to device 0x%x", device);
39603190e67d5c80c1e39e3be91784110af1180cd182keunyoung                    findIoHandlesByAddress(desc, device, address, outputs);
39610fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
3962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3963e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // then look for output profiles that can be routed to this device
39651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
3966e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
3967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
3968e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
3969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
3970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
3973275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
3974a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
397553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (!device_distinguishes_on_address(device) ||
3976a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                            profile->supportDeviceAddress(address)) {
3977275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        profiles.add(profile);
3978275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
3979275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                    }
3980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
39847b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent        ALOGV("  found %zu profiles, %zu outputs", profiles.size(), outputs.size());
39850fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi
3986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty() && outputs.isEmpty()) {
3987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
3989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open outputs for matching profiles if needed. Direct outputs are also opened to
3992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
39941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
3995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // nothing to do if one output is already opened for this profile
3997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            size_t j;
39980fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            for (j = 0; j < outputs.size(); j++) {
39990fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                desc = mOutputs.valueFor(outputs.itemAt(j));
4000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (!desc->isDuplicated() && desc->mProfile == profile) {
4001f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi                    // matching profile: save the sample rates, format and channel masks supported
4002f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi                    // by the profile in our device descriptor
40039080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    if (audio_device_is_digital(device)) {
40049080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                        devDesc->importAudioPort(profile);
40059080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    }
4006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    break;
4007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
40090fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            if (j != outputs.size()) {
4010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
4011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
401383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            ALOGV("opening output for device %08x with params %s profile %p",
401483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                      device, address.string(), profile.get());
4015c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
4016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc->mDevice = device;
4017cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4018cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.sample_rate = desc->mSamplingRate;
4019cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.channel_mask = desc->mChannelMask;
4020cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.format = desc->mFormat;
4021cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.offload_info.sample_rate = desc->mSamplingRate;
4022cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.offload_info.channel_mask = desc->mChannelMask;
4023cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.offload_info.format = desc->mFormat;
4024cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4025322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openOutput(profile->getModuleHandle(),
4026cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &output,
4027cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &config,
4028cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &desc->mDevice,
4029cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            address,
4030cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &desc->mLatency,
4031cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            desc->mFlags);
4032cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
4033cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mSamplingRate = config.sample_rate;
4034cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mChannelMask = config.channel_mask;
4035cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mFormat = config.format;
4036cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
4037d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where the out_set_parameters() for card & device gets called
40383a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (!address.isEmpty()) {
4039cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    char *param = audio_device_address_to_parameter(device, address);
4040cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    mpClientInterface->setParameters(output, String8(param));
4041cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    free(param);
4042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
404300eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                updateAudioProfiles(device, output, profile->getAudioProfiles());
4044112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                if (!profile->hasValidAudioProfile()) {
40450fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGW("checkOutputsForDevice() missing param");
4046d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
4047cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    output = AUDIO_IO_HANDLE_NONE;
4048112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                } else if (profile->hasDynamicAudioProfile()) {
4049d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
4050702b105b290d9a3c8b23f3c809a79086d784c9bePhil Burk                    output = AUDIO_IO_HANDLE_NONE;
4051112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->pickAudioProfile(config.sample_rate, config.channel_mask, config.format);
4052cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.sample_rate = config.sample_rate;
4053cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.channel_mask = config.channel_mask;
4054cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.format = config.format;
4055322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent                    status = mpClientInterface->openOutput(profile->getModuleHandle(),
4056cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &output,
4057cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &config,
4058cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &desc->mDevice,
4059cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           address,
4060cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &desc->mLatency,
4061cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           desc->mFlags);
4062cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    if (status == NO_ERROR) {
4063cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        desc->mSamplingRate = config.sample_rate;
4064cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        desc->mChannelMask = config.channel_mask;
4065cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        desc->mFormat = config.format;
4066cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    } else {
4067cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        output = AUDIO_IO_HANDLE_NONE;
4068cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    }
4069d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4070d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4071cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                if (output != AUDIO_IO_HANDLE_NONE) {
4072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, desc);
407353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (device_distinguishes_on_address(device) && address != "0") {
4074036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        sp<AudioPolicyMix> policyMix;
4075036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
4076275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                            ALOGE("checkOutputsForDevice() cannot find policy for address %s",
4077275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                  address.string());
4078275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        }
4079036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        policyMix->setOutput(desc);
4080dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi                        desc->mPolicyMix = policyMix->getMix();
4081036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
408287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                    } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
408387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                                    hasPrimaryOutput()) {
4084c722f30eef03e77054395ae122470cf8dba93937Eric Laurent                        // no duplicated output for direct outputs and
4085c722f30eef03e77054395ae122470cf8dba93937Eric Laurent                        // outputs used by dynamic policy mixes
4086cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
4087d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4088d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // set initial stream volume for device
4089c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        applyStreamVolumes(desc, device, 0, true);
4090d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4091d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        //TODO: configure audio effect output stage here
4092d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4093d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // open a duplicating output thread for the new output and the primary output
4094c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        duplicatedOutput =
4095c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                mpClientInterface->openDuplicateOutput(output,
4096c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                       mPrimaryOutput->mIoHandle);
4097cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
4098d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            // add duplicated output descriptor
4099c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            sp<SwAudioOutputDescriptor> dupOutputDesc =
4100c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                    new SwAudioOutputDescriptor(NULL, mpClientInterface);
4101c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            dupOutputDesc->mOutput1 = mPrimaryOutput;
4102c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            dupOutputDesc->mOutput2 = desc;
4103d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
4104d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mFormat = desc->mFormat;
4105d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mChannelMask = desc->mChannelMask;
4106d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mLatency = desc->mLatency;
4107d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            addOutput(duplicatedOutput, dupOutputDesc);
4108c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            applyStreamVolumes(dupOutputDesc, device, 0, true);
4109d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        } else {
4110d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
4111c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                    mPrimaryOutput->mIoHandle, output);
4112d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            mpClientInterface->closeOutput(output);
411353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                            removeOutput(output);
41146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                            nextAudioPortGeneration();
4115cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                            output = AUDIO_IO_HANDLE_NONE;
4116d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        }
4117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
4118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4119cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            } else {
4120cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                output = AUDIO_IO_HANDLE_NONE;
4121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4122cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (output == AUDIO_IO_HANDLE_NONE) {
4123e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
4124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profiles.removeAt(profile_index);
4125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profile_index--;
4126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
4127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(output);
41289080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                // Load digital format info only for digital devices
41299080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                if (audio_device_is_digital(device)) {
41309080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    devDesc->importAudioPort(profile);
41319080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                }
4132f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi
413353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (device_distinguishes_on_address(device)) {
41340fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
41350fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            device, address.string());
4136c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
41370fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            NULL/*patch handle*/, address.string());
41380fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
4139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding output %d", output);
4140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4142e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4143e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty()) {
4144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
4145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
4146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4147d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else { // Disconnect
4148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // check if one opened output is not needed any more after disconnecting one device
4149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
4150e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
41510fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            if (!desc->isDuplicated()) {
4152275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                // exact match on device
415353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (device_distinguishes_on_address(device) &&
4154c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        (desc->supportedDevices() == device)) {
41553190e67d5c80c1e39e3be91784110af1180cd182keunyoung                    findIoHandlesByAddress(desc, device, address, outputs);
4156c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
41570fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
41580fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            mOutputs.keyAt(i));
41590fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    outputs.add(mOutputs.keyAt(i));
41600fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
4161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4163d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
4164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
4165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
4166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
4167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
4168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
4170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
41711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
4172a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
4173d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): "
4174d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            "clearing direct output profile %zu on module %zu", j, i);
4175112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->clearAudioProfiles();
4176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4183e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& devDesc,
418453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_policy_dev_state_t state,
418553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  SortedVector<audio_io_handle_t>& inputs,
4186e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                  const String8& address)
4187d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
41889080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean    audio_devices_t device = devDesc->type();
41891f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> desc;
4190cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
4191cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    if (audio_device_is_digital(device)) {
4192cc750d3604b33a92374253b12dd739dc06440aadEric Laurent        // erase all current sample rates, formats and channel masks
419320eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        devDesc->clearAudioProfiles();
4194cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    }
4195cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
4196d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
4197d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // first list already open inputs that can be routed to this device
4198d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4199d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
4200a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (desc->mProfile->supportDevice(device)) {
4201d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
4202d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent               inputs.add(mInputs.keyAt(input_index));
4203d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4204d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4205d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4206d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // then look for input profiles that can be routed to this device
42071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
4208d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
4209d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        {
4210d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_idx]->mHandle == 0) {
4211d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
4212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4213d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
4214d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_idx]->mInputProfiles.size();
4215d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++)
4216d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            {
4217275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
4218275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4219a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
422053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (!device_distinguishes_on_address(device) ||
4221a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                            profile->supportDeviceAddress(address)) {
4222275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        profiles.add(profile);
4223275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
4224275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                              profile_index, module_idx);
4225275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                    }
4226d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4227d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4228d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4229d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty() && inputs.isEmpty()) {
4231d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4232d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
4233d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4234d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4235d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // open inputs for matching profiles if needed. Direct inputs are also opened to
4236d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
4237d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
4238d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
42391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
4240d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // nothing to do if one input is already opened for this profile
4241d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            size_t input_index;
4242d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (input_index = 0; input_index < mInputs.size(); input_index++) {
4243d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                desc = mInputs.valueAt(input_index);
4244d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (desc->mProfile == profile) {
42459080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    if (audio_device_is_digital(device)) {
42469080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                        devDesc->importAudioPort(profile);
42479080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    }
4248d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    break;
4249d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4250d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4251d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input_index != mInputs.size()) {
4252d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
4253d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4254d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4255d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGV("opening input for device 0x%X with params %s", device, address.string());
4256d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = new AudioInputDescriptor(profile);
4257d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc->mDevice = device;
4258cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4259cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.sample_rate = desc->mSamplingRate;
4260cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.channel_mask = desc->mChannelMask;
4261cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.format = desc->mFormat;
4262cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
4263322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
4264cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &input,
4265cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &config,
4266cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &desc->mDevice,
4267cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           address,
4268cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           AUDIO_SOURCE_MIC,
4269cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           AUDIO_INPUT_FLAG_NONE /*FIXME*/);
4270d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4271cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
4272cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mSamplingRate = config.sample_rate;
4273cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mChannelMask = config.channel_mask;
4274cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mFormat = config.format;
4275d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4276d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (!address.isEmpty()) {
4277cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    char *param = audio_device_address_to_parameter(device, address);
4278cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    mpClientInterface->setParameters(input, String8(param));
4279cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    free(param);
4280d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
428100eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                updateAudioProfiles(device, input, profile->getAudioProfiles());
4282112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                if (!profile->hasValidAudioProfile()) {
4283d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkInputsForDevice() direct input missing param");
4284d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeInput(input);
4285cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    input = AUDIO_IO_HANDLE_NONE;
4286d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4287d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4288d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (input != 0) {
4289d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    addInput(input, desc);
4290d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } // endif input != 0
4292d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4293cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (input == AUDIO_IO_HANDLE_NONE) {
4294d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
4295d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profiles.removeAt(profile_index);
4296d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profile_index--;
4297d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } else {
4298d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(input);
42999080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                if (audio_device_is_digital(device)) {
43009080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    devDesc->importAudioPort(profile);
43019080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                }
4302d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding input %d", input);
4303d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4304d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } // end scan profiles
4305d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4306d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty()) {
4307d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4308d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
4309d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4310d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else {
4311d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Disconnect
4312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // check if one opened input is not needed any more after disconnecting one device
4313d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4314d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
4315a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!(desc->mProfile->supportDevice(mAvailableInputDevices.types()))) {
4316d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
4317d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                      mInputs.keyAt(input_index));
4318d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(mInputs.keyAt(input_index));
4319d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4320d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4321d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
4322d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
4323d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_index]->mHandle == 0) {
4324d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
4325d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4326d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
4327d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_index]->mInputProfiles.size();
4328d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++) {
43291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
4330a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
4331beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn                    ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
4332d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                          profile_index, module_index);
4333112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->clearAudioProfiles();
4334d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4335d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4336d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4337d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end disconnect
4338d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4339d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    return NO_ERROR;
4340d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
4341d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4342d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4343e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output)
4344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("closeOutput(%d)", output);
4346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4347c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
4348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc == NULL) {
4349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("closeOutput() unknown output %d", output);
4350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4352036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    mPolicyMixes.closeOutput(outputDesc);
4353275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // look for duplicated outputs connected to the output being removed.
4355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
4356c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
4357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dupOutputDesc->isDuplicated() &&
4358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (dupOutputDesc->mOutput1 == outputDesc ||
4359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                dupOutputDesc->mOutput2 == outputDesc)) {
43601f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent            sp<AudioOutputDescriptor> outputDesc2;
4361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dupOutputDesc->mOutput1 == outputDesc) {
4362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput2;
4363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
4364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput1;
4365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // As all active tracks on duplicated output will be deleted,
4367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and as they were also referenced on the other output, the reference
4368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // count for their stream type must be adjusted accordingly on
4369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the other output.
43703b73df74357b33869b39a1d69427673c780bd805Eric Laurent            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
4371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int refCount = dupOutputDesc->mRefCount[j];
43723b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
4373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4374e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
4375e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
4376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(duplicatedOutput);
437853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            removeOutput(duplicatedOutput);
4379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
438205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    nextAudioPortGeneration();
438305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4384ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
438505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (index >= 0) {
438605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4387fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten        (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
438805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mAudioPatches.removeItemsAt(index);
438905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
439005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
439105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
4393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.add(String8("closing"), String8("true"));
4394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->setParameters(output, param.toString());
4395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->closeOutput(output);
439753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    removeOutput(output);
4398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
439905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent}
440005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
440105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurentvoid AudioPolicyManager::closeInput(audio_io_handle_t input)
440205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent{
440305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    ALOGV("closeInput(%d)", input);
440405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
440505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
440605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (inputDesc == NULL) {
440705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        ALOGW("closeInput() unknown input %d", input);
440805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        return;
440905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
441005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
44116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
441205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
44138c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
441405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (index >= 0) {
441505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4416fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten        (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
441705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mAudioPatches.removeItemsAt(index);
441805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
441905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
442005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
442105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    mpClientInterface->closeInput(input);
442205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    mInputs.removeItem(input);
4423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4425c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
4426c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                audio_devices_t device,
4427e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                                const SwAudioOutputCollection& openOutputs)
4428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> outputs;
4430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getOutputsForDevice() device %04x", device);
4432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < openOutputs.size(); i++) {
443337ddbb43721947d6cb5246ec2cf2a6bd8fc28bcbEric Laurent        ALOGVV("output %zu isDuplicated=%d device=%04x",
44348c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                i, openOutputs.valueAt(i)->isDuplicated(),
44358c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                openOutputs.valueAt(i)->supportedDevices());
4436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
4437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
4438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputs.add(openOutputs.keyAt(i));
4439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs;
4442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4444e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
444553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                      SortedVector<audio_io_handle_t>& outputs2)
4446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs1.size() != outputs2.size()) {
4448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
4449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs1.size(); i++) {
4451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputs1[i] != outputs2[i]) {
4452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
4453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return true;
4456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4458e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
4459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
4461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
4462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
4463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
4464e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4465fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    // also take into account external policy-related changes: add all outputs which are
4466fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    // associated with policies in the "before" and "after" output vectors
4467fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    ALOGVV("checkOutputForStrategy(): policy related outputs");
4468fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
4469c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
4470fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        if (desc != 0 && desc->mPolicyMix != NULL) {
4471fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            srcOutputs.add(desc->mIoHandle);
4472fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
4473fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        }
4474fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    }
4475fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    for (size_t i = 0 ; i < mOutputs.size() ; i++) {
4476c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
4477fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        if (desc != 0 && desc->mPolicyMix != NULL) {
4478fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            dstOutputs.add(desc->mIoHandle);
4479fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            ALOGVV(" new outputs: adding %d", desc->mIoHandle);
4480fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        }
4481fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    }
4482fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi
4483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!vectorsEqual(srcOutputs,dstOutputs)) {
4484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
4485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, srcOutputs[0], dstOutputs[0]);
4486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // mute strategy while moving tracks from one output to another
4487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < srcOutputs.size(); i++) {
4488c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
4489ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if (isStrategyActive(desc, strategy)) {
4490c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute(strategy, true, desc);
4491c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
4492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4493d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            sp<AudioSourceDescriptor> source =
4494d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    getSourceForStrategyOnOutput(srcOutputs[i], strategy);
4495d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (source != 0){
4496d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                connectAudioSource(source);
4497d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
4498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move effects associated to this strategy from previous output to new output
4501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy == STRATEGY_MEDIA) {
450236829f97c0c547d9c6c918e248071cc616818616Eric Laurent            selectOutputForMusicEffects();
4503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move tracks associated to this strategy from previous output to new output
4505794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
45063b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (getStrategy((audio_stream_type_t)i) == strategy) {
45073b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mpClientInterface->invalidateStream((audio_stream_type_t)i);
4508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4513e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies()
4514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
45152110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
4516966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
4517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_PHONE);
45182110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
4519966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
4520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION);
4521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4522223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
4523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_MEDIA);
4524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_DTMF);
4525223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    checkOutputForStrategy(STRATEGY_REROUTING);
4526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4528e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend()
4529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
453053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
4531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (a2dpOutput == 0) {
45323a4311c68348f728558e87b5db67d47605783890Eric Laurent        mA2dpSuspended = false;
4533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
45363a4311c68348f728558e87b5db67d47605783890Eric Laurent    bool isScoConnected =
4537ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent            ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET &
4538ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent                    ~AUDIO_DEVICE_BIT_IN) != 0) ||
4539ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent            ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);
4540f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent
4541f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    // if suspended, restore A2DP output if:
4542f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //      ((SCO device is NOT connected) ||
4543f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //       ((forced usage communication is NOT SCO) && (forced usage for record is NOT SCO) &&
4544f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //        (phone state is NOT in call) && (phone state is NOT ringing)))
4545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
4546f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    // if not suspended, suspend A2DP output if:
4547f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //      (SCO device is connected) &&
4548f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //       ((forced usage for communication is SCO) || (forced usage for record is SCO) ||
4549f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent    //       ((phone state is in call) || (phone state is ringing)))
4550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
4551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mA2dpSuspended) {
4552f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent        if (!isScoConnected ||
4553f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent             ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) !=
4554f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                     AUDIO_POLICY_FORCE_BT_SCO) &&
4555f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) !=
4556f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                      AUDIO_POLICY_FORCE_BT_SCO) &&
4557f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
45582110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
4559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->restoreOutput(a2dpOutput);
4561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = false;
4562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
4564f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent        if (isScoConnected &&
4565f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent             ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ==
4566f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                     AUDIO_POLICY_FORCE_BT_SCO) ||
4567f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) ==
4568f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent                      AUDIO_POLICY_FORCE_BT_SCO) ||
4569f732e0726c5e0c4a1460e2dfa8c39e7a9a697ae9Eric Laurent              (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
45702110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
4571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->suspendOutput(a2dpOutput);
4573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = true;
4574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4578c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
4579c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                       bool fromCache)
4580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
4582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4583ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
45846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
45856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
45866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached) {
45876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("getNewOutputDevice() device %08x forced by patch %d",
4588ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                  outputDesc->device(), outputDesc->getPatchHandle());
45896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return outputDesc->device();
45906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
45916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
45926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
4593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check the following by order of priority to request a routing change if necessary:
4594966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    // 1: the strategy enforced audible is active and enforced on the output:
4595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy enforced audible
4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: we are in call or the strategy phone is active on the output:
4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy phone
4598966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    // 3: the strategy for enforced audible is active but not enforced on the output:
4599966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    //      use the device for strategy enforced audible
460028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // 4: the strategy sonification is active on the output:
4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy sonification
460228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // 5: the strategy accessibility is active on the output:
460328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    //      use device for strategy accessibility
46045de234b29141334c1bb5e40bc19c11836848841bJean-Michel Trivi    // 6: the strategy "respectful" sonification is active on the output:
4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy "respectful" sonification
4606223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 7: the strategy media is active on the output:
4607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy media
4608223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 8: the strategy DTMF is active on the output:
4609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy DTMF
4610223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
4611d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    //      use device for strategy t-t-s
4612ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
46132110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
4614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
4615e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isInCall() ||
4616ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                    isStrategyActive(outputDesc, STRATEGY_PHONE)) {
4617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
4618ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
4619966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
4620ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
4621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
462228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
462328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
4624ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
4625e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
4626ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
4627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
4628ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
4629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
4630ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
4631d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
4632ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
4633223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
4634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
46361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("getNewOutputDevice() selected device %x", device);
46371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return device;
46381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
46391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4640fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc)
46411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
4642fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
46436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
46448c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
46456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
46466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
46476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached) {
46486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("getNewInputDevice() device %08x forced by patch %d",
46498c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                  inputDesc->mDevice, inputDesc->getPatchHandle());
46506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return inputDesc->mDevice;
46516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
46526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
46536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
4654fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    audio_source_t source = inputDesc->getHighestPrioritySource(true /*activeOnly*/);
4655fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (isInCall()) {
4656fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        device = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
4657fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    } else if (source != AUDIO_SOURCE_DEFAULT) {
4658fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        device = getDeviceAndMixForInputSource(source);
4659fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
46601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
4662e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4664794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurentbool AudioPolicyManager::streamsMatchForvolume(audio_stream_type_t stream1,
4665794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent                                               audio_stream_type_t stream2) {
466699bb2f9afd956174785051827aa96d008b33faeeJean-Michel Trivi    return (stream1 == stream2);
466728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent}
466828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent
4669e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (uint32_t)getStrategy(stream);
4671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4673e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
4674e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // By checking the range of stream before calling getStrategy, we avoid
4675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
4676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and then return STRATEGY_MEDIA, but we want to return the empty set.
4677223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
46786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return AUDIO_DEVICE_NONE;
46796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
468028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_devices_t devices = AUDIO_DEVICE_NONE;
4681794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
4682794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
468328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
468428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
4685794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
468628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        audio_devices_t curDevices =
4687447a87bbfe11cc85123ddd94551c3a5ede54ea20Eric Laurent                getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
468828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs);
468928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        for (size_t i = 0; i < outputs.size(); i++) {
469028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
4691794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
469228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                curDevices |= outputDesc->device();
469328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            }
46946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
469528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        devices |= curDevices;
4696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
469711c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund
469811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
469911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund      and doesn't really need to.*/
470011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
470111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund        devices |= AUDIO_DEVICE_OUT_SPEAKER;
470211c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund        devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
470311c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    }
4704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return devices;
4705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4706e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
47072110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffierouting_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
47082110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
4709223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
47102110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getStrategyForStream(stream);
4711e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
47135bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviuint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
47145bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // flags to strategy mapping
4715d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4716d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
4717d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
47185bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
47195bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
47205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
47215bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // usage to strategy mapping
47222110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
47235bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
47245bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
4725e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
4726e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(stream) {
47273b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
4728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
4730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
4732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4734e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4736d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::handleEventForBeacon(int event) {
47379459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
47389459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    // skip beacon mute management if a dedicated TTS output is available
47399459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    if (mTtsOutputAvailable) {
47409459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent        return 0;
47419459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    }
47429459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
4743d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    switch(event) {
4744d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STARTING_OUTPUT:
4745d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconMuteRefCount++;
4746d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4747d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STOPPING_OUTPUT:
4748d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        if (mBeaconMuteRefCount > 0) {
4749d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mBeaconMuteRefCount--;
4750d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
4751d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4752d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STARTING_BEACON:
4753d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconPlayingRefCount++;
4754d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4755d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STOPPING_BEACON:
4756d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        if (mBeaconPlayingRefCount > 0) {
4757d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mBeaconPlayingRefCount--;
4758d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
4759d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4760d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
4761d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
4762d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (mBeaconMuteRefCount > 0) {
4763d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // any playback causes beacon to be muted
4764d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return setBeaconMute(true);
4765d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    } else {
4766d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // no other playback: unmute when beacon starts playing, mute when it stops
4767d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return setBeaconMute(mBeaconPlayingRefCount == 0);
4768d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
4769d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}
4770d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
4771d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::setBeaconMute(bool mute) {
4772d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d",
4773d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mute, mBeaconMuteRefCount, mBeaconPlayingRefCount);
4774d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // keep track of muted state to avoid repeating mute/unmute operations
4775d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (mBeaconMuted != mute) {
4776d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // mute/unmute AUDIO_STREAM_TTS on all outputs
4777d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        ALOGV("\t muting %d", mute);
4778d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        uint32_t maxLatency = 0;
4779d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        for (size_t i = 0; i < mOutputs.size(); i++) {
4780c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
4781d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
4782c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    desc,
4783d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                    0 /*delay*/, AUDIO_DEVICE_NONE);
4784d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            const uint32_t latency = desc->latency() * 2;
4785d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            if (latency > maxLatency) {
4786d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                maxLatency = latency;
4787d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            }
4788d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
4789d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconMuted = mute;
4790d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return maxLatency;
4791d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
4792d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    return 0;
4793d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}
4794d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
4795e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
479653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                         bool fromCache)
4797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4798aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // Routing
4799aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // see if we have an explicit route
4800aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // scan the whole RouteMap, for each entry, convert the stream type to a strategy
4801aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // (getStrategy(stream)).
4802aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // if the strategy from the stream type in the RouteMap is the same as the argument above,
4803aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // and activity count is non-zero
4804aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // the device = the device from the descriptor in the RouteMap, and exit.
4805aa9811945f575614b3482d09e4d969792701cebbPaul McLean    for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
4806aa9811945f575614b3482d09e4d969792701cebbPaul McLean        sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
480728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        routing_strategy routeStrategy = getStrategy(route->mStreamType);
480828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        if ((routeStrategy == strategy) && route->isActive()) {
4809aa9811945f575614b3482d09e4d969792701cebbPaul McLean            return route->mDeviceDescriptor->type();
4810aa9811945f575614b3482d09e4d969792701cebbPaul McLean        }
4811aa9811945f575614b3482d09e4d969792701cebbPaul McLean    }
4812aa9811945f575614b3482d09e4d969792701cebbPaul McLean
4813e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (fromCache) {
4814e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
4815e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, mDeviceForStrategy[strategy]);
4816e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDeviceForStrategy[strategy];
4817e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
48182110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getDeviceForStrategy(strategy);
4819e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4820e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4821e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs()
4822e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4823e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
4824e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4825e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4826e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
4827e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4828e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4829e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehuint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
4830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       audio_devices_t prevDevice,
4831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       uint32_t delayMs)
4832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute/unmute strategies using an incompatible device combination
4834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if muting, wait for the audio in pcm buffer to be drained before proceeding
4835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if unmuting, unmute only after the specified delay
4836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
4837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
4838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs = 0;
4841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = outputDesc->device();
48423b73df74357b33869b39a1d69427673c780bd805Eric Laurent    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
4843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4844e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4846c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        curDevice = curDevice & outputDesc->supportedDevices();
4847e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
4848e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool doMute = false;
4849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
4851e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
4852e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = true;
4853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
4854e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
4855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = false;
4856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
485799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        if (doMute) {
4858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mOutputs.size(); j++) {
48591f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
4860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // skip output if it does not share any device with current output
4861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((desc->supportedDevices() & outputDesc->supportedDevices())
4862e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        == AUDIO_DEVICE_NONE) {
4863e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    continue;
4864e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
486537ddbb43721947d6cb5246ec2cf2a6bd8fc28bcbEric Laurent                ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
4866c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                      mute ? "muting" : "unmuting", i, curDevice);
4867c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
4868ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                if (isStrategyActive(desc, (routing_strategy)i)) {
486999401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                    if (mute) {
487099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // FIXME: should not need to double latency if volume could be applied
487199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // immediately by the audioflinger mixer. We must account for the delay
487299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // between now and the next time the audioflinger thread for this output
487399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // will process a buffer (which corresponds to one buffer size,
487499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // usually 1/2 or 1/4 of the latency).
487599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        if (muteWaitMs < desc->latency() * 2) {
487699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                            muteWaitMs = desc->latency() * 2;
4877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        }
4878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
4879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
488499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // temporary mute output if device selection changes to avoid volume bursts due to
488599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // different per device volumes
488699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    if (outputDesc->isActive() && (device != prevDevice)) {
4887dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
4888dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        // temporary mute duration is conservatively set to 4 times the reported latency
4889dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
4890dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        if (muteWaitMs < tempMuteWaitMs) {
4891dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            muteWaitMs = tempMuteWaitMs;
489299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
4893dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
489499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4895ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if (isStrategyActive(outputDesc, (routing_strategy)i)) {
4896dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // make sure that we do not start the temporary mute period too early in case of
4897dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // delayed device change
4898dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
4899c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute((routing_strategy)i, false, outputDesc,
4900dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                                delayMs + tempMuteDurationMs, device);
490199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent            }
490299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
490399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    }
490499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent
4905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // wait for the PCM output buffers to empty before proceeding with the rest of the command
4906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (muteWaitMs > delayMs) {
4907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs -= delayMs;
4908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        usleep(muteWaitMs * 1000);
4909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
4910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
4912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4914c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
4915e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device,
4916e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool force,
49176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                             int delayMs,
49180fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                                             audio_patch_handle_t *patchHandle,
49190fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                                             const char* address)
4920e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4921c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
4922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
4923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs;
4924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
4926c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs);
4927c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs);
4928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
4929e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4930e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
4931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // output profile
4932c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if ((device != AUDIO_DEVICE_NONE) &&
4933c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            ((device & outputDesc->supportedDevices()) == 0)) {
4934e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
4935e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4936e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4937e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // filter devices according to output selected
4938c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    device = (audio_devices_t)(device & outputDesc->supportedDevices());
4939e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4940e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t prevDevice = outputDesc->mDevice;
4941e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4942aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
4943e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device != AUDIO_DEVICE_NONE) {
4945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
4946e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
4948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not change the routing if:
4950b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //      the requested device is AUDIO_DEVICE_NONE
4951b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //      OR the requested device is the same as current device
4952b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //  AND force is not specified
4953b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //  AND the output is connected by a valid audio patch.
4954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Doing this check here allows the caller to call setOutputDevice() without conditions
4955aa9811945f575614b3482d09e4d969792701cebbPaul McLean    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
4956aa9811945f575614b3482d09e4d969792701cebbPaul McLean        !force &&
4957ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi        outputDesc->getPatchHandle() != 0) {
4958c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
4959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
4960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4961e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() changing device");
49631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do the routing
49651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (device == AUDIO_DEVICE_NONE) {
4966c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        resetOutputDevice(outputDesc, delayMs, NULL);
49671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    } else {
4968c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        DeviceVector deviceList;
4969c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        if ((address == NULL) || (strlen(address) == 0)) {
4970c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            deviceList = mAvailableOutputDevices.getDevicesFromType(device);
4971c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        } else {
4972c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            deviceList = mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
4973c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        }
4974c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent
49751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
49761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
49771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            outputDesc->toAudioPortConfig(&patch.sources[0]);
49781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
49791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 0;
49801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
49811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
49821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                patch.num_sinks++;
49831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
49846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ssize_t index;
49856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
49866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                index = mAudioPatches.indexOfKey(*patchHandle);
49876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
4988ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
49896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
49906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp< AudioPatch> patchDesc;
49916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
49926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
49936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
49946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
49956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
49966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
49971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
49986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                   &afPatchHandle,
49996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                   delayMs);
50001c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
50011c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                    "num_sources %d num_sinks %d",
50026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                       status, afPatchHandle, patch.num_sources, patch.num_sinks);
50031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
50046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
500598cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&patch, mUidCached);
50066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
50076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
50086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = patch;
50096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
50106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
50116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchHandle) {
50126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    *patchHandle = patchDesc->mHandle;
50136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
5014ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                outputDesc->setPatchHandle(patchDesc->mHandle);
50156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
5016b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
50171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
50181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
5019f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu
5020f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        // inform all input as well
5021f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        for (size_t i = 0; i < mInputs.size(); i++) {
5022f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu            const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
502353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!is_virtual_input_device(inputDescriptor->mDevice)) {
5024f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                AudioParameter inputCmd = AudioParameter();
5025f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                ALOGV("%s: inform input %d of device:%d", __func__,
5026f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                      inputDescriptor->mIoHandle, device);
5027f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                inputCmd.addInt(String8(AudioParameter::keyRouting),device);
5028f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                mpClientInterface->setParameters(inputDescriptor->mIoHandle,
5029f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                                                 inputCmd.toString(),
5030f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                                                 delayMs);
5031f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu            }
5032f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        }
50331c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
5034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // update stream volumes according to new device
5036c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    applyStreamVolumes(outputDesc, device, delayMs);
5037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return muteWaitMs;
5039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5041c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t AudioPolicyManager::resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
50426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               int delayMs,
50436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               audio_patch_handle_t *patchHandle)
50441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
50456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index;
50466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchHandle) {
50476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*patchHandle);
50486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
5049ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi        index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
50506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
50516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
50521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
50531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
50546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
50556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
50561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
5057a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
50586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    removeAudioPatch(patchDesc->mHandle);
50596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
5060b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPatchListUpdate();
50611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
50621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
50631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
50641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
50651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                            audio_devices_t device,
50666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            bool force,
50676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            audio_patch_handle_t *patchHandle)
50681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
50691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    status_t status = NO_ERROR;
50701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
50711f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
50721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
50731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        inputDesc->mDevice = device;
50741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
50751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
50761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
50771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
50781c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            inputDesc->toAudioPortConfig(&patch.sinks[0]);
5079daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            // AUDIO_SOURCE_HOTWORD is for internal use only:
5080daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
5081df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
5082599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    !inputDesc->isSoundTrigger()) {
5083daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent                patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
5084daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            }
50851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 1;
50861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            //only one input device for now
50871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
50881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
50896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ssize_t index;
50906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
50916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                index = mAudioPatches.indexOfKey(*patchHandle);
50926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
50938c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
50946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
50956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp< AudioPatch> patchDesc;
50966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
50976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
50986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
50996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
51006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
51016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
51021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
51036a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  &afPatchHandle,
51041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  0);
51051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
51066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                          status, afPatchHandle);
51071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
51086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
510998cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&patch, mUidCached);
51106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
51116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
51126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = patch;
51136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
51146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
51156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchHandle) {
51166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    *patchHandle = patchDesc->mHandle;
51176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
51188c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                inputDesc->setPatchHandle(patchDesc->mHandle);
51196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
5120b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
51211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
51221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
51231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
51241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
51251c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
51261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
51276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
51286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              audio_patch_handle_t *patchHandle)
51291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
51301f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
51316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index;
51326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchHandle) {
51336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*patchHandle);
51346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
51358c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
51366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
51376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
51381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
51391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
51406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
51416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
51421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
5143a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    inputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
51446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    removeAudioPatch(patchDesc->mHandle);
51456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
5146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPatchListUpdate();
51471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
51481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
51491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
515056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
5151e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh                                                  const String8& address,
515253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  uint32_t& samplingRate,
5153f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                  audio_format_t& format,
5154f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                  audio_channel_mask_t& channelMask,
515553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_input_flags_t flags)
5156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Choose an input profile based on the requested capture parameters: select the first available
5158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // profile supporting all requested parameters.
5159f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    //
5160f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
5161f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // the best matching profile, not the first one.
5162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++)
5164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
5165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
5166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
5167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
5169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
51701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
5171d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // profile->log();
5172275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            if (profile->isCompatibleProfile(device, address, samplingRate,
5173cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten                                             &samplingRate /*updatedSamplingRate*/,
5174f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             format,
5175f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             &format /*updatedFormat*/,
5176f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             channelMask,
5177f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             &channelMask /*updatedChannelMask*/,
5178f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             (audio_output_flags_t) flags)) {
5179275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
5180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return profile;
5181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NULL;
5185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5187c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
5188c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
518953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                                  AudioMix **policyMix)
5190e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5191036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
5192036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    audio_devices_t selectedDeviceFromMix =
5193036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie           mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
5194275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
5195036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
5196036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        return selectedDeviceFromMix;
5197275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
5198c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    return getDeviceForInputSource(inputSource);
5199c73ca6ef04136f28306784ad35f444538f081957Eric Laurent}
5200c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
5201c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
5202c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{
5203466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
5204466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean         sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
52058c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent         if (inputSource == route->mSource && route->isActive()) {
5206466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean             return route->mDeviceDescriptor->type();
5207466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean         }
5208466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean     }
5209466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
5210466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean     return mEngine->getDeviceForInputSource(inputSource);
5211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5213e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream,
5214d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                        int index,
5215d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                        audio_devices_t device)
5216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
521700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi    float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
52183d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi
52193d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // handle the case of accessibility active while a ringtone is playing: if the ringtone is much
52203d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
52213d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
52223d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // the ringtone volume
52233d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    if ((stream == AUDIO_STREAM_ACCESSIBILITY)
52243d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState())
52253d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi            && isStreamActive(AUDIO_STREAM_RING, 0)) {
52263d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi        const float ringVolumeDB = computeVolume(AUDIO_STREAM_RING, index, device);
52273d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi        return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
52283d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    }
52293d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi
5230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if a headset is connected, apply the following rules to ring tones and notifications
5231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // to avoid sound level bursts in user's ears:
52326af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // - always attenuate notifications volume by 6dB
52336af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // - attenuate ring tones volume by 6dB unless music is not playing and
52346af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // speaker is part of the select devices
5235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - if music is playing, always limit the volume to current music volume,
5236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // with a minimum threshold at -36dB so that notification is always perceived.
52373b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
5238e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
5239e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
5240e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADSET |
5241904d632a24db8f94de83e44f7179d1c0af022b03Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
5242904d632a24db8f94de83e44f7179d1c0af022b03Eric Laurent            AUDIO_DEVICE_OUT_USB_HEADSET)) &&
5243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ((stream_strategy == STRATEGY_SONIFICATION)
5244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
52453b73df74357b33869b39a1d69427673c780bd805Eric Laurent                || (stream == AUDIO_STREAM_SYSTEM)
5246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
52472110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                    (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
5248d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            mVolumeCurves->canBeMuted(stream)) {
5249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when the phone is ringing we must consider that music could have been paused just before
5250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by the music application and behave as if music was active if the last music track was
5251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // just stopped
52523b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
5253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mLimitRingtoneVolume) {
525400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
5255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
5256ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent            float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
5257d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                             mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
5258d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                                                              musicDevice),
5259d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                             musicDevice);
5260ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent            float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
5261ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                    musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
526200a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            if (volumeDB > minVolDB) {
526300a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                volumeDB = minVolDB;
5264ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
5265e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
526600a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
526700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
526800a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                // on A2DP, also ensure notification volume is not too low compared to media when
526900a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                // intended to be played
527000a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                if ((volumeDB > -96.0f) &&
527100a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                        (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDB)) {
527200a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
527300a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                            stream, device,
527400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                            volumeDB, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
527500a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    volumeDB = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
527600a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                }
527700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            }
52786af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent        } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
52796af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent                stream_strategy != STRATEGY_SONIFICATION) {
528000a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
5281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5283e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
528400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi    return volumeDB;
5285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5286e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5287e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
5288c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   int index,
5289c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   const sp<AudioOutputDescriptor>& outputDesc,
5290c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   audio_devices_t device,
5291c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   int delayMs,
5292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   bool force)
5293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change actual stream volume if the stream is muted
5295c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mMuteCount[stream] != 0) {
5296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() stream %d muted count %d",
5297c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent              stream, outputDesc->mMuteCount[stream]);
5298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
5299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
53002110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    audio_policy_forced_cfg_t forceUseForComm =
53012110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
5302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change in call volume if bluetooth is connected and vice versa
53032110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
53042110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
5305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
53062110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             stream, forceUseForComm);
5307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
5308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5310c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
5311c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        device = outputDesc->device();
5312275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
5313c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
5314ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent    float volumeDb = computeVolume(stream, index, device);
5315c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->isFixedVolume(device)) {
5316ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent        volumeDb = 0.0f;
5317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5319ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent    outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
5320c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
53213b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_VOICE_CALL ||
53223b73df74357b33869b39a1d69427673c780bd805Eric Laurent        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
5323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        float voiceVolume;
5324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
53253b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_VOICE_CALL) {
5326d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);
5327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
5328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = 1.0;
5329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
533118fba84019d778b3c20875d93f9f36c2410ecf33Eric Laurent        if (voiceVolume != mLastVoiceVolume) {
5332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
5333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mLastVoiceVolume = voiceVolume;
5334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
5338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5340c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
5341c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                audio_devices_t device,
5342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                int delayMs,
5343c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                bool force)
5344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5345c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGVV("applyStreamVolumes() for device %08x", device);
5346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5347794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
53483b73df74357b33869b39a1d69427673c780bd805Eric Laurent        checkAndSetVolume((audio_stream_type_t)stream,
5349d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                          mVolumeCurves->getVolumeIndex((audio_stream_type_t)stream, device),
5350c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          outputDesc,
5351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          device,
5352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          delayMs,
5353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          force);
5354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5357e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy,
5358c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             bool on,
5359c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             const sp<AudioOutputDescriptor>& outputDesc,
5360c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             int delayMs,
5361c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_devices_t device)
5362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
536372249d5b2f9f42a96c0e0825431e8f3f49b82644Eric Laurent    ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
536472249d5b2f9f42a96c0e0825431e8f3f49b82644Eric Laurent           strategy, on, outputDesc->getId());
5365794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
53663b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (getStrategy((audio_stream_type_t)stream) == strategy) {
5367c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
5368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5372e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
5373c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           bool on,
5374c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           const sp<AudioOutputDescriptor>& outputDesc,
5375c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           int delayMs,
5376c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           audio_devices_t device)
5377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
5379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
5380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5382c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
5383c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent          stream, on, outputDesc->mMuteCount[stream], device);
5384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (on) {
5386e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
5387d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            if (mVolumeCurves->canBeMuted(stream) &&
53883b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
53892110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
5390c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
5391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
5394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mMuteCount[stream]++;
5395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
5396e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
5397e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setStreamMute() unmuting non muted stream!");
5398e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
5399e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--outputDesc->mMuteCount[stream] == 0) {
5401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            checkAndSetVolume(stream,
5402d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                              mVolumeCurves->getVolumeIndex(stream, device),
5403c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                              outputDesc,
5404e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              device,
5405e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              delayMs);
5406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5407e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5408e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5409e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5410e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
54113b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                      bool starting, bool stateChange)
5412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
541387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if(!hasPrimaryOutput()) {
541487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        return;
541587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    }
541687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent
5417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if the stream pertains to sonification strategy and we are in call we must
5418e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
5419e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the device used for phone strategy and play the tone if the selected device does not
5420e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // interfere with the device used for phone strategy
5421e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
5422e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // many times as there are active tracks on the output
54233b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
5424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((stream_strategy == STRATEGY_SONIFICATION) ||
5425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
5426c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
5427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
5428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stream, starting, outputDesc->mDevice, stateChange);
5429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream]) {
5430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            int muteCount = 1;
5431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (stateChange) {
5432e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                muteCount = outputDesc->mRefCount[stream];
5433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
54343b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (audio_is_low_visibility(stream)) {
5435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
5436e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                for (int i = 0; i < muteCount; i++) {
5437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setStreamMute(stream, starting, mPrimaryOutput);
5438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
5440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() high visibility");
5441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->device() &
5442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
5443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
5444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    for (int i = 0; i < muteCount; i++) {
5445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStreamMute(stream, starting, mPrimaryOutput);
5446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
5447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (starting) {
54493b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
54503b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                 AUDIO_STREAM_VOICE_CALL);
5451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
5452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->stopTone();
5453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
54595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
54605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{
54615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // flags to stream type mapping
54625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
54635bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_ENFORCED_AUDIBLE;
54645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
54655bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
54665bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_BLUETOOTH_SCO;
54675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
546879ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
546979ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi        return AUDIO_STREAM_TTS;
547079ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi    }
54715bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
54725bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // usage to stream type mapping
54735bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    switch (attr->usage) {
54745bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_MEDIA:
54755bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_GAME:
547636867767ba86244b0d942255b9d241b092151309Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANT:
54775bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
54785bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_MUSIC;
5479223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5480223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        return AUDIO_STREAM_ACCESSIBILITY;
54815bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
54825bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_SYSTEM;
54835bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_VOICE_COMMUNICATION:
54845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_VOICE_CALL;
54855bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
54865bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
54875bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_DTMF;
54885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
54895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ALARM:
54905bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_ALARM;
54915bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
54925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_RING;
54935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
54945bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION:
54955bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
54965bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
54975bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
54985bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_EVENT:
54995bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_NOTIFICATION;
55005bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
55015bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_UNKNOWN:
55025bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    default:
55035bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_MUSIC;
55045bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
55055bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
5506e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
550753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiebool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
550853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
5509e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // has flags that map to a strategy?
5510e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
5511e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return true;
5512e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
5513e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
5514e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // has known usage?
5515e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    switch (paa->usage) {
5516e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_UNKNOWN:
5517e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_MEDIA:
5518e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_VOICE_COMMUNICATION:
5519e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
5520e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ALARM:
5521e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION:
5522e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
5523e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
5524e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
5525e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
5526e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_EVENT:
5527e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5528e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
5529e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
5530e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_GAME:
5531275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    case AUDIO_USAGE_VIRTUAL_SOURCE:
553236867767ba86244b0d942255b9d241b092151309Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANT:
5533e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        break;
5534e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    default:
5535e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return false;
5536e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
5537e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return true;
5538e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
5539e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
5540e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehbool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc,
5541ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                          routing_strategy strategy, uint32_t inPastMs,
5542ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                          nsecs_t sysTime) const
5543ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie{
5544ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if ((sysTime == 0) && (inPastMs != 0)) {
5545ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        sysTime = systemTime();
5546ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    }
5547794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
5548ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
5549ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                (NUM_STRATEGIES == strategy)) &&
5550ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
5551ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            return true;
5552ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        }
5553ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    }
5554ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    return false;
5555ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie}
5556ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie
55572110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffieaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
55582110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
55592110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getForceUse(usage);
55602110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
55612110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
55622110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffiebool AudioPolicyManager::isInCall()
55632110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
55642110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return isStateInCall(mEngine->getPhoneState());
55652110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
55662110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
55672110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffiebool AudioPolicyManager::isStateInCall(int state)
55682110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
55692110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return is_state_in_call(state);
55702110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
55712110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
5572d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc)
5573d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
5574d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
5575d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
5576d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceDesc->mDevice->equals(deviceDesc)) {
5577d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->getHandle());
5578d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            stopAudioSource(sourceDesc->getHandle());
5579d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5580d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
5581d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
5582d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {
5583d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
5584d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        bool release = false;
5585d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t j = 0; j < patchDesc->mPatch.num_sources && !release; j++)  {
5586d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const struct audio_port_config *source = &patchDesc->mPatch.sources[j];
5587d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (source->type == AUDIO_PORT_TYPE_DEVICE &&
5588d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    source->ext.device.type == deviceDesc->type()) {
5589d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                release = true;
5590d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
5591d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5592d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t j = 0; j < patchDesc->mPatch.num_sinks && !release; j++)  {
5593d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const struct audio_port_config *sink = &patchDesc->mPatch.sinks[j];
5594d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
5595d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    sink->ext.device.type == deviceDesc->type()) {
5596d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                release = true;
5597d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
5598d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5599d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (release) {
5600d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s releasing patch %u", __FUNCTION__, patchDesc->mHandle);
5601d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            releaseAudioPatch(patchDesc->mHandle, patchDesc->mUid);
5602d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5603d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
5604d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
5605d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
560609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk// Modify the list of surround sound formats supported.
56070709b0aba2adb719d347341ff58441347a1c1582Phil Burkvoid AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
56080709b0aba2adb719d347341ff58441347a1c1582Phil Burk    FormatVector &formats = *formatsPtr;
560907ac114c3965e16fe523f88c913e701602604589Phil Burk    // TODO Set this based on Config properties.
561007ac114c3965e16fe523f88c913e701602604589Phil Burk    const bool alwaysForceAC3 = true;
561109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
561209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
561309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
56140709b0aba2adb719d347341ff58441347a1c1582Phil Burk    ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
561509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
561609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    // Analyze original support for various formats.
561707ac114c3965e16fe523f88c913e701602604589Phil Burk    bool supportsAC3 = false;
561807ac114c3965e16fe523f88c913e701602604589Phil Burk    bool supportsOtherSurround = false;
561909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    bool supportsIEC61937 = false;
562009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
562109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        audio_format_t format = formats[formatIndex];
562209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        switch (format) {
562309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_AC3:
562407ac114c3965e16fe523f88c913e701602604589Phil Burk                supportsAC3 = true;
562507ac114c3965e16fe523f88c913e701602604589Phil Burk                break;
562609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_E_AC3:
562709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_DTS:
562809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_DTS_HD:
562907ac114c3965e16fe523f88c913e701602604589Phil Burk                supportsOtherSurround = true;
563009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                break;
563109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_IEC61937:
563209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                supportsIEC61937 = true;
563309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                break;
563409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            default:
563509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                break;
563609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        }
563709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
563809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
563909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    // Modify formats based on surround preferences.
564009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    // If NEVER, remove support for surround formats.
564107ac114c3965e16fe523f88c913e701602604589Phil Burk    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
564207ac114c3965e16fe523f88c913e701602604589Phil Burk        if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
564307ac114c3965e16fe523f88c913e701602604589Phil Burk            // Remove surround sound related formats.
564407ac114c3965e16fe523f88c913e701602604589Phil Burk            for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
564507ac114c3965e16fe523f88c913e701602604589Phil Burk                audio_format_t format = formats[formatIndex];
564607ac114c3965e16fe523f88c913e701602604589Phil Burk                switch(format) {
564707ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_AC3:
564807ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_E_AC3:
564907ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_DTS:
565007ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_DTS_HD:
565107ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_IEC61937:
565207ac114c3965e16fe523f88c913e701602604589Phil Burk                        formats.removeAt(formatIndex);
565307ac114c3965e16fe523f88c913e701602604589Phil Burk                        break;
565407ac114c3965e16fe523f88c913e701602604589Phil Burk                    default:
565507ac114c3965e16fe523f88c913e701602604589Phil Burk                        formatIndex++; // keep it
565607ac114c3965e16fe523f88c913e701602604589Phil Burk                        break;
565707ac114c3965e16fe523f88c913e701602604589Phil Burk                }
565809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            }
565907ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsAC3 = false;
566007ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsOtherSurround = false;
566107ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsIEC61937 = false;
566207ac114c3965e16fe523f88c913e701602604589Phil Burk        }
566307ac114c3965e16fe523f88c913e701602604589Phil Burk    } else { // AUTO or ALWAYS
566407ac114c3965e16fe523f88c913e701602604589Phil Burk        // Most TVs support AC3 even if they do not report it in the EDID.
566507ac114c3965e16fe523f88c913e701602604589Phil Burk        if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
566607ac114c3965e16fe523f88c913e701602604589Phil Burk                && !supportsAC3) {
566707ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_AC3);
566807ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsAC3 = true;
566907ac114c3965e16fe523f88c913e701602604589Phil Burk        }
567007ac114c3965e16fe523f88c913e701602604589Phil Burk
567107ac114c3965e16fe523f88c913e701602604589Phil Burk        // If ALWAYS, add support for raw surround formats if all are missing.
567207ac114c3965e16fe523f88c913e701602604589Phil Burk        // This assumes that if any of these formats are reported by the HAL
567307ac114c3965e16fe523f88c913e701602604589Phil Burk        // then the report is valid and should not be modified.
567407ac114c3965e16fe523f88c913e701602604589Phil Burk        if ((forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS)
567507ac114c3965e16fe523f88c913e701602604589Phil Burk                && !supportsOtherSurround) {
567607ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_E_AC3);
567707ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_DTS);
567807ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_DTS_HD);
567907ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsOtherSurround = true;
568007ac114c3965e16fe523f88c913e701602604589Phil Burk        }
568107ac114c3965e16fe523f88c913e701602604589Phil Burk
568207ac114c3965e16fe523f88c913e701602604589Phil Burk        // Add support for IEC61937 if any raw surround supported.
568307ac114c3965e16fe523f88c913e701602604589Phil Burk        // The HAL could do this but add it here, just in case.
568407ac114c3965e16fe523f88c913e701602604589Phil Burk        if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
568507ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_IEC61937);
568607ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsIEC61937 = true;
568709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        }
568809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
56890709b0aba2adb719d347341ff58441347a1c1582Phil Burk}
56900709b0aba2adb719d347341ff58441347a1c1582Phil Burk
56910709b0aba2adb719d347341ff58441347a1c1582Phil Burk// Modify the list of channel masks supported.
56920709b0aba2adb719d347341ff58441347a1c1582Phil Burkvoid AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
56930709b0aba2adb719d347341ff58441347a1c1582Phil Burk    ChannelsVector &channelMasks = *channelMasksPtr;
56940709b0aba2adb719d347341ff58441347a1c1582Phil Burk    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
56950709b0aba2adb719d347341ff58441347a1c1582Phil Burk            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
56960709b0aba2adb719d347341ff58441347a1c1582Phil Burk
56970709b0aba2adb719d347341ff58441347a1c1582Phil Burk    // If NEVER, then remove support for channelMasks > stereo.
56980709b0aba2adb719d347341ff58441347a1c1582Phil Burk    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
56990709b0aba2adb719d347341ff58441347a1c1582Phil Burk        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
57000709b0aba2adb719d347341ff58441347a1c1582Phil Burk            audio_channel_mask_t channelMask = channelMasks[maskIndex];
57010709b0aba2adb719d347341ff58441347a1c1582Phil Burk            if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
57020709b0aba2adb719d347341ff58441347a1c1582Phil Burk                ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
57030709b0aba2adb719d347341ff58441347a1c1582Phil Burk                channelMasks.removeAt(maskIndex);
57040709b0aba2adb719d347341ff58441347a1c1582Phil Burk            } else {
57050709b0aba2adb719d347341ff58441347a1c1582Phil Burk                maskIndex++;
57060709b0aba2adb719d347341ff58441347a1c1582Phil Burk            }
57070709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
57080709b0aba2adb719d347341ff58441347a1c1582Phil Burk    // If ALWAYS, then make sure we at least support 5.1
57090709b0aba2adb719d347341ff58441347a1c1582Phil Burk    } else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
57100709b0aba2adb719d347341ff58441347a1c1582Phil Burk        bool supports5dot1 = false;
57110709b0aba2adb719d347341ff58441347a1c1582Phil Burk        // Are there any channel masks that can be considered "surround"?
57120709b0aba2adb719d347341ff58441347a1c1582Phil Burk        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); maskIndex++) {
57130709b0aba2adb719d347341ff58441347a1c1582Phil Burk            audio_channel_mask_t channelMask = channelMasks[maskIndex];
57140709b0aba2adb719d347341ff58441347a1c1582Phil Burk            if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
57150709b0aba2adb719d347341ff58441347a1c1582Phil Burk                supports5dot1 = true;
57160709b0aba2adb719d347341ff58441347a1c1582Phil Burk                break;
57170709b0aba2adb719d347341ff58441347a1c1582Phil Burk            }
57180709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
57190709b0aba2adb719d347341ff58441347a1c1582Phil Burk        // If not then add 5.1 support.
57200709b0aba2adb719d347341ff58441347a1c1582Phil Burk        if (!supports5dot1) {
57210709b0aba2adb719d347341ff58441347a1c1582Phil Burk            channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
57220709b0aba2adb719d347341ff58441347a1c1582Phil Burk            ALOGI("%s: force ALWAYS, so adding channelMask for 5.1 surround", __FUNCTION__);
57230709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
572409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
572509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk}
572609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
572700eeb32846df81288f12fe4c83e61d7db2842226Phil Burkvoid AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
572800eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                                             audio_io_handle_t ioHandle,
5729112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                             AudioProfileVector &profiles)
5730112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie{
5731112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    String8 reply;
57320709b0aba2adb719d347341ff58441347a1c1582Phil Burk
5733112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    // Format MUST be checked first to update the list of AudioProfile
5734112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    if (profiles.hasDynamicFormat()) {
5735388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov        reply = mpClientInterface->getParameters(
5736388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
57370709b0aba2adb719d347341ff58441347a1c1582Phil Burk        ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
573862e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent        AudioParameter repliedParameters(reply);
573962e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent        if (repliedParameters.get(
5740388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
5741112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
5742112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            return;
5743112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
574409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        FormatVector formats = formatsFromString(reply.string());
574500eeb32846df81288f12fe4c83e61d7db2842226Phil Burk        if (device == AUDIO_DEVICE_OUT_HDMI) {
57460709b0aba2adb719d347341ff58441347a1c1582Phil Burk            filterSurroundFormats(&formats);
574700eeb32846df81288f12fe4c83e61d7db2842226Phil Burk        }
574809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        profiles.setFormats(formats);
5749112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
5750112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    const FormatVector &supportedFormats = profiles.getSupportedFormats();
5751112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
575220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent    for (size_t formatIndex = 0; formatIndex < supportedFormats.size(); formatIndex++) {
5753112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        audio_format_t format = supportedFormats[formatIndex];
575420eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        ChannelsVector channelMasks;
575520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        SampleRateVector samplingRates;
5756112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        AudioParameter requestedParameters;
5757388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov        requestedParameters.addInt(String8(AudioParameter::keyFormat), format);
5758112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
5759112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        if (profiles.hasDynamicRateFor(format)) {
5760388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov            reply = mpClientInterface->getParameters(
5761388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    ioHandle,
5762388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    requestedParameters.toString() + ";" +
5763388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    AudioParameter::keyStreamSupportedSamplingRates);
5764112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.string());
576562e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            AudioParameter repliedParameters(reply);
576662e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            if (repliedParameters.get(
5767388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    String8(AudioParameter::keyStreamSupportedSamplingRates), reply) == NO_ERROR) {
576862e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                samplingRates = samplingRatesFromString(reply.string());
5769112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            }
5770112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
5771112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        if (profiles.hasDynamicChannelsFor(format)) {
5772112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            reply = mpClientInterface->getParameters(ioHandle,
5773112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                     requestedParameters.toString() + ";" +
5774388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                                                     AudioParameter::keyStreamSupportedChannels);
5775112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.string());
577662e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            AudioParameter repliedParameters(reply);
577762e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            if (repliedParameters.get(
5778388360c786cdcbec650b79db65c734b8952dfec0Mikhail Naganov                    String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
577962e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                channelMasks = channelMasksFromString(reply.string());
57800709b0aba2adb719d347341ff58441347a1c1582Phil Burk                if (device == AUDIO_DEVICE_OUT_HDMI) {
57810709b0aba2adb719d347341ff58441347a1c1582Phil Burk                    filterSurroundChannelMasks(&channelMasks);
57820709b0aba2adb719d347341ff58441347a1c1582Phil Burk                }
5783112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            }
5784112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
578520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
5786112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
5787112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie}
5788d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
5789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android
5790