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
27f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#define AUDIO_POLICY_XML_CONFIG_FILE "/system/etc/audio_policy_configuration.xml"
28f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie
29d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <inttypes.h>
30d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <math.h>
31d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
322110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie#include <AudioPolicyManagerInterface.h>
332110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie#include <AudioPolicyEngineInstance.h>
34d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <cutils/properties.h>
35e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <utils/Log.h>
36e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#include <hardware/audio.h>
37d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include <hardware/audio_effect.h>
383b73df74357b33869b39a1d69427673c780bd805Eric Laurent#include <media/AudioParameter.h>
39e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent#include <media/AudioPolicyHelper.h>
40df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent#include <soundtrigger/SoundTrigger.h>
41d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent#include "AudioPolicyManager.h"
42d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#ifndef USE_XML_AUDIO_POLICY_CONF
4353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <ConfigParsingUtils.h>
44d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <StreamDescriptor.h>
45f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#endif
46d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <Serializer.h>
47a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie#include "TypeConverter.h"
4853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <policy.h>
49e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
503b73df74357b33869b39a1d69427673c780bd805Eric Laurentnamespace android {
51e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
52dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent//FIXME: workaround for truncated touch sounds
53dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent// to be removed when the problem is handled by system UI
54dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent#define TOUCH_SOUND_FIXED_DELAY_MS 100
55e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
56e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// AudioPolicyInterface implementation
57e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
58e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
59e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
60e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      audio_policy_dev_state_t state,
61e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      const char *device_address,
62e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                      const char *device_name)
63e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
64e743a47f445f02a0612018fa5640301304844fbfPaul McLean    return setDeviceConnectionStateInt(device, state, device_address, device_name);
65c73ca6ef04136f28306784ad35f444538f081957Eric Laurent}
66c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
67c73ca6ef04136f28306784ad35f444538f081957Eric Laurentstatus_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
68a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent                                                         audio_policy_dev_state_t state,
69e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                         const char *device_address,
70e743a47f445f02a0612018fa5640301304844fbfPaul McLean                                                         const char *device_name)
71c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{
72e743a47f445f02a0612018fa5640301304844fbfPaul McLean    ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
73e743a47f445f02a0612018fa5640301304844fbfPaul McLean-            device, state, device_address, device_name);
74e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
75e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // connect/disconnect only 1 device at a time
76e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
77e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
7853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    sp<DeviceDescriptor> devDesc =
7953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            mHwModules.getDeviceDescriptor(device, device_address, device_name);
80e743a47f445f02a0612018fa5640301304844fbfPaul McLean
81e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle output devices
82e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
83d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> outputs;
84d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
853a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
863a4311c68348f728558e87b5db67d47605783890Eric Laurent
87e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // save a copy of the opened output descriptors before any output is opened or closed
88e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
89e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
90e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
91e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
92e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device connection
933ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
943a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
95e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %x", device);
96e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
97e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
98e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setDeviceConnectionState() connecting device %x", device);
99e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // register new device as available
1013a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableOutputDevices.add(devDesc);
1023a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
10353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                sp<HwModule> module = mHwModules.getModuleForDevice(device);
104cf817a2330936947df94c11859f48771f5596a59Eric Laurent                if (module == 0) {
105cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
106cf817a2330936947df94c11859f48771f5596a59Eric Laurent                          device);
107cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    mAvailableOutputDevices.remove(devDesc);
108cf817a2330936947df94c11859f48771f5596a59Eric Laurent                    return INVALID_OPERATION;
109cf817a2330936947df94c11859f48771f5596a59Eric Laurent                }
110e743a47f445f02a0612018fa5640301304844fbfPaul McLean                mAvailableOutputDevices[index]->attach(module);
1113a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
1123a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
114e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
115a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
1160fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                mAvailableOutputDevices.remove(devDesc);
1170fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                return INVALID_OPERATION;
1180fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            }
1192110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
1202110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
1212110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
1220fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            // outputs should never be empty here
1230fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
1240fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    "checkOutputsForDevice() returned no outputs but status OK");
1250fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
1260fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                  outputs.size());
1273ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
12856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            // Send connect to HALs
1293ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            AudioParameter param = AudioParameter(devDesc->mAddress);
1303ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
1313ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
1323ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
1333ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            } break;
134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle output device disconnection
1353b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
1363a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %x", device);
138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1415c477aa6205e2ebafec237411900d89a510cc105Paul McLean            ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
1425c477aa6205e2ebafec237411900d89a510cc105Paul McLean
143e743a47f445f02a0612018fa5640301304844fbfPaul McLean            // Send Disconnect to HALs
144a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            AudioParameter param = AudioParameter(devDesc->mAddress);
1455c477aa6205e2ebafec237411900d89a510cc105Paul McLean            param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
1465c477aa6205e2ebafec237411900d89a510cc105Paul McLean            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
1475c477aa6205e2ebafec237411900d89a510cc105Paul McLean
148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // remove device from available output devices
1493a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(devDesc);
1503a4311c68348f728558e87b5db67d47605783890Eric Laurent
151a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
1522110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
1532110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
1542110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } break;
156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1623a4311c68348f728558e87b5db67d47605783890Eric Laurent        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
1633a4311c68348f728558e87b5db67d47605783890Eric Laurent        // output is suspended before any tracks are moved to it
164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkA2dpSuspend();
165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForAllStrategies();
166e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // outputs must be closed after checkOutputForAllStrategies() is executed
167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputs.isEmpty()) {
168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < outputs.size(); i++) {
169c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // close unused outputs after device disconnection or direct outputs that have been
171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // opened by checkOutputsForDevice() to query dynamic parameters
1723b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                         (desc->mDirectOpenCount == 0))) {
175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    closeOutput(outputs[i]);
176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1783a4311c68348f728558e87b5db67d47605783890Eric Laurent            // check again after closing A2DP output to reset mA2dpSuspended if needed
1793a4311c68348f728558e87b5db67d47605783890Eric Laurent            checkA2dpSuspend();
180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
18387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
184c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
185c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            updateCallRouting(newDevice);
186c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
188c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
189c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
190c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
191c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // do not force device change on duplicated output because if device is 0, it will
192c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // also force a device 0 for the two outputs it is duplicated to which may override
193c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                // a valid device selection on those outputs.
194c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                bool force = !desc->isDuplicated()
19553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                        && (!device_distinguishes_on_address(device)
196c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                // always force when disconnecting (a non-duplicated device)
197c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
198c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setOutputDevice(desc, newDevice, force, 0);
199c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            }
200e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
202d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
203d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            cleanUpForDevice(devDesc);
204d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
205d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
20672aa32f7dbbfb658097930b57659d8e50f24a953Eric Laurent        mpClientInterface->onAudioPortListUpdate();
207b71e58b64cd4992355cf6afaf3f3530f723bc72cEric Laurent        return NO_ERROR;
208d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }  // end if is output device
209d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
210e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle input devices
211e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_input_device(device)) {
212d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        SortedVector <audio_io_handle_t> inputs;
213d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2143a4311c68348f728558e87b5db67d47605783890Eric Laurent        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        switch (state)
216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device connection
2183b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
2193a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device already connected: %d", device);
221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
22353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<HwModule> module = mHwModules.getModuleForDevice(device);
2246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (module == NULL) {
2256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
2266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                      device);
2276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
2286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
2299080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean            if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
230d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                return INVALID_OPERATION;
231d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
232d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
2333a4311c68348f728558e87b5db67d47605783890Eric Laurent            index = mAvailableInputDevices.add(devDesc);
2343a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index >= 0) {
235e743a47f445f02a0612018fa5640301304844fbfPaul McLean                mAvailableInputDevices[index]->attach(module);
2363a4311c68348f728558e87b5db67d47605783890Eric Laurent            } else {
2373a4311c68348f728558e87b5db67d47605783890Eric Laurent                return NO_MEMORY;
2383a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
2393ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
2403ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            // Set connect to HALs
2413ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            AudioParameter param = AudioParameter(devDesc->mAddress);
2423ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
2433ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
2443ae5f31393609b7fa92f24132c66e9a8c9244a45Eric Laurent
2452110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
2462110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
247d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle input device disconnection
2503b73df74357b33869b39a1d69427673c780bd805Eric Laurent        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
2513a4311c68348f728558e87b5db67d47605783890Eric Laurent            if (index < 0) {
252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("setDeviceConnectionState() device not connected: %d", device);
253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return INVALID_OPERATION;
254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
2555c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2565c477aa6205e2ebafec237411900d89a510cc105Paul McLean            ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
2575c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2585c477aa6205e2ebafec237411900d89a510cc105Paul McLean            // Set Disconnect to HALs
259a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent            AudioParameter param = AudioParameter(devDesc->mAddress);
2605c477aa6205e2ebafec237411900d89a510cc105Paul McLean            param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
2615c477aa6205e2ebafec237411900d89a510cc105Paul McLean            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
2625c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2639080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean            checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
2643a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(devDesc);
2655c477aa6205e2ebafec237411900d89a510cc105Paul McLean
2662110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            // Propagate device availability to Engine
2672110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->setDeviceConnectionState(devDesc, state);
268d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } break;
269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        default:
271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGE("setDeviceConnectionState() invalid state: %x", state);
272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
275d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        closeAllInputs();
2765f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        // As the input device list can impact the output device selection, update
2775f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        // getDeviceForStrategy() cache
2785f5fca540ce22d2f9caff1c823b2d5b637904729Eric Laurent        updateDevicesAndOutputs();
279e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
28087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
281c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
282c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            updateCallRouting(newDevice);
283c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
284c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
285d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
286d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            cleanUpForDevice(devDesc);
287d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
288d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
289b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mpClientInterface->onAudioPortListUpdate();
290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
291d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end if is input device
292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW("setDeviceConnectionState() invalid device: %x", device);
294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return BAD_VALUE;
295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
297e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
29853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                                      const char *device_address)
299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
300634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    sp<DeviceDescriptor> devDesc =
301634b71478742310960f3fdb4241e70a0735712c4Eric Laurent            mHwModules.getDeviceDescriptor(device, device_address, "",
302634b71478742310960f3fdb4241e70a0735712c4Eric Laurent                                           (strlen(device_address) != 0)/*matchAddress*/);
303634b71478742310960f3fdb4241e70a0735712c4Eric Laurent
304634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    if (devDesc == 0) {
305634b71478742310960f3fdb4241e70a0735712c4Eric Laurent        ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
306634b71478742310960f3fdb4241e70a0735712c4Eric Laurent              device, device_address);
307634b71478742310960f3fdb4241e70a0735712c4Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
308634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    }
30953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
3103a4311c68348f728558e87b5db67d47605783890Eric Laurent    DeviceVector *deviceVector;
3113a4311c68348f728558e87b5db67d47605783890Eric Laurent
312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_output_device(device)) {
3133a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableOutputDevices;
314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (audio_is_input_device(device)) {
3153a4311c68348f728558e87b5db67d47605783890Eric Laurent        deviceVector = &mAvailableInputDevices;
3163a4311c68348f728558e87b5db67d47605783890Eric Laurent    } else {
3173a4311c68348f728558e87b5db67d47605783890Eric Laurent        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
3183a4311c68348f728558e87b5db67d47605783890Eric Laurent        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
320634b71478742310960f3fdb4241e70a0735712c4Eric Laurent
321634b71478742310960f3fdb4241e70a0735712c4Eric Laurent    return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
322634b71478742310960f3fdb4241e70a0735712c4Eric Laurent            AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
323a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent}
324a1d525fbf2c1e0b2c61e5d29f338b0a0d8823436Eric Laurent
325dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurentuint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
326c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent{
327c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    bool createTxPatch = false;
328c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    status_t status;
329c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    audio_patch_handle_t afPatchHandle;
330c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    DeviceVector deviceList;
331dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t muteWaitMs = 0;
332c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
333a76c7de622e6e29f8559921d8d2e9ef93eb37d1fAndy Hung    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
334dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        return muteWaitMs;
33587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    }
336c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
337c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
338c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
339c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // release existing RX patch if any
340c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (mCallRxPatch != 0) {
341c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
342c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mCallRxPatch.clear();
343c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
344c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // release TX patch if any
345c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (mCallTxPatch != 0) {
346c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
347c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        mCallTxPatch.clear();
348c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
349c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
350c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // If the RX device is on the primary HW module, then use legacy routing method for voice calls
351c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // via setOutputDevice() on primary output.
352c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    // Otherwise, create two audio patches for TX and RX path.
353c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    if (availablePrimaryOutputDevices() & rxDevice) {
354dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        muteWaitMs = setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
355c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // If the TX device is also on the primary HW module, setOutputDevice() will take care
356c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // of it due to legacy implementation. If not, create a patch.
357c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
358c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                == AUDIO_DEVICE_NONE) {
359c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            createTxPatch = true;
360c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
3618ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    } else { // create RX path audio patch
3628ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        struct audio_patch patch;
3638ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent
3648ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        patch.num_sources = 1;
3658ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        patch.num_sinks = 1;
366c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
367c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
368c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() selected device not in output device list");
369c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
370c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
371c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
372c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() no telephony RX device");
373c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
374c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
375c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
376c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
377c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
378c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // request to reuse existing output stream if one is already opened to reach the RX device
379c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        SortedVector<audio_io_handle_t> outputs =
380c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                getOutputsForDevice(rxDevice, mOutputs);
3818838a3895c365d443ee22e169ccf45956780c081Eric Laurent        audio_io_handle_t output = selectOutput(outputs,
3828838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_OUTPUT_FLAG_NONE,
3838838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_FORMAT_INVALID);
384c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (output != AUDIO_IO_HANDLE_NONE) {
385c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
386c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
387c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                        "updateCallRouting() RX device output is duplicated");
388c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            outputDesc->toAudioPortConfig(&patch.sources[1]);
3893bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent            patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
390c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            patch.num_sources = 2;
391c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
392c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
393c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
394dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
395c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
396c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                               status);
397c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (status == NO_ERROR) {
39898cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie            mCallRxPatch = new AudioPatch(&patch, mUidCached);
399c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallRxPatch->mAfPatchHandle = afPatchHandle;
400c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallRxPatch->mUid = mUidCached;
401c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
402c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        createTxPatch = true;
403c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
4048ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    if (createTxPatch) { // create TX path audio patch
405c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        struct audio_patch patch;
4068ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent
407c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        patch.num_sources = 1;
408c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        patch.num_sinks = 1;
409c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
410c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
411c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() selected device not in input device list");
412c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
413c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
414c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
415c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOG_ASSERT(!deviceList.isEmpty(),
416c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                    "updateCallRouting() no telephony TX device");
417c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
418c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
419c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
420c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        SortedVector<audio_io_handle_t> outputs =
421c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
4228838a3895c365d443ee22e169ccf45956780c081Eric Laurent        audio_io_handle_t output = selectOutput(outputs,
4238838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_OUTPUT_FLAG_NONE,
4248838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                AUDIO_FORMAT_INVALID);
425c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // request to reuse existing output stream if one is already opened to reach the TX
426c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        // path output device
427c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (output != AUDIO_IO_HANDLE_NONE) {
428c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
429c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
430c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                        "updateCallRouting() RX device output is duplicated");
431c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            outputDesc->toAudioPortConfig(&patch.sources[1]);
4323bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent            patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
433c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            patch.num_sources = 2;
434c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
435c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
436c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // terminate active capture if on the same HW module as the call TX source device
437c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // FIXME: would be better to refine to only inputs whose profile connects to the
438c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // call TX device but this information is not in the audio patch and logic here must be
439c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        // symmetric to the one in startInput()
440232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        audio_io_handle_t activeInput = mInputs.getActiveInput();
441232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (activeInput != 0) {
442232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
443232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            if (activeDesc->getModuleHandle() == txSourceDeviceDesc->getModuleHandle()) {
444232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                //FIXME: consider all active sessions
445232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
446232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                audio_session_t activeSession = activeSessions.keyAt(0);
447232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                stopInput(activeInput, activeSession);
448232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                releaseInput(activeInput, activeSession);
449c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent            }
450c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent        }
451c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent
452c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
453dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
454c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
455c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent                                               status);
456c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        if (status == NO_ERROR) {
45798cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie            mCallTxPatch = new AudioPatch(&patch, mUidCached);
458c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallTxPatch->mAfPatchHandle = afPatchHandle;
459c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent            mCallTxPatch->mUid = mUidCached;
460c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
461c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
462dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
463dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    return muteWaitMs;
464c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent}
465c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent
466e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setPhoneState(audio_mode_t state)
467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
468e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setPhoneState() state %d", state);
4692110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    // store previous phone state for management of sonification strategy below
4702110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    int oldState = mEngine->getPhoneState();
471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4722110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->setPhoneState(state) != NO_ERROR) {
4732110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        ALOGW("setPhoneState() invalid or same state %d", state);
474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4762110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    /// Opens: can these line be executed after the switch of volume curves???
477e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if leaving call state, handle special case of active streams
478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
47963dea1d5334acf3baa9448086dd504ead57d814bEric Laurent    if (isStateInCall(oldState)) {
480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
481794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
4823b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, false, true);
483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4842cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent
48563dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        // force reevaluating accessibility routing when call stops
4862cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4892110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    /**
4902110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     * Switching to or from incall state or switching between telephony and VoIP lead to force
4912110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     * routing command.
4922110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie     */
4932110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
4942110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                  || (is_state_in_call(state) && (state != oldState)));
495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new phone state
497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int delayMs = 0;
502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        nsecs_t sysTime = systemTime();
504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
505c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // mute media and sonification strategies and delay device switch by the largest
507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // latency of any output where either strategy is active.
508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // This avoid sending the ring tone or music tail into the earpiece or headset.
509ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if ((isStrategyActive(desc, STRATEGY_MEDIA,
510ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  SONIFICATION_HEADSET_MUSIC_DELAY,
511ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  sysTime) ||
512ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                 isStrategyActive(desc, STRATEGY_SONIFICATION,
513ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  SONIFICATION_HEADSET_MUSIC_DELAY,
514ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                  sysTime)) &&
515c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    (delayMs < (int)desc->latency()*2)) {
516c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                delayMs = desc->latency()*2;
517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
518c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_MEDIA, true, desc);
519c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
520e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
521c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, true, desc);
522c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
524e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
52787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if (hasPrimaryOutput()) {
52887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // Note that despite the fact that getNewOutputDevice() is called on the primary output,
52987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // the device returned is not necessarily reachable via this output
53087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
53187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // force routing command to audio hardware when ending call
53287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        // even if no device change is needed
53387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
53487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            rxDevice = mPrimaryOutput->device();
535c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
53687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent
53787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        if (state == AUDIO_MODE_IN_CALL) {
53887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            updateCallRouting(rxDevice, delayMs);
53987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        } else if (oldState == AUDIO_MODE_IN_CALL) {
54087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (mCallRxPatch != 0) {
54187ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
54287ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mCallRxPatch.clear();
54387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            }
54487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (mCallTxPatch != 0) {
54587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
54687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                mCallTxPatch.clear();
54787ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            }
54887ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
54987ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        } else {
55087ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
551c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
552c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if entering in call state, handle special case of active streams
554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // pertaining to sonification strategy see handleIncallSonification()
555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isStateInCall(state)) {
556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("setPhoneState() in call state management: new state is %d", state);
557794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
5583b73df74357b33869b39a1d69427673c780bd805Eric Laurent            handleIncallSonification((audio_stream_type_t)stream, true, true);
559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
56063dea1d5334acf3baa9448086dd504ead57d814bEric Laurent
56163dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        // force reevaluating accessibility routing when call starts
56263dea1d5334acf3baa9448086dd504ead57d814bEric Laurent        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
5663b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_MODE_RINGTONE &&
5673b73df74357b33869b39a1d69427673c780bd805Eric Laurent        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = true;
569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mLimitRingtoneVolume = false;
571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
574887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Triviaudio_mode_t AudioPolicyManager::getPhoneState() {
575887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi    return mEngine->getPhoneState();
576887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi}
577887a9ed4446cb451181c392a0e51a69914e58fbfJean-Michel Trivi
578e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
5793b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                         audio_policy_forced_cfg_t config)
580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5812110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
5822110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
5832110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->setForceUse(usage, config) != NO_ERROR) {
5842110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
5852110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        return;
586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5872110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
5882110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
5892110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check for device and output changes triggered by new force usage
592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkA2dpSuspend();
593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForAllStrategies();
594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
59509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
596dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    //FIXME: workaround for truncated touch sounds
597dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    // to be removed when the problem is handled by system UI
598dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t delayMs = 0;
599dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    uint32_t waitMs = 0;
600dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    if (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) {
601dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
602dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent    }
60387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
604c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
605dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        waitMs = updateCallRouting(newDevice, delayMs);
606c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    }
607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
608c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
609c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
610c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
611dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
612dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                                     delayMs);
613c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent        }
614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
615dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            applyStreamVolumes(outputDesc, newDevice, waitMs, true);
616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
619232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    audio_io_handle_t activeInput = mInputs.getActiveInput();
620232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    if (activeInput != 0) {
621232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
622232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        audio_devices_t newDevice = getNewInputDevice(activeInput);
623c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        // Force new input selection if the new device can not be reached via current input
624232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (activeDesc->mProfile->getSupportedDevices().types() & (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
625232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            setInputDevice(activeInput, newDevice);
626c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        } else {
627232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            closeInput(activeInput);
628c171c7c47d099a52ade95c3c8d8907bf09bb88faEric Laurent        }
629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
632e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setSystemProperty(const char* property, const char* value)
633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setSystemProperty() property %s, value %s", property, value);
635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
636e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// Find a direct output profile compatible with the parameters passed, even if the input flags do
638e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// not explicitly request a direct output
63956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
640e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_devices_t device,
641e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               uint32_t samplingRate,
642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_format_t format,
643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_channel_mask_t channelMask,
644e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                               audio_output_flags_t flags)
645e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
646861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    // only retain flags that will drive the direct output profile selection
647861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    // if explicitly requested
648861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    static const uint32_t kRelevantFlags =
649861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
650861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    flags =
651861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
652861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
653861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    sp<IOProfile> profile;
654861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
658e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
659e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
660861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
661861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            if (!curProfile->isCompatibleProfile(device, String8(""),
662f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    samplingRate, NULL /*updatedSamplingRate*/,
663f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    format, NULL /*updatedFormat*/,
664f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    channelMask, NULL /*updatedChannelMask*/,
665861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                    flags)) {
666861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
667861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
668861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            // reject profiles not corresponding to a device currently available
669a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((mAvailableOutputDevices.types() & curProfile->getSupportedDevicesType()) == 0) {
670861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
671861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
672861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            // if several profiles are compatible, give priority to one with offload capability
673a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
674861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                continue;
675861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            }
676861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            profile = curProfile;
677a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
678861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent                break;
6793a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
682861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent    return profile;
683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
685e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
68653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                uint32_t samplingRate,
68753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                audio_format_t format,
68853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                audio_channel_mask_t channelMask,
68953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                audio_output_flags_t flags,
69053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                const audio_offload_info_t *offloadInfo)
691e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
6923b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(stream);
693e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          device, stream, samplingRate, format, channelMask, flags);
696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
697e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE,
698e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                              stream, samplingRate,format, channelMask,
699e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                              flags, offloadInfo);
700e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
701e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
702e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentstatus_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
703e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_io_handle_t *output,
704e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_session_t session,
705e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_stream_type_t *stream,
7068c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                              uid_t uid,
707e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              uint32_t samplingRate,
708e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_format_t format,
709e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_channel_mask_t channelMask,
710e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              audio_output_flags_t flags,
711aa9811945f575614b3482d09e4d969792701cebbPaul McLean                                              audio_port_handle_t selectedDeviceId,
712e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                              const audio_offload_info_t *offloadInfo)
713e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent{
714e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    audio_attributes_t attributes;
715e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (attr != NULL) {
716e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (!isValidAttributes(attr)) {
717e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
718e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                  attr->usage, attr->content_type, attr->flags,
719e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                  attr->tags);
720e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            return BAD_VALUE;
721e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        }
722e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        attributes = *attr;
723e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    } else {
724e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
725e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            ALOGE("getOutputForAttr():  invalid stream type");
726e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            return BAD_VALUE;
727e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        }
728e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        stream_type_to_audio_attributes(*stream, &attributes);
7295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
730c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc;
731e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi    if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
732036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
733fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        if (!audio_has_proportional_frames(format)) {
734036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie            return BAD_VALUE;
735275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
736036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        *stream = streamTypefromAttributesInt(&attributes);
737036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        *output = desc->mIoHandle;
738036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        ALOGV("getOutputForAttr() returns output %d", *output);
739036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        return NO_ERROR;
740275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
741275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
742275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
743275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        return BAD_VALUE;
744275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
745275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
7468c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
7478c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            " session %d selectedDeviceId %d",
7488c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
7498c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            session, selectedDeviceId);
7508c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
7518c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    *stream = streamTypefromAttributesInt(&attributes);
7528c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
7538c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Explicit routing?
7548c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    sp<DeviceDescriptor> deviceDesc;
7558c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
7568c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (mAvailableOutputDevices[i]->getId() == selectedDeviceId) {
7578c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            deviceDesc = mAvailableOutputDevices[i];
7588c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            break;
7598c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
7608c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
7618c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
7625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
763e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
7645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
76593c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent
766e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
76793c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
76893c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    }
76993c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent
770fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi    ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
7715bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi          device, samplingRate, format, channelMask, flags);
7725bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
773e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    *output = getOutputForDevice(device, session, *stream,
774e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                 samplingRate, format, channelMask,
775e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                 flags, offloadInfo);
776e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (*output == AUDIO_IO_HANDLE_NONE) {
7778c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        mOutputRoutes.removeRoute(session);
778e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return INVALID_OPERATION;
779e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
780aa9811945f575614b3482d09e4d969792701cebbPaul McLean
781e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return NO_ERROR;
7825bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
7835bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
7845bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_io_handle_t AudioPolicyManager::getOutputForDevice(
7855bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_devices_t device,
786caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent        audio_session_t session __unused,
7875bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_stream_type_t stream,
7885bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        uint32_t samplingRate,
7895bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_format_t format,
7905bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_channel_mask_t channelMask,
7915bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        audio_output_flags_t flags,
7925bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        const audio_offload_info_t *offloadInfo)
7935bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{
794cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
795cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    status_t status;
7965bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mCurOutput != 0) {
799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
801e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
802e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mTestOutputs[mCurOutput] == 0) {
803e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() opening test output");
804c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
805c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                               mpClientInterface);
806e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mDevice = mTestDevice;
807e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mLatency = mTestLatencyMs;
8083b73df74357b33869b39a1d69427673c780bd805Eric Laurent            outputDesc->mFlags =
8093b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
810e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mRefCount[stream] = 0;
811cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
812cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.sample_rate = mTestSamplingRate;
813cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.channel_mask = mTestChannels;
814cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.format = mTestFormat;
81577cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk            if (offloadInfo != NULL) {
81677cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk                config.offload_info = *offloadInfo;
81777cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk            }
818cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            status = mpClientInterface->openOutput(0,
819cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &mTestOutputs[mCurOutput],
820cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &config,
821cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &outputDesc->mDevice,
822cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  String8(""),
823cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  &outputDesc->mLatency,
824cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                  outputDesc->mFlags);
825cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
826cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                outputDesc->mSamplingRate = config.sample_rate;
827cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                outputDesc->mFormat = config.format;
828cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                outputDesc->mChannelMask = config.channel_mask;
829e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                AudioParameter outputCmd = AudioParameter();
830e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputCmd.addInt(String8("set_id"),mCurOutput);
831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                addOutput(mTestOutputs[mCurOutput], outputDesc);
833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
834e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
835e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mTestOutputs[mCurOutput];
836e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
837e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
838e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
839e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a direct output if required by specified parameters
840e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //force direct flag if offload flag is set: offloading implies a direct output stream
841e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and all common behaviors are driven by checking only the direct flag
842e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // this should normally be set appropriately in the policy configuration file
843e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
8443b73df74357b33869b39a1d69427673c780bd805Eric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
845e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
84693c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
84793c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
84893c3d41bdb15e39dac0faea9c5b60f1637cd477cEric Laurent    }
849e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // only allow deep buffering for music stream type
850e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if (stream != AUDIO_STREAM_MUSIC) {
851e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
852439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda    } else if (/* stream == AUDIO_STREAM_MUSIC && */
853439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda            flags == AUDIO_OUTPUT_FLAG_NONE &&
854439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda            property_get_bool("audio.deep_buffer.media", false /* default_value */)) {
855439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda        // use DEEP_BUFFER as default output for music stream type
856439e4ed408c21bd65711d279bd5251cef7e83440Ravi Kumar Alamanda        flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
857e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
858c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda    if (stream == AUDIO_STREAM_TTS) {
859c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda        flags = AUDIO_OUTPUT_FLAG_TTS;
860c36a8897ff877f4c5b2e0580830faef8b87dd74aRavi Kumar Alamanda    }
861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
862b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    sp<IOProfile> profile;
863b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
864b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    // skip direct output selection if the request can obviously be attached to a mixed output
865c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent    // and not explicitly requested
866c260784e37dea73a2090d4ccd91472d61d3b6230Eric Laurent    if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
86705ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten            audio_is_linear_pcm(format) && samplingRate <= SAMPLE_RATE_HZ_MAX &&
868b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent            audio_channel_count_from_out_mask(channelMask) <= 2) {
869b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent        goto non_direct_output;
870b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent    }
871b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
8722ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
8732ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // This prevents creating an offloaded track and tearing it down immediately after start
8742ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // when audioflinger detects there is an active non offloadable effect.
875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
878b732cf5af93c33fa183769210ce9954521fb68cdEric Laurent
879e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
8802ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        profile = getProfileForDirectOutput(device,
882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           samplingRate,
883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           format,
884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           channelMask,
885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                           (audio_output_flags_t)flags);
886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
887e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
8881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (profile != 0) {
889c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = NULL;
890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
892c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc = desc;
895e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // reuse direct output if currently open and configured with same parameters
896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((samplingRate == outputDesc->mSamplingRate) &&
897e693002b0fb25099540588245892ed98103749baEric Laurent                        audio_formats_match(format, outputDesc->mFormat) &&
898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (channelMask == outputDesc->mChannelMask)) {
899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mDirectOpenCount++;
900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    return mOutputs.keyAt(i);
902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // close direct output if currently open and configured with different parameters
906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc != NULL) {
9071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            closeOutput(outputDesc->mIoHandle);
908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
909861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
910861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        // if the selected profile is offloaded and no offload info was specified,
911861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        // create a default one
912861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
913a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
914861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
915861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.sample_rate = samplingRate;
916861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.channel_mask = channelMask;
917861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.format = format;
918861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.stream_type = stream;
919861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.bit_rate = 0;
920861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.duration_us = -1;
921861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.has_video = true; // conservative
922861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            defaultOffloadInfo.is_streaming = true; // likely
923861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent            offloadInfo = &defaultOffloadInfo;
924861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        }
925861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent
926c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
928e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mLatency = 0;
929861a628adbcbe7c3baa6eab1b765b87b480ff4a2Eric Laurent        outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
930cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        audio_config_t config = AUDIO_CONFIG_INITIALIZER;
931cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        config.sample_rate = samplingRate;
932cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        config.channel_mask = channelMask;
933cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        config.format = format;
93477cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk        if (offloadInfo != NULL) {
93577cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk            config.offload_info = *offloadInfo;
93677cce80fa9d44f1e2a6bc486ad957fbbebfce3b2Phil Burk        }
937322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        status = mpClientInterface->openOutput(profile->getModuleHandle(),
938cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &output,
939cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &config,
940cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &outputDesc->mDevice,
941cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               String8(""),
942cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               &outputDesc->mLatency,
943cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                               outputDesc->mFlags);
944e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // only accept an output with the requested parameters
946cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        if (status != NO_ERROR ||
947cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            (samplingRate != 0 && samplingRate != config.sample_rate) ||
948e693002b0fb25099540588245892ed98103749baEric Laurent            (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) ||
949cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            (channelMask != 0 && channelMask != config.channel_mask)) {
950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
951e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    "format %d %d, channelMask %04x %04x", output, samplingRate,
952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputDesc->mChannelMask);
954cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (output != AUDIO_IO_HANDLE_NONE) {
955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mpClientInterface->closeOutput(output);
956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
957a82797faddb37adb2d441737884576684c8515cbEric Laurent            // fall back to mixer output if possible when the direct output could not be open
95805ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten            if (audio_is_linear_pcm(format) && samplingRate <= SAMPLE_RATE_HZ_MAX) {
95956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                goto non_direct_output;
96056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
961cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            return AUDIO_IO_HANDLE_NONE;
962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
963cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mSamplingRate = config.sample_rate;
964cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mChannelMask = config.channel_mask;
965cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mFormat = config.format;
966cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mRefCount[stream] = 0;
967cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mStopTime[stream] = 0;
968cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        outputDesc->mDirectOpenCount = 1;
969cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t srcOutput = getOutputForEffect();
971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        addOutput(output, outputDesc);
972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_io_handle_t dstOutput = getOutputForEffect();
973e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dstOutput == output) {
974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mPreviousOutputs = mOutputs;
977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("getOutput() returns new direct output %d", output);
978b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mpClientInterface->onAudioPortListUpdate();
979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return output;
980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
982b732cf5af93c33fa183769210ce9954521fb68cdEric Laurentnon_direct_output:
98314cbfcae68582eca97f1a8168c584254515879eeEric Laurent
98414cbfcae68582eca97f1a8168c584254515879eeEric Laurent    // A request for HW A/V sync cannot fallback to a mixed output because time
98514cbfcae68582eca97f1a8168c584254515879eeEric Laurent    // stamps are embedded in audio data
98614cbfcae68582eca97f1a8168c584254515879eeEric Laurent    if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
98714cbfcae68582eca97f1a8168c584254515879eeEric Laurent        return AUDIO_IO_HANDLE_NONE;
98814cbfcae68582eca97f1a8168c584254515879eeEric Laurent    }
98914cbfcae68582eca97f1a8168c584254515879eeEric Laurent
990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // ignoring channel mask due to downmix capability in mixer
991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
992e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open a non direct output
993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // for non direct outputs, only PCM is supported
995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (audio_is_linear_pcm(format)) {
996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // get which output is suitable for the specified stream. The actual
997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing change will happen when startOutput() will be called
998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
10008838a3895c365d443ee22e169ccf45956780c081Eric Laurent        // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
10018838a3895c365d443ee22e169ccf45956780c081Eric Laurent        flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
10028838a3895c365d443ee22e169ccf45956780c081Eric Laurent        output = selectOutput(outputs, flags, format);
1003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1007aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("  getOutputForDevice() returns output %d", output);
1008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
1010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1012e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
10138838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                       audio_output_flags_t flags,
10148838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                       audio_format_t format)
1015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several that provide a path to a particular device or set of
1017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // devices (the list was previously build by getOutputsForDevice()).
1018e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
1019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: the output with the highest number of requested policy flags
1020e693002b0fb25099540588245892ed98103749baEric Laurent    // 2: the output with the bit depth the closest to the requested one
1021e693002b0fb25099540588245892ed98103749baEric Laurent    // 3: the primary output
1022e693002b0fb25099540588245892ed98103749baEric Laurent    // 4: the first output in the list
1023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
1025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 1) {
1028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputs[0];
1029e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int maxCommonFlags = 0;
1032e693002b0fb25099540588245892ed98103749baEric Laurent    audio_io_handle_t outputForFlags = 0;
1033e693002b0fb25099540588245892ed98103749baEric Laurent    audio_io_handle_t outputForPrimary = 0;
1034e693002b0fb25099540588245892ed98103749baEric Laurent    audio_io_handle_t outputForFormat = 0;
1035e693002b0fb25099540588245892ed98103749baEric Laurent    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
1036e693002b0fb25099540588245892ed98103749baEric Laurent    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
1037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
1039c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
1040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (!outputDesc->isDuplicated()) {
10418838a3895c365d443ee22e169ccf45956780c081Eric Laurent            // if a valid format is specified, skip output if not compatible
10428838a3895c365d443ee22e169ccf45956780c081Eric Laurent            if (format != AUDIO_FORMAT_INVALID) {
10438838a3895c365d443ee22e169ccf45956780c081Eric Laurent                if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1044e693002b0fb25099540588245892ed98103749baEric Laurent                    if (!audio_formats_match(format, outputDesc->mFormat)) {
10458838a3895c365d443ee22e169ccf45956780c081Eric Laurent                        continue;
10468838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    }
10478838a3895c365d443ee22e169ccf45956780c081Eric Laurent                } else if (!audio_is_linear_pcm(format)) {
10488838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    continue;
10498838a3895c365d443ee22e169ccf45956780c081Eric Laurent                }
1050e693002b0fb25099540588245892ed98103749baEric Laurent                if (AudioPort::isBetterFormatMatch(
1051e693002b0fb25099540588245892ed98103749baEric Laurent                        outputDesc->mFormat, bestFormat, format)) {
1052e693002b0fb25099540588245892ed98103749baEric Laurent                    outputForFormat = outputs[i];
1053e693002b0fb25099540588245892ed98103749baEric Laurent                    bestFormat = outputDesc->mFormat;
1054e693002b0fb25099540588245892ed98103749baEric Laurent                }
10558838a3895c365d443ee22e169ccf45956780c081Eric Laurent            }
10568838a3895c365d443ee22e169ccf45956780c081Eric Laurent
1057a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
1058e693002b0fb25099540588245892ed98103749baEric Laurent            if (commonFlags >= maxCommonFlags) {
1059e693002b0fb25099540588245892ed98103749baEric Laurent                if (commonFlags == maxCommonFlags) {
1060e693002b0fb25099540588245892ed98103749baEric Laurent                    if (AudioPort::isBetterFormatMatch(
1061e693002b0fb25099540588245892ed98103749baEric Laurent                            outputDesc->mFormat, bestFormatForFlags, format)) {
1062e693002b0fb25099540588245892ed98103749baEric Laurent                        outputForFlags = outputs[i];
1063e693002b0fb25099540588245892ed98103749baEric Laurent                        bestFormatForFlags = outputDesc->mFormat;
1064e693002b0fb25099540588245892ed98103749baEric Laurent                    }
1065e693002b0fb25099540588245892ed98103749baEric Laurent                } else {
1066e693002b0fb25099540588245892ed98103749baEric Laurent                    outputForFlags = outputs[i];
1067e693002b0fb25099540588245892ed98103749baEric Laurent                    maxCommonFlags = commonFlags;
1068e693002b0fb25099540588245892ed98103749baEric Laurent                    bestFormatForFlags = outputDesc->mFormat;
1069e693002b0fb25099540588245892ed98103749baEric Laurent                }
1070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
1071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1072a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
1073e693002b0fb25099540588245892ed98103749baEric Laurent                outputForPrimary = outputs[i];
1074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1078e693002b0fb25099540588245892ed98103749baEric Laurent    if (outputForFlags != 0) {
1079e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForFlags;
1080e693002b0fb25099540588245892ed98103749baEric Laurent    }
1081e693002b0fb25099540588245892ed98103749baEric Laurent    if (outputForFormat != 0) {
1082e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForFormat;
1083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1084e693002b0fb25099540588245892ed98103749baEric Laurent    if (outputForPrimary != 0) {
1085e693002b0fb25099540588245892ed98103749baEric Laurent        return outputForPrimary;
1086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1088e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
1089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1091e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::startOutput(audio_io_handle_t output,
10923b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                             audio_stream_type_t stream,
1093e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                             audio_session_t session)
1094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1095aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("startOutput() output %d, stream %d, session %d",
1096aa9811945f575614b3482d09e4d969792701cebbPaul McLean          output, stream, session);
1097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startOutput() unknown output %d", output);
1100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1103c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1104c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
11058c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Routing?
11068c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mOutputRoutes.incRouteActivity(session);
11078c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
1108c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    audio_devices_t newDevice;
1109c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    AudioMix *policyMix = NULL;
1110c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    const char *address = NULL;
1111c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mPolicyMix != NULL) {
1112c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        policyMix = outputDesc->mPolicyMix;
1113c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        address = policyMix->mDeviceAddress.string();
1114c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
1115c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            newDevice = policyMix->mDeviceType;
1116c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        } else {
1117c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1118c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        }
1119493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    } else if (mOutputRoutes.hasRouteChanged(session)) {
1120493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent        newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
11218c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        checkStrategyRoute(getStrategy(stream), output);
1122c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
1123c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        newDevice = AUDIO_DEVICE_NONE;
1124c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1125c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1126c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    uint32_t delayMs = 0;
1127c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1128c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    status_t status = startSource(outputDesc, stream, newDevice, address, &delayMs);
1129c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1130c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (status != NO_ERROR) {
1131c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mOutputRoutes.decRouteActivity(session);
11328c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        return status;
1133c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1134c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // Automatically enable the remote submix input when output is started on a re routing mix
1135c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // of type MIX_TYPE_RECORDERS
1136c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent    if (audio_is_remote_submix_device(newDevice) && policyMix != NULL &&
1137c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            policyMix->mMixType == MIX_TYPE_RECORDERS) {
1138c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1139c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1140c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                    address,
1141c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    "remote-submix");
1142c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1143c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1144c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (delayMs != 0) {
1145c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        usleep(delayMs * 1000);
1146c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1147c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1148c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return status;
1149c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
1150c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1151c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t AudioPolicyManager::startSource(sp<AudioOutputDescriptor> outputDesc,
1152c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_stream_type_t stream,
1153c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_devices_t device,
1154c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                             const char *address,
1155c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             uint32_t *delayMs)
1156c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
1157d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // cannot start playback of STREAM_TTS if any other output is being used
1158d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    uint32_t beaconMuteLatency = 0;
1159c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1160c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    *delayMs = 0;
1161d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (stream == AUDIO_STREAM_TTS) {
1162d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        ALOGV("\t found BEACON stream");
11639459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
1164d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            return INVALID_OPERATION;
1165d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        } else {
1166d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
1167d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
1168d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    } else {
1169d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // some playback other than beacon starts
1170d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
1171d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
1172d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
117377305a67301c74438ee09fdb8f80b89a43712951Eric Laurent    // force device change if the output is inactive and no audio patch is already present.
11747c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent    // check active before incrementing usage count
117577305a67301c74438ee09fdb8f80b89a43712951Eric Laurent    bool force = !outputDesc->isActive() &&
117677305a67301c74438ee09fdb8f80b89a43712951Eric Laurent            (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
11777c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent
1178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // increment usage count for this stream on the requested output:
1179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // NOTE that the usage count is the same for duplicated output and hardware output which is
1180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    outputDesc->changeRefCount(stream, 1);
1182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1183493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
1184275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        // starting an output being rerouted?
1185c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (device == AUDIO_DEVICE_NONE) {
1186c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            device = getNewOutputDevice(outputDesc, false /*fromCache*/);
1187275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
1188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        routing_strategy strategy = getStrategy(stream);
1189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
1190d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
1191d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                            (beaconMuteLatency > 0);
1192d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        uint32_t waitMs = beaconMuteLatency;
1193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
11941f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (desc != outputDesc) {
119677305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // force a device change if any other output is:
119777305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - managed by the same hw module
119877305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - has a current device selection that differs from selected device.
119977305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - supports currently selected device
120077305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                // - has an active audio patch
1201e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // In this case, the audio HAL must receive the new device selection so that it can
1202e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // change the device currently selected by the other active output.
1203e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->sharesHwModuleWith(desc) &&
120477305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->device() != device &&
120577305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->supportedDevices() & device &&
120677305a67301c74438ee09fdb8f80b89a43712951Eric Laurent                        desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
1207e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    force = true;
1208e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1209e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // wait for audio on other active outputs to be presented when starting
1210d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                // a notification so that audio focus effect can propagate, or that a mute/unmute
1211d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                // event occurred for beacon
1212e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                uint32_t latency = desc->latency();
1213e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1214e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    waitMs = latency;
1215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1218dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force, 0, NULL, address);
1219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1220e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // handle special case for sonification while in call
1221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (isInCall()) {
1222e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleIncallSonification(stream, true, false);
1223e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1225e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // apply volume rules for current stream and device if necessary
1226e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkAndSetVolume(stream,
1227d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                          mVolumeCurves->getVolumeIndex(stream, device),
1228c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          outputDesc,
1229c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          device);
1230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // update the outputs if starting an output with a stream that can affect notification
1232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // routing
1233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleNotificationRoutingForStream(stream);
1234c722f30eef03e77054395ae122470cf8dba93937Eric Laurent
12352cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        // force reevaluating accessibility routing when ringtone or alarm starts
12362cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        if (strategy == STRATEGY_SONIFICATION) {
12372cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent            mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
12382cbe89a82d4167c5d5bcf3024edc22ab6874143aEric Laurent        }
1239dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
1240dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        if (waitMs > muteWaitMs) {
1241dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            *delayMs = waitMs - muteWaitMs;
1242dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        }
1243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1244dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
1245e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1247e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1249e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
12503b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                            audio_stream_type_t stream,
1251e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                            audio_session_t session)
1252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopOutput() unknown output %d", output);
1257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1260c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1261c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1262c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mRefCount[stream] == 1) {
1263c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // Automatically disable the remote submix input when output is stopped on a
1264c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // re routing mix of type MIX_TYPE_RECORDERS
1265c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1266c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                outputDesc->mPolicyMix != NULL &&
1267c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1268c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1269c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
12707638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    outputDesc->mPolicyMix->mDeviceAddress,
1271c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    "remote-submix");
1272c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        }
1273c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1274c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1275c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // Routing?
12768c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    bool forceDeviceUpdate = false;
1277c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
12788c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        int activityCount = mOutputRoutes.decRouteActivity(session);
12798c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        forceDeviceUpdate = (mOutputRoutes.hasRoute(session) && (activityCount == 0));
12808c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
12818c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (forceDeviceUpdate) {
12828c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
12838c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
1284c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
1285e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
12868c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    return stopSource(outputDesc, stream, forceDeviceUpdate);
1287c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
1288c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
1289c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t AudioPolicyManager::stopSource(sp<AudioOutputDescriptor> outputDesc,
12908c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            audio_stream_type_t stream,
12918c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            bool forceDeviceUpdate)
1292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
1293d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // always handle stream stop, check which stream type is stopping
1294d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
1295d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
1296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // handle special case for sonification while in call
1297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (isInCall()) {
1298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        handleIncallSonification(stream, false, false);
1299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1300e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1301e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->mRefCount[stream] > 0) {
1302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // decrement usage count of this stream on the output
1303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->changeRefCount(stream, -1);
1304aa9811945f575614b3482d09e4d969792701cebbPaul McLean
1305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // store time at which the stream was stopped - see isStreamActive()
13068c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
1307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStopTime[stream] = systemTime();
1308c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
1309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // delay the device switch by twice the latency because stopOutput() is executed when
1310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the track stop() command is received and at that time the audio track buffer can
1311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // still contain data that needs to be drained. The latency only covers the audio HAL
1312e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and kernel buffers. Also the latency does not always include additional delay in the
1313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // audio path (audio DSP, CODEC ...)
1314c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
1315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // force restoring the device selection on other active outputs if it differs from the
1317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // one being selected for this output
131857de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent            uint32_t delayMs = outputDesc->latency()*2;
1319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
13201f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1321c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                if (desc != outputDesc &&
1322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        desc->isActive() &&
1323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputDesc->sharesHwModuleWith(desc) &&
1324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        (newDevice != desc->device())) {
132511c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                    audio_devices_t newDevice2 = getNewOutputDevice(desc, false /*fromCache*/);
132611c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                    bool force = desc->device() != newDevice2;
1327c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    setOutputDevice(desc,
132811c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                                    newDevice2,
132911c499a59eb8effc59209f6c06df3ed78c2998a8Haynes Mathew George                                    force,
133057de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                                    delayMs);
133157de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    // re-apply device specific volume if not done by setOutputDevice()
133257de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    if (!force) {
133357de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                        applyStreamVolumes(desc, newDevice2, delayMs);
133457de36ccd1f524d602d267884bdcfae8559a6e6aEric Laurent                    }
1335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
1336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // update the outputs if stopping one with a stream that can affect notification routing
1338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            handleNotificationRoutingForStream(stream);
1339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
1341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
1342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGW("stopOutput() refcount is already 0");
1343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
1344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1347e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyManager::releaseOutput(audio_io_handle_t output,
1348caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                       audio_stream_type_t stream __unused,
1349caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                       audio_session_t session __unused)
1350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseOutput() %d", output);
1352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(output);
1353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseOutput() releasing unknown output %d", output);
1355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
1359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    int testIndex = testOutputIndex(output);
1360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (testIndex != 0) {
13611f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->isActive()) {
1363e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(output);
136453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            removeOutput(output);
1365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[testIndex] = 0;
1366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
1370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1371aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // Routing
1372aa9811945f575614b3482d09e4d969792701cebbPaul McLean    mOutputRoutes.removeRoute(session);
1373aa9811945f575614b3482d09e4d969792701cebbPaul McLean
1374c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
13753b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (desc->mDirectOpenCount <= 0) {
1377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("releaseOutput() invalid open count %d for output %d",
1378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                              desc->mDirectOpenCount, output);
1379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
1380e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1381e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--desc->mDirectOpenCount == 0) {
1382e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            closeOutput(output);
1383e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // If effects where present on the output, audioflinger moved them to the primary
1384e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // output by default: move them back to the appropriate output.
1385e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t dstOutput = getOutputForEffect();
138687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent            if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) {
1387c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
1388c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                               mPrimaryOutput->mIoHandle, dstOutput);
1389e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1390b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent            mpClientInterface->onAudioPortListUpdate();
1391e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1392e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1393e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1394e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1395e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1396caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurentstatus_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
1397caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_io_handle_t *input,
1398caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_session_t session,
13998c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                             uid_t uid,
1400caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             uint32_t samplingRate,
1401caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_format_t format,
1402caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent                                             audio_channel_mask_t channelMask,
140397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                                             audio_input_flags_t flags,
1404466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean                                             audio_port_handle_t selectedDeviceId,
140597bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                                             input_type_t *inputType)
1406e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1407caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
1408caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent            "session %d, flags %#x",
1409caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent          attr->source, samplingRate, format, channelMask, session, flags);
1410e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1411caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    *input = AUDIO_IO_HANDLE_NONE;
141297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi    *inputType = API_INPUT_INVALID;
1413275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    audio_devices_t device;
1414275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    // handle legacy remote submix case where the address was not always specified
1415275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    String8 address = String8("");
1416c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    audio_source_t inputSource = attr->source;
1417c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    audio_source_t halInputSource;
1418c722f30eef03e77054395ae122470cf8dba93937Eric Laurent    AudioMix *policyMix = NULL;
1419275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
1420c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    if (inputSource == AUDIO_SOURCE_DEFAULT) {
1421c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent        inputSource = AUDIO_SOURCE_MIC;
1422c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    }
1423c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    halInputSource = inputSource;
1424c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent
1425466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Explicit routing?
1426466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    sp<DeviceDescriptor> deviceDesc;
1427466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
1428466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean        if (mAvailableInputDevices[i]->getId() == selectedDeviceId) {
1429466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean            deviceDesc = mAvailableInputDevices[i];
1430466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean            break;
1431466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean        }
1432466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    }
14338c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
1434466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1435c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
1436275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
1437dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi        status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
1438036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        if (ret != NO_ERROR) {
1439036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie            return ret;
1440c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
144197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi        *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
1442036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1443036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        address = String8(attr->tags + strlen("addr="));
1444275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    } else {
1445c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent        device = getDeviceAndMixForInputSource(inputSource, &policyMix);
1446275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        if (device == AUDIO_DEVICE_NONE) {
1447c447ded04f11169e9b96b31cd196b2c4ffa9f31cEric Laurent            ALOGW("getInputForAttr() could not find device for source %d", inputSource);
1448275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            return BAD_VALUE;
1449275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
1450c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        if (policyMix != NULL) {
14517638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            address = policyMix->mDeviceAddress;
145297bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
145397bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // there is an external policy, but this input is attached to a mix of recorders,
145497bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // meaning it receives audio injected into the framework, so the recorder doesn't
145597bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // know about it and is therefore considered "legacy"
145697bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                *inputType = API_INPUT_LEGACY;
145797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            } else {
145897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // recording a mix of players defined by an external policy, we're rerouting for
145997bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                // an external policy
146097bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi                *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
146197bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            }
1462c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        } else if (audio_is_remote_submix_device(device)) {
1463c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            address = String8("0");
146497bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            *inputType = API_INPUT_MIX_CAPTURE;
146582db269d4797cb9909988b723d91fa2094a74b38Eric Laurent        } else if (device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
146682db269d4797cb9909988b723d91fa2094a74b38Eric Laurent            *inputType = API_INPUT_TELEPHONY_RX;
146797bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi        } else {
146897bb33f58d742539f3382583d7978fca71ffa2d5Jean-Michel Trivi            *inputType = API_INPUT_LEGACY;
1469c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
1470b367f5b2de343bfd9040028b00acb96567f30beaRavi Kumar Alamanda
1471599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1472599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1473599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    *input = getInputForDevice(device, address, session, uid, inputSource,
1474599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                               samplingRate, format, channelMask, flags,
1475599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                               policyMix);
1476599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (*input == AUDIO_IO_HANDLE_NONE) {
1477599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        mInputRoutes.removeRoute(session);
1478599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return INVALID_OPERATION;
1479599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1480599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("getInputForAttr() returns input type = %d", *inputType);
1481599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return NO_ERROR;
1482599c758b258cc5da0dba9b530425381facc37d77Eric Laurent}
1483599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1484599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1485599c758b258cc5da0dba9b530425381facc37d77Eric Laurentaudio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
1486599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        String8 address,
1487599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_session_t session,
1488599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        uid_t uid,
1489599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_source_t inputSource,
1490599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        uint32_t samplingRate,
1491599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_format_t format,
1492599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_channel_mask_t channelMask,
1493599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        audio_input_flags_t flags,
1494599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                        AudioMix *policyMix)
1495599c758b258cc5da0dba9b530425381facc37d77Eric Laurent{
1496599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
1497599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audio_source_t halInputSource = inputSource;
1498599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    bool isSoundTrigger = false;
1499599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1500599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (inputSource == AUDIO_SOURCE_HOTWORD) {
1501599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1502599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (index >= 0) {
1503599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            input = mSoundTriggerSessions.valueFor(session);
1504599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            isSoundTrigger = true;
1505599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1506599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            ALOGV("SoundTrigger capture on session %d input %d", session, input);
1507599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        } else {
1508599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
15095dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent        }
15105dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent    }
15115dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent
1512f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // find a compatible input profile (not necessarily identical in parameters)
1513f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    sp<IOProfile> profile;
1514f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // samplingRate and flags may be updated by getInputProfile
151505ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    uint32_t profileSamplingRate = (samplingRate == 0) ? SAMPLE_RATE_HZ_DEFAULT : samplingRate;
1516f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_format_t profileFormat = format;
1517f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_channel_mask_t profileChannelMask = channelMask;
1518f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    audio_input_flags_t profileFlags = flags;
1519f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    for (;;) {
1520275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        profile = getInputProfile(device, address,
1521f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                  profileSamplingRate, profileFormat, profileChannelMask,
1522f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                  profileFlags);
1523f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        if (profile != 0) {
1524f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung            break; // success
1525050677873c10d4da308ac222f8533c96cca3207eEric Laurent        } else if (profileFlags & AUDIO_INPUT_FLAG_RAW) {
1526050677873c10d4da308ac222f8533c96cca3207eEric Laurent            profileFlags = (audio_input_flags_t) (profileFlags & ~AUDIO_INPUT_FLAG_RAW); // retry
1527f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
1528f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung            profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
1529f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        } else { // fail
1530599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            ALOGW("getInputForDevice() could not find profile for device 0x%X,"
1531599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                  "samplingRate %u, format %#x, channelMask 0x%X, flags %#x",
1532f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                    device, samplingRate, format, channelMask, flags);
1533599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            return input;
15345dbe47139713292bf45bbf4f1a7af0835a5ff368Eric Laurent        }
1535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
153605ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    // Pick input sampling rate if not specified by client
153705ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    if (samplingRate == 0) {
153805ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten        samplingRate = profileSamplingRate;
153905ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten    }
1540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1541322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    if (profile->getModuleHandle() == 0) {
1542322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        ALOGE("getInputForAttr(): HW module %s not opened", profile->getModuleName());
1543599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return input;
1544cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    }
1545cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
1546599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = new AudioSession(session,
1547599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              inputSource,
1548599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              format,
1549599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              samplingRate,
1550599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              channelMask,
1551599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              flags,
1552599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                              uid,
15532f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                              isSoundTrigger,
15542f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                              policyMix, mpClientInterface);
1555599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1556232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent// TODO enable input reuse
1557232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent#if 0
1558599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    // reuse an open input if possible
1559599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1560599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
1561232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // reuse input if it shares the same profile and same sound trigger attribute
1562232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (profile == desc->mProfile &&
1563232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            isSoundTrigger == desc->isSoundTrigger()) {
1564599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1565599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            sp<AudioSession> as = desc->getAudioSession(session);
1566599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            if (as != 0) {
1567599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                // do not allow unmatching properties on same session
1568599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                if (as->matches(audioSession)) {
1569599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    as->changeOpenCount(1);
1570599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                } else {
1571599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    ALOGW("getInputForDevice() record with different attributes"
1572599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                          " exists for session %d", session);
1573232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                    return input;
1574fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                }
1575599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            } else {
1576599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                desc->addAudioSession(session, audioSession);
1577599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            }
1578232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            ALOGV("getInputForDevice() reusing input %d", mInputs.keyAt(i));
1579232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            return mInputs.keyAt(i);
1580599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        }
1581599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1582232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent#endif
1583599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1584cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1585f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    config.sample_rate = profileSamplingRate;
1586f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    config.channel_mask = profileChannelMask;
1587f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    config.format = profileFormat;
1588df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
1589322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
1590599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                                                   &input,
1591cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                   &config,
1592cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                   &device,
1593fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi                                                   address,
15941c9c2cc4b170b79a83433749808e286eb0fcc449Eric Laurent                                                   halInputSource,
1595f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                   profileFlags);
1596cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
1597cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    // only accept input with the exact requested set of parameters
1598599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
1599f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        (profileSamplingRate != config.sample_rate) ||
1600e693002b0fb25099540588245892ed98103749baEric Laurent        !audio_formats_match(profileFormat, config.format) ||
1601f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung        (profileChannelMask != config.channel_mask)) {
1602599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("getInputForAttr() failed opening input: samplingRate %d"
1603599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              ", format %d, channelMask %x",
1604cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                samplingRate, format, channelMask);
1605599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (input != AUDIO_IO_HANDLE_NONE) {
1606599c758b258cc5da0dba9b530425381facc37d77Eric Laurent            mpClientInterface->closeInput(input);
1607cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent        }
1608599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        return AUDIO_IO_HANDLE_NONE;
1609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16111f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
1612f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    inputDesc->mSamplingRate = profileSamplingRate;
1613f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    inputDesc->mFormat = profileFormat;
1614f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    inputDesc->mChannelMask = profileChannelMask;
1615cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent    inputDesc->mDevice = device;
1616c722f30eef03e77054395ae122470cf8dba93937Eric Laurent    inputDesc->mPolicyMix = policyMix;
1617599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    inputDesc->addAudioSession(session, audioSession);
1618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1619599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    addInput(input, inputDesc);
1620b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPortListUpdate();
1621466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1622599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    return input;
1623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16254dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::startInput(audio_io_handle_t input,
1626232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                                        audio_session_t session)
1627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("startInput() input %d", input);
1629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("startInput() unknown input %d", input);
1632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
16341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1636599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
1637599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession == 0) {
16384dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("startInput() unknown session %d on input %d", session, input);
16394dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return BAD_VALUE;
16404dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
16414dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
1642232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    // virtual input devices are compatible with other input devices
1643232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    if (!is_virtual_input_device(inputDesc->mDevice)) {
1644232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent
1645232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // for a non-virtual input device, check if there is another (non-virtual) active input
1646232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        audio_io_handle_t activeInput = mInputs.getActiveInput();
1647232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (activeInput != 0 && activeInput != input) {
1648232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent
1649232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
1650232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            // otherwise the active input continues and the new input cannot be started.
1651232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
1652232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            if ((activeDesc->inputSource() == AUDIO_SOURCE_HOTWORD) &&
1653232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                    !activeDesc->hasPreemptedSession(session)) {
1654232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
1655232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                //FIXME: consider all active sessions
1656232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
1657232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                audio_session_t activeSession = activeSessions.keyAt(0);
1658232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                SortedVector<audio_session_t> sessions =
1659232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                                           activeDesc->getPreemptedSessions();
1660232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                sessions.add(activeSession);
1661232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                inputDesc->setPreemptedSessions(sessions);
1662232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                stopInput(activeInput, activeSession);
1663232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                releaseInput(activeInput, activeSession);
1664232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            } else {
1665232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
1666232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                return INVALID_OPERATION;
1667232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            }
1668232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        }
1669c0a889f766953b657a5e997bc1362661806d3a19Eric Laurent
1670232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // Do not allow capture if an active voice call is using a software patch and
1671232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // the call TX source device is on the same HW module.
1672232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // FIXME: would be better to refine to only inputs whose profile connects to the
1673232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // call TX device but this information is not in the audio patch
1674232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (mCallTxPatch != 0 &&
1675232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
1676232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            return INVALID_OPERATION;
1677232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        }
1678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1679e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
16808c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // Routing?
16818c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    mInputRoutes.incRouteActivity(session);
16828c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
1683232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    if (!inputDesc->isActive() || mInputRoutes.hasRouteChanged(session)) {
1684232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // if input maps to a dynamic policy with an activity listener, notify of state change
1685232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if ((inputDesc->mPolicyMix != NULL)
1686232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
16877638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
1688232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                    MIX_STATE_MIXING);
1689232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        }
1690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1691271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // indicate active capture to sound trigger service if starting capture from a mic on
1692271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // primary HW module
1693271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        audio_devices_t device = getNewInputDevice(input);
1694271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
1695271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
1696271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent                mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
1697232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            SoundTrigger::setCaptureState(true);
1698232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        }
1699271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        setInputDevice(input, device, true /* force */);
1700fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent
1701232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // automatically enable the remote submix output when input is started if not
1702232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // used by a policy mix of type MIX_TYPE_RECORDERS
1703232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // For remote submix (a virtual device), we open only one input per capture request.
1704232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1705232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            String8 address = String8("");
1706232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            if (inputDesc->mPolicyMix == NULL) {
1707232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                address = String8("0");
1708232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
17097638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                address = inputDesc->mPolicyMix->mDeviceAddress;
1710fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            }
1711232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            if (address != "") {
1712232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1713232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1714232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                        address, "remote-submix");
1715c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
171674a8e2533561f04029873446206ab407cd2e033bGlenn Kasten        }
1717e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1719599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    ALOGV("AudioPolicyManager::startInput() input source = %d", audioSession->inputSource());
1720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1721232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    audioSession->changeActiveCount(1);
1722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
17254dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentstatus_t AudioPolicyManager::stopInput(audio_io_handle_t input,
17264dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent                                       audio_session_t session)
1727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("stopInput() input %d", input);
1729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1730e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1731e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() unknown input %d", input);
1732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1733e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
17341f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1735e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1736599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
17374dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    if (index < 0) {
17384dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("stopInput() unknown session %d on input %d", session, input);
17394dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return BAD_VALUE;
17404dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
17414dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
1742599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->activeCount() == 0) {
1743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("stopInput() input %d already stopped", input);
1744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
17456a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
17466a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten
1747599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    audioSession->changeActiveCount(-1);
1748466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1749466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Routing?
1750466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    mInputRoutes.decRouteActivity(session);
1751466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1752232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    if (!inputDesc->isActive()) {
1753232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // if input maps to a dynamic policy with an activity listener, notify of state change
1754232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if ((inputDesc->mPolicyMix != NULL)
1755232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
17567638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
1757232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                    MIX_STATE_IDLE);
1758232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        }
1759232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent
1760232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // automatically disable the remote submix output when input is stopped if not
1761232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        // used by a policy mix of type MIX_TYPE_RECORDERS
1762232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1763232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            String8 address = String8("");
1764232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            if (inputDesc->mPolicyMix == NULL) {
1765232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                address = String8("0");
1766232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
17677638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                address = inputDesc->mPolicyMix->mDeviceAddress;
1768c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
1769232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            if (address != "") {
1770232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1771232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                                         AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1772232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                                         address, "remote-submix");
1773c722f30eef03e77054395ae122470cf8dba93937Eric Laurent            }
1774232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        }
1775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1776271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        audio_devices_t device = inputDesc->mDevice;
1777232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        resetInputDevice(input);
1778df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
1779271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // indicate inactive capture to sound trigger service if stopping capture from a mic on
1780271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        // primary HW module
1781271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
1782271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent        if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
1783271a93e924f46ccaf3f76a8fc38685afea40d3eeEric Laurent                mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
1784232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent            SoundTrigger::setCaptureState(false);
1785df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        }
1786232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent        inputDesc->clearPreemptedSessions();
1787e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
17886a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    return NO_ERROR;
1789e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1790e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
17914dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurentvoid AudioPolicyManager::releaseInput(audio_io_handle_t input,
17924dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent                                      audio_session_t session)
1793e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
17942f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
1795e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() %d", input);
1796e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
1797e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
1798e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("releaseInput() releasing unknown input %d", input);
1799e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
1800e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1801466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
1802466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    // Routing
1803466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    mInputRoutes.removeRoute(session);
1804466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
18056a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
18066a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    ALOG_ASSERT(inputDesc != 0);
18074dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent
1808599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
18094dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    if (index < 0) {
18104dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        ALOGW("releaseInput() unknown session %d on input %d", session, input);
18114dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent        return;
18124dc680607181e6a76f4e91a39366c4f5dfb7b03eEric Laurent    }
1813599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1814599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->openCount() == 0) {
1815599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        ALOGW("releaseInput() invalid open count %d on session %d",
1816599c758b258cc5da0dba9b530425381facc37d77Eric Laurent              audioSession->openCount(), session);
18176a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        return;
18186a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
1819599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
1820599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    if (audioSession->changeOpenCount(-1) == 0) {
1821599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        inputDesc->removeAudioSession(session);
1822599c758b258cc5da0dba9b530425381facc37d77Eric Laurent    }
1823599c758b258cc5da0dba9b530425381facc37d77Eric Laurent
182465bfe916ca972b95f41d7f6cc2566c2e12a3eadaJean-Michel Trivi    if (inputDesc->getOpenRefCount() > 0) {
18256a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        ALOGV("releaseInput() exit > 0");
18266a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten        return;
18276a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten    }
18286a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten
182905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    closeInput(input);
1830b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPortListUpdate();
1831e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("releaseInput() exit");
1832e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1833e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1834d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurentvoid AudioPolicyManager::closeAllInputs() {
183505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    bool patchRemoved = false;
183605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
1837d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
183805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
18398c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
184005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        if (patch_index >= 0) {
184105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
1842fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten            (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
184305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            mAudioPatches.removeItemsAt(patch_index);
184405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent            patchRemoved = true;
184505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        }
1846d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        mpClientInterface->closeInput(mInputs.keyAt(input_index));
1847d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    }
1848d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    mInputs.clear();
184952785f3df24fe817af4f1c3c2cddfb30ab5450eeChris Thornton    SoundTrigger::setCaptureState(false);
18506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
185105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
185205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (patchRemoved) {
185305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
185405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
1855d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
1856d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
1857e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
1858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMin,
1859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            int indexMax)
1860e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1861e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
1862d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
186328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent
186428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // initialize other private stream volumes which follow this one
1865794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
1866794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
186728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
186828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
186928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
1870223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
1871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1873e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
187453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  int index,
187553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_devices_t device)
1876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1878d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if ((index < mVolumeCurves->getVolumeIndexMin(stream)) ||
1879d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            (index > mVolumeCurves->getVolumeIndexMax(stream))) {
1880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
1883e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1884e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1885e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1886e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Force max volume if stream cannot be muted
1887d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
1888e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
18891fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
1890e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          stream, device, index);
1891e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
189228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // update other private stream volumes which follow this one
1893794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
1894794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
189528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
189628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
189728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
1898223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
1899e04e62bc05316d9682688f87053be5cf47e9c707Eric Laurent
19001fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // update volume on all outputs and streams matching the following:
19011fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - The requested stream (or a stream matching for volume control) is active on the output
19021fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - The device (or devices) selected by the strategy corresponding to this stream includes
19031fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // the requested device
19041fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // - For non default requested device, currently selected device on the output is either the
19051fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent    // requested device or one of the devices selected by the strategy
19065a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
19075a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // no specific device volume value exists for currently selected device.
1908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    status_t status = NO_ERROR;
1909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
1910c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
1911c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
1912794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
1913794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
191428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                continue;
191528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            }
1916d3926fe68ffd8d156e7c019277bbeb32ca786d8eEric Laurent            if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
1917d3926fe68ffd8d156e7c019277bbeb32ca786d8eEric Laurent                    (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
19181fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                continue;
19191fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
1920794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
1921e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, false /*fromCache*/);
1922e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
1923e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                    ((curStreamDevice & device) == 0)) {
19241fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                continue;
19251fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
1926e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            bool applyVolume;
19275a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
19281fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent                curStreamDevice |= device;
1929e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                applyVolume = (curDevice & curStreamDevice) != 0;
1930e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            } else {
1931e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
1932e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent                        stream, Volume::getDeviceForVolume(curStreamDevice));
19331fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent            }
19341fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent
1935e76f29cbde016e2a5e76e308f946644adae10a17Eric Laurent            if (applyVolume) {
1936dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                //FIXME: workaround for truncated touch sounds
1937dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // delayed volume change for system stream to be removed when the problem is
1938dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // handled by system UI
193928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                status_t volStatus =
1940dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                        checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice,
1941dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                            (stream == AUDIO_STREAM_SYSTEM) ? TOUCH_SOUND_FIXED_DELAY_MS : 0);
194228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                if (volStatus != NO_ERROR) {
194328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                    status = volStatus;
194428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                }
1945e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
1946223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        }
1947e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1948e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return status;
1949e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1950e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1951e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
1952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      int *index,
1953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                      audio_devices_t device)
1954e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1955e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index == NULL) {
1956e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1958e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!audio_is_output_device(device)) {
1959e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return BAD_VALUE;
1960e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
19615a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
1962e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // the strategy the stream belongs to.
19635a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
1964e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
1965e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1966dfd7409c1b708f6c429aa43722ca8493a91d8df0François Gaffie    device = Volume::getDeviceForVolume(device);
1967e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1968d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    *index =  mVolumeCurves->getVolumeIndex(stream, device);
1969e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
1970e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
1971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
1972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1973e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::selectOutputForEffects(
1974e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            const SortedVector<audio_io_handle_t>& outputs)
1975e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
1976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // select one output among several suitable for global effects.
1977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // The priority is as follows:
1978e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 1: An offloaded output. If the effect ends up not being offloadable,
1979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    AudioFlinger will invalidate the track and the offloaded output
1980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //    will be closed causing the effect to be moved to a PCM output.
1981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: A deep buffer output
1982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 3: the first output in the list
1983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs.size() == 0) {
1985e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
1986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
1987e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1988e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputOffloaded = 0;
1989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t outputDeepBuffer = 0;
1990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
1991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs.size(); i++) {
1992c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
1993d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
1994e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputOffloaded = outputs[i];
1996e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
1997e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1998e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDeepBuffer = outputs[i];
1999e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2000e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2001e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2002e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
2003e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          outputOffloaded, outputDeepBuffer);
2004e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputOffloaded != 0) {
2005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputOffloaded;
2006e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2007e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDeepBuffer != 0) {
2008e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return outputDeepBuffer;
2009e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2010e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2011e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs[0];
2012e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2013e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2014e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
2015e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2016e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // apply simple rule where global effects are attached to the same output as MUSIC streams
2017e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
20183b73df74357b33869b39a1d69427673c780bd805Eric Laurent    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
2019e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
2020e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
2021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_io_handle_t output = selectOutputForEffects(dstOutputs);
2023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
2024e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent          output, (desc == NULL) ? "unspecified" : desc->name,  (desc == NULL) ? 0 : desc->flags);
2025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return output;
2027e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2028e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2029e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
2030e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                audio_io_handle_t io,
2031e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                uint32_t strategy,
2032e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int session,
2033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                int id)
2034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2035e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ssize_t index = mOutputs.indexOfKey(io);
2036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (index < 0) {
2037e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        index = mInputs.indexOfKey(io);
2038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (index < 0) {
2039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("registerEffect() unknown io %d", io);
2040e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return INVALID_OPERATION;
2041e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
204345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    return mEffects.registerEffect(desc, io, strategy, session, id);
2044e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2046c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
2047c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
204828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    bool active = false;
2049794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT && !active; curStream++) {
2050794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
205128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
205228d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
205328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs);
205428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    }
205528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    return active;
2056c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
2057c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
2058c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
2059c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
2060c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return mOutputs.isStreamActiveRemotely(stream, inPastMs);
2061c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
2062c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
2063e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isSourceActive(audio_source_t source) const
2064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2065e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
20661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent        const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
2067599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (inputDescriptor->isSourceActive(source)) {
2068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return true;
2069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2071e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
2072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2074275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// Register a list of custom mixes with their attributes and format.
2075275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a mix is registered, corresponding input and output profiles are
2076275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// added to the remote submix hw module. The profile contains only the
2077275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// parameters (sampling rate, format...) specified by the mix.
2078275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// The corresponding input remote submix device is also connected.
2079275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2080275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When a remote submix device is connected, the address is checked to select the
2081275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// appropriate profile and the corresponding input or output stream is opened.
2082275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2083275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When capture starts, getInputForAttr() will:
2084275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 1 look for a mix matching the address passed in attribtutes tags if any
2085275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 2 if none found, getDeviceForInputSource() will:
2086275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//     - 2.1 look for a mix matching the attributes source
2087275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//     - 2.2 if none found, default to device selection by policy rules
2088275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// At this time, the corresponding output remote submix device is also connected
2089275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// and active playback use cases can be transferred to this mix if needed when reconnecting
2090275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// after AudioTracks are invalidated
2091275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//
2092275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent// When playback starts, getOutputForAttr() will:
2093275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 1 look for a mix matching the address passed in attribtutes tags if any
2094275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 2 if none found, look for a mix matching the attributes usage
2095275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent//  - 3 if none found, default to device and output selection by policy rules.
2096275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2097275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes)
2098275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{
20997638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    ALOGV("registerPolicyMixes() %zu mix(es)", mixes.size());
21007638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    status_t res = NO_ERROR;
21017638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
21027638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    sp<HwModule> rSubmixModule;
21037638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    // examine each mix's route type
21047638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    for (size_t i = 0; i < mixes.size(); i++) {
21057638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        // we only support MIX_ROUTE_FLAG_LOOP_BACK or MIX_ROUTE_FLAG_RENDER, not the combination
21067638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_ALL) == MIX_ROUTE_FLAG_ALL) {
21077638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            res = INVALID_OPERATION;
2108275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            break;
2109275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
21107638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
21117638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // Loop back through "remote submix"
21127638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
21137638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                for (size_t j = 0; i < mHwModules.size(); j++) {
21147638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
21157638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                            && mHwModules[j]->mHandle != 0) {
21167638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        rSubmixModule = mHwModules[j];
21177638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        break;
21187638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
21197638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
21207638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2121275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
21227638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
2123275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
21247638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
21257638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                ALOGE(" Unable to find audio module for submix, aborting mix %zu registration", i);
21267638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
21277638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
21287638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2129275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
21307638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
2131036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
21327638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.registerMix(address, mixes[i], 0 /*output desc*/) != NO_ERROR) {
21335ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                ALOGE(" Error registering mix %zu for address %s", i, address.string());
21347638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
21357638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
21367638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
21377638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_config_t outputConfig = mixes[i].mFormat;
21387638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_config_t inputConfig = mixes[i].mFormat;
21397638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
21407638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            // stereo and let audio flinger do the channel conversion if needed.
21417638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
21427638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
21437638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->addOutputProfile(address, &outputConfig,
21447638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address);
21457638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->addInputProfile(address, &inputConfig,
21467638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
21477638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
21487638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
21497638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
21507638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
21517638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
21527638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            } else {
21537638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
21547638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
21557638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
21567638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
21577638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        } else if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
21587638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
21597638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            audio_devices_t device = mixes[i].mDeviceType;
21605ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            ALOGV(" registerPolicyMixes() mix %zu of %zu is RENDER, dev=0x%X addr=%s",
21615ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                    i, mixes.size(), device, address.string());
21627638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
21635ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            bool foundOutput = false;
21647638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            for (size_t j = 0 ; j < mOutputs.size() ; j++) {
21657638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(j);
21667638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                sp<AudioPatch> patch = mAudioPatches.valueFor(desc->getPatchHandle());
21677638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                if ((patch != 0) && (patch->mPatch.num_sinks != 0)
21687638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        && (patch->mPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE)
21697638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        && (patch->mPatch.sinks[0].ext.device.type == device)
21705ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        && (strncmp(patch->mPatch.sinks[0].ext.device.address, address.string(),
21715ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                                AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
21727638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (mPolicyMixes.registerMix(address, mixes[i], desc) != NO_ERROR) {
21737638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        res = INVALID_OPERATION;
21745ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                    } else {
21755ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        foundOutput = true;
21767638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
21777638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    break;
21787638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
21797638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
21807638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
21817638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (res != NO_ERROR) {
21827638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                ALOGE(" Error registering mix %zu for device 0x%X addr %s",
21835ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        i, device, address.string());
21845ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                res = INVALID_OPERATION;
21855ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                break;
21865ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi            } else if (!foundOutput) {
21875ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                ALOGE(" Output not found for mix %zu for device 0x%X addr %s",
21885ac8cd425e1a0c4287c0bb84f922fef4fa106411Jean-Michel Trivi                        i, device, address.string());
21897638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
21907638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                break;
21917638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2192c722f30eef03e77054395ae122470cf8dba93937Eric Laurent        }
2193275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
21947638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    if (res != NO_ERROR) {
21957638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        unregisterPolicyMixes(mixes);
21967638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    }
21977638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    return res;
2198275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent}
2199275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2200275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentstatus_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
2201275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent{
22027b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent    ALOGV("unregisterPolicyMixes() num mixes %zu", mixes.size());
22037638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    status_t res = NO_ERROR;
22047638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    sp<HwModule> rSubmixModule;
22057638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    // examine each mix's route type
2206275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    for (size_t i = 0; i < mixes.size(); i++) {
22077638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
22087638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
22097638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
22107638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                for (size_t j = 0; i < mHwModules.size(); j++) {
22117638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
22127638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                            && mHwModules[j]->mHandle != 0) {
22137638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        rSubmixModule = mHwModules[j];
22147638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        break;
22157638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    }
22167638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                }
22177638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
22187638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (rSubmixModule == 0) {
22197638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
22207638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
22217638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2222036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
22237638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            String8 address = mixes[i].mDeviceAddress;
2224275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
22257638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
22267638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
22277638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
22287638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2229275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
22307638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
22317638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
22327638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
22337638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
22347638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
22357638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
22367638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
22377638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
22387638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
22397638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
22407638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                        address.string(), "remote-submix");
22417638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
22427638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->removeOutputProfile(address);
22437638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            rSubmixModule->removeInputProfile(address);
22447638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi
22457638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi        } if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
22467638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            if (mPolicyMixes.unregisterMix(mixes[i].mDeviceAddress) != NO_ERROR) {
22477638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                res = INVALID_OPERATION;
22487638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi                continue;
22497638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            }
2250275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
2251275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
22527638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi    return res;
2253275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent}
2254275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
2255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2256e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::dump(int fd)
2257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    const size_t SIZE = 256;
2259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char buffer[SIZE];
2260e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    String8 result;
2261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2262e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
2263e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
2264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
226587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    snprintf(buffer, SIZE, " Primary Output: %d\n",
226687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent             hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
2267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22682110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Phone state: %d\n", mEngine->getPhoneState());
2269e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22703b73df74357b33869b39a1d69427673c780bd805Eric Laurent    snprintf(buffer, SIZE, " Force use for communications %d\n",
22712110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
2272e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22732110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
2274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22752110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
2276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22772110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
2278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22792110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
2280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    result.append(buffer);
22817b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang    snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
22822110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
22837b24ee381e806dcb53308c1cafc8a45f4e2d8300Jungshik Jang    result.append(buffer);
228409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    snprintf(buffer, SIZE, " Force use for encoded surround output %d\n",
228509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND));
228609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    result.append(buffer);
22879459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
22889459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    result.append(buffer);
22892ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
22902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    result.append(buffer);
22919459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
22922110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    write(fd, result.string(), result.size());
2293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2294112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    mAvailableOutputDevices.dump(fd, String8("Available output"));
2295112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    mAvailableInputDevices.dump(fd, String8("Available input"));
229653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mHwModules.dump(fd);
229753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mOutputs.dump(fd);
229853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mInputs.dump(fd);
2299d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->dump(fd);
230045ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    mEffects.dump(fd);
230153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mAudioPatches.dump(fd);
2302e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2303e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
2304e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This function checks for the parameters which can be offloaded.
2307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// This can be enhanced depending on the capability of the DSP and policy
2308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// of the system.
2309e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
2310e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
2311e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
2312d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent     " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
2313e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.sample_rate, offloadInfo.channel_mask,
2314e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.format,
2315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
2316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent     offloadInfo.has_video);
2317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
23182ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono) {
23192ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        return false; // no offloading if mono is set.
23202ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
23212ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
2322e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if offload has been disabled
2323e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    char propValue[PROPERTY_VALUE_MAX];
2324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.disable", propValue, "0")) {
2325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (atoi(propValue) != 0) {
2326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
2327e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2328e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2329e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Check if stream type is music, then only allow offload as of now.
2332e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
2333e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
2334e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
2335e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2336e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2338e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //TODO: enable audio offloading with video when ready
233908945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung    const bool allowOffloadWithVideo =
234008945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung            property_get_bool("audio.offload.video", false /* default_value */);
234108945c44a97d3749cc48f860eb4e01e57183ad90Andy Hung    if (offloadInfo.has_video && !allowOffloadWithVideo) {
2342e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("isOffloadSupported: has_video == true, returning false");
2343e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2344e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2346e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //If duration is less than minimum value defined in property, return false
2347e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
2348e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
2349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
2350e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
2351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
2352e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
2353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
2354e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2355e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2356e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2357e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
2358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // creating an offloaded track and tearing it down immediately after start when audioflinger
2359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // detects there is an active non offloadable effect.
2360e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // FIXME: We should check the audio session here but we do not have it in this context.
2361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // This may prevent offloading in rare situations where effects are left active by apps
2362e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the background.
236345ed3b053d9af2250f5ece9ee4e826905c3763a7François Gaffie    if (mEffects.isNonOffloadableEffectEnabled()) {
2364e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
2365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
2366e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
2367e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // See if there is a profile to support this.
2368e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // AUDIO_DEVICE_NONE
23691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
2370e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.sample_rate,
2371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.format,
2372e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            offloadInfo.channel_mask,
2373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
23741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
23751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return (profile != 0);
2376e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
2377e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
23786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
23796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            audio_port_type_t type,
23806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            unsigned int *num_ports,
23816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            struct audio_port *ports,
23826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            unsigned int *generation)
23836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
23846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
23856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            generation == NULL) {
23866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
23876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
23886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
23896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (ports == NULL) {
23906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        *num_ports = 0;
23916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
23926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
23936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    size_t portsWritten = 0;
23946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    size_t portsMax = *num_ports;
23956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *num_ports = 0;
23966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
23975a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
23985a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent        // as they are used by stub HALs by convention
23996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
24005a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
24015a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
24025a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    continue;
24035a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
24045a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (portsWritten < portsMax) {
24055a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
24065a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
24075a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                (*num_ports)++;
24086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
24096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
24106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
24115a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent            for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
24125a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
24135a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    continue;
24145a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
24155a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                if (portsWritten < portsMax) {
24165a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                    mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
24175a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                }
24185a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent                (*num_ports)++;
24196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
24206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
24216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
24226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
24236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
24246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
24256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                mInputs[i]->toAudioPort(&ports[portsWritten++]);
24266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
24276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            *num_ports += mInputs.size();
24286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
24296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
243084c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            size_t numOutputs = 0;
243184c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            for (size_t i = 0; i < mOutputs.size(); i++) {
243284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                if (!mOutputs[i]->isDuplicated()) {
243384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    numOutputs++;
243484c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    if (portsWritten < portsMax) {
243584c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        mOutputs[i]->toAudioPort(&ports[portsWritten++]);
243684c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                    }
243784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                }
24386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
243984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            *num_ports += numOutputs;
24406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
24416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
24426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *generation = curAudioPortGeneration();
2443beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn    ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
24446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
24456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
24466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
24476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
24486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
24496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
24506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
24516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
24526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
24536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               audio_patch_handle_t *handle,
24546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               uid_t uid)
24556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
24566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch()");
24576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
24586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (handle == NULL || patch == NULL) {
24596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
24606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
24616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
24626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
2463874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2464874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2465874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        return BAD_VALUE;
2466874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
2467874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    // only one source per audio patch supported for now
2468874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->num_sources > 1) {
24696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
24706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
2471874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2472874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
24736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
24746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
2475874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    for (size_t i = 0; i < patch->num_sinks; i++) {
2476874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2477874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            return INVALID_OPERATION;
2478874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        }
2479874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
24806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
24816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp<AudioPatch> patchDesc;
24826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index = mAudioPatches.indexOfKey(*handle);
24836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
24846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
24856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                           patch->sources[0].role,
24866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                           patch->sources[0].type);
2487874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#if LOG_NDEBUG == 0
2488874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    for (size_t i = 0; i < patch->num_sinks; i++) {
24897b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent        ALOGV("createAudioPatch sink %zu: id %d role %d type %d", i, patch->sinks[i].id,
2490874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                             patch->sinks[i].role,
2491874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                             patch->sinks[i].type);
2492874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent    }
2493874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent#endif
24946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
24956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
24966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        patchDesc = mAudioPatches.valueAt(index);
24976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
24986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  mUidCached, patchDesc->mUid, uid);
24996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
25006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
25016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
25026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
2503a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten        *handle = AUDIO_PATCH_HANDLE_NONE;
25046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
25056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
25066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
2507c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
25086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (outputDesc == NULL) {
25096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
25106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
25116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
251284c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent        ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
251384c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                                                outputDesc->mIoHandle);
25146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc != 0) {
25156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
25166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
25176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                          patchDesc->mPatch.sources[0].id, patch->sources[0].id);
25186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
25196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
25206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
2521874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        DeviceVector devices;
2522874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        for (size_t i = 0; i < patch->num_sinks; i++) {
2523874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // Only support mix to devices connection
2524874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // TODO add support for mix to mix connection
2525874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2526874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                ALOGV("createAudioPatch() source mix but sink is not a device");
2527874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2528874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
2529874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            sp<DeviceDescriptor> devDesc =
2530874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2531874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (devDesc == 0) {
2532874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2533874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return BAD_VALUE;
2534874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
25356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
253653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
2537275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                           devDesc->mAddress,
2538874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                                                           patch->sources[0].sample_rate,
253953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           NULL,  // updatedSamplingRate
254053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           patch->sources[0].format,
2541f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                           NULL,  // updatedFormat
254253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           patch->sources[0].channel_mask,
2543f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                           NULL,  // updatedChannelMask
254453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                           AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
2545f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                ALOGV("createAudioPatch() profile not supported for device %08x",
2546f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                        devDesc->type());
2547874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2548874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
2549874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            devices.add(devDesc);
2550874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        }
2551874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent        if (devices.size() == 0) {
25526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
25536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
2554874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
25556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        // TODO: reconfigure output format and channels here
25566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        ALOGV("createAudioPatch() setting device %08x on output %d",
2557874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent              devices.types(), outputDesc->mIoHandle);
2558c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        setOutputDevice(outputDesc, devices.types(), true, 0, handle);
25596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*handle);
25606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (index >= 0) {
25616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
25626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
25636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
25646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            patchDesc = mAudioPatches.valueAt(index);
25656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            patchDesc->mUid = uid;
25666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() success");
25676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
25686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
25696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return INVALID_OPERATION;
25706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
25716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
25726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
25736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // input device to input mix connection
2574874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            // only one sink supported when connecting an input device to a mix
2575874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            if (patch->num_sinks > 1) {
2576874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                return INVALID_OPERATION;
2577874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            }
257853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
25796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (inputDesc == NULL) {
25806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
25816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
25826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0) {
25836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
25846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    return BAD_VALUE;
25856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
25866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
25876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp<DeviceDescriptor> devDesc =
25886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
25896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (devDesc == 0) {
25906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
25916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
25926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
259353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
2594275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          devDesc->mAddress,
2595275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].sample_rate,
2596275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          NULL, /*updatedSampleRate*/
2597275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].format,
2598f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                          NULL, /*updatedFormat*/
2599275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          patch->sinks[0].channel_mask,
2600f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                          NULL, /*updatedChannelMask*/
2601275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          // FIXME for the parameter type,
2602275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          // and the NONE
2603275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                                          (audio_output_flags_t)
26046a8ab05f0598f4ebdd5ef82e93cf32fde0598189Glenn Kasten                                                            AUDIO_INPUT_FLAG_NONE)) {
26056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
26066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // TODO: reconfigure output format and channels here
26086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() setting device %08x on output %d",
260953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  devDesc->type(), inputDesc->mIoHandle);
261053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
26116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            index = mAudioPatches.indexOfKey(*handle);
26126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
26136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
26146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
26156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
26166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
26176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mUid = uid;
26186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("createAudioPatch() success");
26196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
26206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
26216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
26226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
26246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // device to device connection
26256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchDesc != 0) {
2626874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
26276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    return BAD_VALUE;
26286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
26296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp<DeviceDescriptor> srcDeviceDesc =
26316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
263258f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent            if (srcDeviceDesc == 0) {
263358f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent                return BAD_VALUE;
263458f8eb7ae0ee400585bce6682a7212575115e758Eric Laurent            }
2635874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
26366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            //update source and sink with our own data as the data passed in the patch may
26376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // be incomplete.
26386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            struct audio_patch newPatch = *patch;
26396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
2640874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2641874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent            for (size_t i = 0; i < patch->num_sinks; i++) {
2642874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2643874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    ALOGV("createAudioPatch() source device but one sink is not a device");
2644874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    return INVALID_OPERATION;
2645874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                }
2646874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
2647874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                sp<DeviceDescriptor> sinkDeviceDesc =
2648874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2649874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                if (sinkDeviceDesc == 0) {
2650874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    return BAD_VALUE;
2651874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                }
2652874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
2653874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent
26543bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // create a software bridge in PatchPanel if:
26553bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // - source and sink devices are on differnt HW modules OR
26563bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                // - audio HAL version is < 3.0
2657232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                if ((srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) ||
2658a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                        (srcDeviceDesc->mModule->getHalVersion() < AUDIO_DEVICE_API_VERSION_3_0)) {
26593bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                    // support only one sink device for now to simplify output selection logic
2660874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    if (patch->num_sinks > 1) {
266183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                        return INVALID_OPERATION;
266283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                    }
2663874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    SortedVector<audio_io_handle_t> outputs =
266453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                            getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
2665874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    // if the sink device is reachable via an opened output stream, request to go via
2666874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    // this output stream by adding a second source to the patch description
26678838a3895c365d443ee22e169ccf45956780c081Eric Laurent                    audio_io_handle_t output = selectOutput(outputs,
26688838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                            AUDIO_OUTPUT_FLAG_NONE,
26698838a3895c365d443ee22e169ccf45956780c081Eric Laurent                                                            AUDIO_FORMAT_INVALID);
2670874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    if (output != AUDIO_IO_HANDLE_NONE) {
2671874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2672874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        if (outputDesc->isDuplicated()) {
2673874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                            return INVALID_OPERATION;
2674874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        }
2675874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
26763bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                        newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
2677874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                        newPatch.num_sources = 2;
2678874c4287a4e49c59ac88767751dce00fcd3edb73Eric Laurent                    }
267983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                }
26806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            // TODO: check from routing capabilities in config file and other conflicting patches
26826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
26836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
26846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
26856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
26866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
26876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
26886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            status_t status = mpClientInterface->createAudioPatch(&newPatch,
26896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  &afPatchHandle,
26906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  0);
26916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
26926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  status, afPatchHandle);
26936a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (status == NO_ERROR) {
26946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
269598cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&newPatch, uid);
26966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
26976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
26986a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = newPatch;
26996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
27006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
27016a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                *handle = patchDesc->mHandle;
27026a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
2703b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
27046a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
27056a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
27066a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                status);
27076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return INVALID_OPERATION;
27086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27096a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
27106a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
27116a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27126a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
27136a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
27146a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27156a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
27166a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
27176a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27186a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
27196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                  uid_t uid)
27206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
27216a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("releaseAudioPatch() patch %d", handle);
27226a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27236a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index = mAudioPatches.indexOfKey(handle);
27246a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
27266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
27276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
27296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
27306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent          mUidCached, patchDesc->mUid, uid);
27316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
27326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return INVALID_OPERATION;
27336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    struct audio_patch *patch = &patchDesc->mPatch;
27366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    patchDesc->mUid = mUidCached;
27376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
2738c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
27396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (outputDesc == NULL) {
27406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
27416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
27426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
2744c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        setOutputDevice(outputDesc,
2745c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        getNewOutputDevice(outputDesc, true /*fromCache*/),
27466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       true,
27476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       0,
27486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                       NULL);
27496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
27506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
275153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
27526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (inputDesc == NULL) {
27536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
27546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                return BAD_VALUE;
27556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
27566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            setInputDevice(inputDesc->mIoHandle,
2757232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent                           getNewInputDevice(inputDesc->mIoHandle),
27586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                           true,
27596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                           NULL);
27606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
27616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
27626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
27636a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                              status, patchDesc->mAfPatchHandle);
27646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            removeAudioPatch(patchDesc->mHandle);
27656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            nextAudioPortGeneration();
2766b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent            mpClientInterface->onAudioPatchListUpdate();
27676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        } else {
27686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return BAD_VALUE;
27696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
27706a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
27716a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
27726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return NO_ERROR;
27746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
27756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
27766a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
27776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              struct audio_patch *patches,
27786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              unsigned int *generation)
27796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
278053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    if (generation == NULL) {
27816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return BAD_VALUE;
27826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
27836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    *generation = curAudioPortGeneration();
278453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return mAudioPatches.listAudioPatches(num_patches, patches);
27856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
27866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
2787e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
27886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
2789e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("setAudioPortConfig()");
2790e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
2791e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    if (config == NULL) {
2792e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        return BAD_VALUE;
2793e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
2794e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("setAudioPortConfig() on port handle %d", config->id);
2795e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    // Only support gain configuration for now
2796a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
2797a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        return INVALID_OPERATION;
2798e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
2799e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
2800a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    sp<AudioPortConfig> audioPortConfig;
2801e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    if (config->type == AUDIO_PORT_TYPE_MIX) {
2802e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
2803c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
2804e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            if (outputDesc == NULL) {
2805e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                return BAD_VALUE;
2806e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            }
280784c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent            ALOG_ASSERT(!outputDesc->isDuplicated(),
280884c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        "setAudioPortConfig() called on duplicated output %d",
280984c70244bfea51b3413a8d8ffbf74ca737436251Eric Laurent                        outputDesc->mIoHandle);
2810a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent            audioPortConfig = outputDesc;
2811e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
281253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(config->id);
2813e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            if (inputDesc == NULL) {
2814e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                return BAD_VALUE;
2815e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            }
2816a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent            audioPortConfig = inputDesc;
2817e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else {
2818e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
2819e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
2820e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
2821e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        sp<DeviceDescriptor> deviceDesc;
2822e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
2823e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
2824e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
2825e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
2826e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        } else {
2827e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
2828e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
2829e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        if (deviceDesc == NULL) {
2830e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent            return BAD_VALUE;
2831e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        }
2832a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig = deviceDesc;
2833e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    } else {
2834e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent        return BAD_VALUE;
2835e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
2836e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
2837a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    struct audio_port_config backupConfig;
2838a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
2839a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (status == NO_ERROR) {
2840a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        struct audio_port_config newConfig;
2841a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig->toAudioPortConfig(&newConfig, config);
2842a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
2843e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
2844a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent    if (status != NO_ERROR) {
2845a121f90f388343dc48793cbc7eb899aba42e7664Eric Laurent        audioPortConfig->applyAudioPortConfig(&backupConfig);
2846e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    }
2847e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
2848e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return status;
28496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
28506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28518c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::releaseResourcesForUid(uid_t uid)
28528c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
2853d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    clearAudioSources(uid);
28548c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    clearAudioPatches(uid);
28558c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    clearSessionRoutes(uid);
28568c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
28578c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
28586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentvoid AudioPolicyManager::clearAudioPatches(uid_t uid)
28596a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
28600add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {
28616a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
28626a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid == uid) {
28630add0fd07401c507a77b37868f46a2ae587c30dfEric Laurent            releaseAudioPatch(mAudioPatches.keyAt(i), uid);
28646a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
28656a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
28666a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
28676a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
28688c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
28698c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                                            audio_io_handle_t ouptutToSkip)
28708c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
28718c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
28728c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
28738c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t j = 0; j < mOutputs.size(); j++) {
28748c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (mOutputs.keyAt(j) == ouptutToSkip) {
28758c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            continue;
28768c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
28778c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
28788c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
28798c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            continue;
28808c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
28818c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // If the default device for this strategy is on another output mix,
28828c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // invalidate all tracks in this strategy to force re connection.
28838c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        // Otherwise select new device on the output mix.
28848c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
2885794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
28868c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                if (getStrategy((audio_stream_type_t)stream) == strategy) {
28878c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                    mpClientInterface->invalidateStream((audio_stream_type_t)stream);
28888c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                }
28898c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
28908c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        } else {
28918c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
28928c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            setOutputDevice(outputDesc, newDevice, false);
28938c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
28948c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
28958c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
28968c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
28978c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurentvoid AudioPolicyManager::clearSessionRoutes(uid_t uid)
28988c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent{
28998c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // remove output routes associated with this uid
29008c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<routing_strategy> affectedStrategies;
29018c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (ssize_t i = (ssize_t)mOutputRoutes.size() - 1; i >= 0; i--)  {
29028c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SessionRoute> route = mOutputRoutes.valueAt(i);
29038c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (route->mUid == uid) {
29048c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mOutputRoutes.removeItemsAt(i);
29058c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            if (route->mDeviceDescriptor != 0) {
29068c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                affectedStrategies.add(getStrategy(route->mStreamType));
29078c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
29088c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
29098c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
29108c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // reroute outputs if necessary
29118c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < affectedStrategies.size(); i++) {
29128c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        checkStrategyRoute(affectedStrategies[i], AUDIO_IO_HANDLE_NONE);
29138c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
29148c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
29158c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // remove input routes associated with this uid
29168c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_source_t> affectedSources;
29178c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (ssize_t i = (ssize_t)mInputRoutes.size() - 1; i >= 0; i--)  {
29188c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<SessionRoute> route = mInputRoutes.valueAt(i);
29198c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        if (route->mUid == uid) {
29208c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mInputRoutes.removeItemsAt(i);
29218c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            if (route->mDeviceDescriptor != 0) {
29228c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                affectedSources.add(route->mSource);
29238c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            }
29248c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
29258c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
29268c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    // reroute inputs if necessary
29278c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    SortedVector<audio_io_handle_t> inputsToClose;
29288c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
29298c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
2930599c758b258cc5da0dba9b530425381facc37d77Eric Laurent        if (affectedSources.indexOf(inputDesc->inputSource()) >= 0) {
29318c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            inputsToClose.add(inputDesc->mIoHandle);
29328c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        }
29338c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
29348c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    for (size_t i = 0; i < inputsToClose.size(); i++) {
29358c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent        closeInput(inputsToClose[i]);
29368c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent    }
29378c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent}
29388c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
2939d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid AudioPolicyManager::clearAudioSources(uid_t uid)
2940d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
2941d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
2942d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
2943d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceDesc->mUid == uid) {
2944d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            stopAudioSource(mAudioSources.keyAt(i));
2945d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
2946d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
2947d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
29488c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent
2949df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
2950df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                                       audio_io_handle_t *ioHandle,
2951df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                                       audio_devices_t *device)
2952df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{
2953eeecb980ff4c202d0a3c4b0bfe040dce2f73336dGlenn Kasten    *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
2954eeecb980ff4c202d0a3c4b0bfe040dce2f73336dGlenn Kasten    *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
2955c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
2956df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
2957df37269852ea92bafd939fe793209d0581c4a574François Gaffie    return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
2958df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent}
2959df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
2960d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
2961d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  const audio_attributes_t *attributes,
2962d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  audio_io_handle_t *handle,
2963d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                  uid_t uid)
2964554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent{
2965d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s source %p attributes %p handle %p", __FUNCTION__, source, attributes, handle);
2966d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (source == NULL || attributes == NULL || handle == NULL) {
2967d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
2968d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
2969d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
2970d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    *handle = AUDIO_IO_HANDLE_NONE;
2971d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
2972d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (source->role != AUDIO_PORT_ROLE_SOURCE ||
2973d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            source->type != AUDIO_PORT_TYPE_DEVICE) {
2974d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s INVALID_OPERATION source->role %d source->type %d", __FUNCTION__, source->role, source->type);
2975d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return INVALID_OPERATION;
2976d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
2977d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
2978d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> srcDeviceDesc =
2979d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mAvailableInputDevices.getDevice(source->ext.device.type,
2980d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                              String8(source->ext.device.address));
2981d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (srcDeviceDesc == 0) {
2982d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
2983d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
2984d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
2985d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> sourceDesc =
2986d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            new AudioSourceDescriptor(srcDeviceDesc, attributes, uid);
2987d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
2988d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    struct audio_patch dummyPatch;
2989d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
2990d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sourceDesc->mPatchDesc = patchDesc;
2991d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
2992d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    status_t status = connectAudioSource(sourceDesc);
2993d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (status == NO_ERROR) {
2994d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        mAudioSources.add(sourceDesc->getHandle(), sourceDesc);
2995d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        *handle = sourceDesc->getHandle();
2996d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
2997d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return status;
2998d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
2999d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3000d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3001d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3002d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3003d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3004d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    // make sure we only have one patch per source.
3005d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    disconnectAudioSource(sourceDesc);
3006d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3007d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
300828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
3009d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
3010d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3011d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
3012d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<DeviceDescriptor> sinkDeviceDesc =
3013d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mAvailableOutputDevices.getDevice(sinkDevice, String8(""));
3014d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3015d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
3016d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    struct audio_patch *patch = &sourceDesc->mPatchDesc->mPatch;
3017d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3018d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
3019d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
3020a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            srcDeviceDesc->getAudioPort()->mModule->getHalVersion() >= AUDIO_DEVICE_API_VERSION_3_0 &&
3021d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
3022d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
3023d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        //   create patch between src device and output device
3024d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        //   create Hwoutput and add to mHwOutputs
3025d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    } else {
3026d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
3027d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        audio_io_handle_t output =
3028d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
3029d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (output == AUDIO_IO_HANDLE_NONE) {
3030d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
3031d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3032d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3033d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
3034d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (outputDesc->isDuplicated()) {
3035d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s output for device %08x is duplicated", __FUNCTION__, sinkDevice);
3036d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3037d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3038d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // create a special patch with no sink and two sources:
3039d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // - the second source indicates to PatchPanel through which output mix this patch should
3040d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // be connected as well as the stream type for volume control
3041d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // - the sink is defined by whatever output device is currently selected for the output
3042d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        // though which this patch is routed.
3043d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->num_sinks = 0;
3044d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->num_sources = 2;
3045d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        srcDeviceDesc->toAudioPortConfig(&patch->sources[0], NULL);
3046d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        outputDesc->toAudioPortConfig(&patch->sources[1], NULL);
3047d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        patch->sources[1].ext.mix.usecase.stream = stream;
3048d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        status_t status = mpClientInterface->createAudioPatch(patch,
3049d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              &afPatchHandle,
3050d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              0);
3051d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
3052d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                              status, afPatchHandle);
3053d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (status != NO_ERROR) {
3054d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGW("%s patch panel could not connect device patch, error %d",
3055d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                  __FUNCTION__, status);
3056d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return INVALID_OPERATION;
3057d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3058d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        uint32_t delayMs = 0;
3059c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
3060d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3061d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (status != NO_ERROR) {
3062d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
3063d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return status;
3064d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3065d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sourceDesc->mSwOutput = outputDesc;
3066d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (delayMs != 0) {
3067d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            usleep(delayMs * 1000);
3068d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3069d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3070d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3071d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sourceDesc->mPatchDesc->mAfPatchHandle = afPatchHandle;
3072d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    addAudioPatch(sourceDesc->mPatchDesc->mHandle, sourceDesc->mPatchDesc);
3073d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3074d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
3075554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent}
3076554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent
3077493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurentstatus_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle __unused)
3078554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent{
3079d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
3080d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, handle);
3081d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (sourceDesc == 0) {
3082d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGW("%s unknown source for handle %d", __FUNCTION__, handle);
3083d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3084d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3085d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    status_t status = disconnectAudioSource(sourceDesc);
3086d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3087d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    mAudioSources.removeItem(handle);
3088d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return status;
3089d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3090d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
30912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hungstatus_t AudioPolicyManager::setMasterMono(bool mono)
30922ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung{
30932ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono == mono) {
30942ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        return NO_ERROR;
30952ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
30962ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mMasterMono = mono;
30972ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // if enabling mono we close all offloaded devices, which will invalidate the
30982ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // corresponding AudioTrack. The AudioTrack client/MediaPlayer is responsible
30992ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // for recreating the new AudioTrack as non-offloaded PCM.
31002ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    //
31012ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // If disabling mono, we leave all tracks as is: we don't know which clients
31022ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // and tracks are able to be recreated as offloaded. The next "song" should
31032ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // play back offloaded.
31042ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    if (mMasterMono) {
31052ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        Vector<audio_io_handle_t> offloaded;
31062ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        for (size_t i = 0; i < mOutputs.size(); ++i) {
31072ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
31082ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            if (desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
31092ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung                offloaded.push(desc->mIoHandle);
31102ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            }
31112ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        }
31122ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        for (size_t i = 0; i < offloaded.size(); ++i) {
31132ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung            closeOutput(offloaded[i]);
31142ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        }
31152ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
31162ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    // update master mono for all remaining outputs
31172ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    for (size_t i = 0; i < mOutputs.size(); ++i) {
31182ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung        updateMono(mOutputs.keyAt(i));
31192ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    }
31202ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    return NO_ERROR;
31212ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung}
31222ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
31232ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hungstatus_t AudioPolicyManager::getMasterMono(bool *mono)
31242ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung{
31252ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    *mono = mMasterMono;
31262ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    return NO_ERROR;
31272ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung}
31282ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung
3129d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3130d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3131d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3132d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3133d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->mPatchDesc->mHandle);
3134d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (patchDesc == 0) {
3135d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        ALOGW("%s source has no patch with handle %d", __FUNCTION__,
3136d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent              sourceDesc->mPatchDesc->mHandle);
3137d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        return BAD_VALUE;
3138d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3139d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
3140d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
314128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
3142d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
3143d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (swOutputDesc != 0) {
3144d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        stopSource(swOutputDesc, stream, false);
3145d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3146d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    } else {
3147d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->mHwOutput.promote();
3148d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (hwOutputDesc != 0) {
3149d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent          //   release patch between src device and output device
3150d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent          //   close Hwoutput and remove from mHwOutputs
3151d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        } else {
3152d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGW("%s source has neither SW nor HW output", __FUNCTION__);
3153d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3154d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3155d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
3156d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
3157d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
3158d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentsp<AudioSourceDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
3159d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        audio_io_handle_t output, routing_strategy strategy)
3160d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
3161d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    sp<AudioSourceDescriptor> source;
3162d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (size_t i = 0; i < mAudioSources.size(); i++)  {
3163d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3164d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        routing_strategy sourceStrategy =
3165d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
3166d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->mSwOutput.promote();
3167d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
3168d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            source = sourceDesc;
3169d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            break;
3170d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
3171d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
3172d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return source;
3173554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent}
3174554a277d4e42a3d3df3d90ba0e7dfa2d31690e32Eric Laurent
3175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
3176e07208765fcd5904165e425ec714a25c350a2f40Eric Laurent// AudioPolicyManager
3177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ----------------------------------------------------------------------------
31786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentuint32_t AudioPolicyManager::nextAudioPortGeneration()
31796a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent{
31806a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    return android_atomic_inc(&mAudioPortGeneration);
31816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent}
31826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
3183e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
3184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    :
3185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    Thread(false),
3187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
31893a4311c68348f728558e87b5db67d47605783890Eric Laurent    mA2dpSuspended(false),
3190d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mAudioPortGeneration(1),
3191d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mBeaconMuteRefCount(0),
3192d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    mBeaconPlayingRefCount(0),
31939459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    mBeaconMuted(false),
31942ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mTtsOutputAvailable(false),
31952ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    mMasterMono(false)
3196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
31976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    mUidCached = getuid();
3198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface = clientInterface;
3199e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3200d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
3201d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
3202d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Note: remove also speaker_drc_enabled from global configuration of XML config file.
3203d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    bool speakerDrcEnabled = false;
3204a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
3205f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#ifdef USE_XML_AUDIO_POLICY_CONF
3206d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves = new VolumeCurvesCollection();
3207d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3208d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                             mDefaultOutputDevice, speakerDrcEnabled,
3209d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
3210f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie    PolicySerializer serializer;
3211f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie    if (serializer.deserialize(AUDIO_POLICY_XML_CONFIG_FILE, config) != NO_ERROR) {
3212f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#else
3213d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves = new StreamDescriptorCollection();
3214d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3215d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                             mDefaultOutputDevice, speakerDrcEnabled);
3216a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
3217f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
3218f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#endif
3219a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        ALOGE("could not load audio policy configuration file, setting defaults");
3220a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        config.setDefault();
3221e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
32222110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
3223d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
3224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3225d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
3226d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
3227d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (!engineInstance) {
3228d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
3229d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        return;
3230d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
3231d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // Retrieve the Policy Manager Interface
3232d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
3233d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    if (mEngine == NULL) {
3234d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
3235d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie        return;
3236d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    }
3237d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    mEngine->setObserver(this);
3238d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    status_t status = mEngine->initCheck();
3239fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten    (void) status;
3240d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
3241d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie
3242d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
3243e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // open all output streams needed to access attached devices
32443a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
32453a4311c68348f728558e87b5db67d47605783890Eric Laurent    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
3246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++) {
3247a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
3248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
3249a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            ALOGW("could not open HW module %s", mHwModules[i]->getName());
3250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
3251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3252e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open all output streams needed to access attached devices
3253e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // except for direct output streams that are only opened when they are actually
3254e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // required by an app.
32553a4311c68348f728558e87b5db67d47605783890Eric Laurent        // This also validates mAvailableOutputDevices list
3256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
32581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
3259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3260a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!outProfile->hasSupportedDevices()) {
3261a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
32623a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
32633a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
3264a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
32659459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent                mTtsOutputAvailable = true;
32669459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent            }
32673a4311c68348f728558e87b5db67d47605783890Eric Laurent
3268a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
3269d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
3270d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
3271a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            audio_devices_t profileType = outProfile->getSupportedDevicesType();
327253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
327353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                profileType = mDefaultOutputDevice->type();
327483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            } else {
3275a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                // chose first device present in profile's SupportedDevices also part of
3276d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                // outputDeviceTypes
3277a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
3278d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
3279d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if ((profileType & outputDeviceTypes) == 0) {
3280d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
3281d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
3282c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
3283c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                                 mpClientInterface);
3284c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
3285c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
3286c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
3287c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                    : String8("");
3288d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3289d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            outputDesc->mDevice = profileType;
3290d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3291d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.sample_rate = outputDesc->mSamplingRate;
3292d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.channel_mask = outputDesc->mChannelMask;
3293d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.format = outputDesc->mFormat;
3294d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3295322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
3296d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &output,
3297d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &config,
3298d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &outputDesc->mDevice,
3299c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                                            address,
3300d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            &outputDesc->mLatency,
3301d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                            outputDesc->mFlags);
3302d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3303d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if (status != NO_ERROR) {
3304d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                ALOGW("Cannot open output stream for device %08x on hw module %s",
3305d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                      outputDesc->mDevice,
3306a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                      mHwModules[i]->getName());
3307d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            } else {
3308d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                outputDesc->mSamplingRate = config.sample_rate;
3309d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                outputDesc->mChannelMask = config.channel_mask;
3310d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                outputDesc->mFormat = config.format;
3311d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3312a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                for (size_t k = 0; k  < supportedDevices.size(); k++) {
3313a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                    ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
3314d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                    // give a valid ID to an attached device once confirmed it is reachable
3315e743a47f445f02a0612018fa5640301304844fbfPaul McLean                    if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
3316e743a47f445f02a0612018fa5640301304844fbfPaul McLean                        mAvailableOutputDevices[index]->attach(mHwModules[i]);
3317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3319d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                if (mPrimaryOutput == 0 &&
3320a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                        outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
3321c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mPrimaryOutput = outputDesc;
3322d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                }
3323d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                addOutput(output, outputDesc);
3324c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setOutputDevice(outputDesc,
3325d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                outputDesc->mDevice,
3326c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                true,
3327c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                0,
3328c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                NULL,
3329c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent                                address.string());
3330e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3331e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
33323a4311c68348f728558e87b5db67d47605783890Eric Laurent        // open input streams needed to access attached devices to validate
33333a4311c68348f728558e87b5db67d47605783890Eric Laurent        // mAvailableInputDevices list
33343a4311c68348f728558e87b5db67d47605783890Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
33353a4311c68348f728558e87b5db67d47605783890Eric Laurent        {
33361c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
33373a4311c68348f728558e87b5db67d47605783890Eric Laurent
3338a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!inProfile->hasSupportedDevices()) {
3339a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
33403a4311c68348f728558e87b5db67d47605783890Eric Laurent                continue;
33413a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
3342a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            // chose first device present in profile's SupportedDevices also part of
3343d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            // inputDeviceTypes
3344a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
3345a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
3346d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if ((profileType & inputDeviceTypes) == 0) {
3347d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                continue;
3348d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            }
33492f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi            sp<AudioInputDescriptor> inputDesc =
33502f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    new AudioInputDescriptor(inProfile);
3351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3352d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            inputDesc->mDevice = profileType;
3353d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3354fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            // find the address
3355fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
3356fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            //   the inputs vector must be of size 1, but we don't want to crash here
3357fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
3358fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi                    : String8("");
3359fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            ALOGV("  for input device 0x%x using address %s", profileType, address.string());
3360fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi            ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
3361fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi
3362d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3363d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.sample_rate = inputDesc->mSamplingRate;
3364d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.channel_mask = inputDesc->mChannelMask;
3365d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            config.format = inputDesc->mFormat;
3366d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
3367322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
3368d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           &input,
3369d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           &config,
3370d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           &inputDesc->mDevice,
3371fd4c14883b268a0bc5514da135fe6b7d1ce2071bJean-Michel Trivi                                                           address,
3372d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           AUDIO_SOURCE_MIC,
3373d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                                                           AUDIO_INPUT_FLAG_NONE);
3374d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent
3375d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            if (status == NO_ERROR) {
3376a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
3377a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                for (size_t k = 0; k  < supportedDevices.size(); k++) {
3378a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                    ssize_t index =  mAvailableInputDevices.indexOf(supportedDevices[k]);
3379d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                    // give a valid ID to an attached device once confirmed it is reachable
338045aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                    if (index >= 0) {
338145aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
338245aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        if (!devDesc->isAttached()) {
338345aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                            devDesc->attach(mHwModules[i]);
338445aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                            devDesc->importAudioPort(inProfile);
338545aabc3578f2362b82f5a425d44e75d4266b1c8cEric Laurent                        }
33863a4311c68348f728558e87b5db67d47605783890Eric Laurent                    }
33873a4311c68348f728558e87b5db67d47605783890Eric Laurent                }
3388d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                mpClientInterface->closeInput(input);
3389d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent            } else {
3390d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                ALOGW("Cannot open input stream for device %08x on hw module %s",
3391d78f153a21868d870b14169a6928d991e4b82e73Eric Laurent                      inputDesc->mDevice,
3392a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                      mHwModules[i]->getName());
33933a4311c68348f728558e87b5db67d47605783890Eric Laurent            }
33943a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
33953a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
33963a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure all attached devices have been allocated a unique ID
33973a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
3398e743a47f445f02a0612018fa5640301304844fbfPaul McLean        if (!mAvailableOutputDevices[i]->isAttached()) {
3399a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
34003a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
34013a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
34023a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
34032110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        // The device is now validated and can be appended to the available devices of the engine
34042110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
34052110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
34063a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
34073a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
34083a4311c68348f728558e87b5db67d47605783890Eric Laurent    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
3409e743a47f445f02a0612018fa5640301304844fbfPaul McLean        if (!mAvailableInputDevices[i]->isAttached()) {
341053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
34113a4311c68348f728558e87b5db67d47605783890Eric Laurent            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
34123a4311c68348f728558e87b5db67d47605783890Eric Laurent            continue;
34133a4311c68348f728558e87b5db67d47605783890Eric Laurent        }
34142110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        // The device is now validated and can be appended to the available devices of the engine
34152110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
34162110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
34173a4311c68348f728558e87b5db67d47605783890Eric Laurent        i++;
34183a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
34193a4311c68348f728558e87b5db67d47605783890Eric Laurent    // make sure default device is reachable
3420a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
342153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
34223a4311c68348f728558e87b5db67d47605783890Eric Laurent    }
3423e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3424e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
3425e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3426e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    updateDevicesAndOutputs();
3427e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3428e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3429e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mPrimaryOutput != 0) {
3430e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter outputCmd = AudioParameter();
3431e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputCmd.addInt(String8("set_id"), 0);
3432c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString());
3433e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3434e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
3435e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestSamplingRate = 44100;
34363b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
34373b73df74357b33869b39a1d69427673c780bd805Eric Laurent        mTestChannels =  AUDIO_CHANNEL_OUT_STEREO;
3438e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mTestLatencyMs = 0;
3439e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mCurOutput = 0;
3440e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDirectOutput = false;
3441e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
3442e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mTestOutputs[i] = 0;
3443e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3444e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        const size_t SIZE = 256;
3446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        char buffer[SIZE];
3447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
3448e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        run(buffer, ANDROID_PRIORITY_AUDIO);
3449e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3450e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3451e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3453e07208765fcd5904165e425ec714a25c350a2f40Eric LaurentAudioPolicyManager::~AudioPolicyManager()
3454e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3455e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3456e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    exit();
3457e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3458e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mOutputs.size(); i++) {
3459e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeOutput(mOutputs.keyAt(i));
3460e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
3461e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   for (size_t i = 0; i < mInputs.size(); i++) {
3462e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mpClientInterface->closeInput(mInputs.keyAt(i));
3463e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent   }
34643a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableOutputDevices.clear();
34653a4311c68348f728558e87b5db67d47605783890Eric Laurent   mAvailableInputDevices.clear();
34661f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mOutputs.clear();
34671f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mInputs.clear();
34681f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent   mHwModules.clear();
3469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3471e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::initCheck()
3472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
347387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
3474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#ifdef AUDIO_POLICY_TEST
3477e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::threadLoop()
3478e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3479e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("entering threadLoop()");
3480e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    while (!exitPending())
3481e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
3482e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 command;
3483e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        int valueInt;
3484e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        String8 value;
3485e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3486e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        Mutex::Autolock _l(mLock);
3487e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
3488e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3489e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
3490e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AudioParameter param = AudioParameter(command);
3491e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3492e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
3493e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            valueInt != 0) {
3494e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("Test command %s received", command.string());
3495e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            String8 target;
3496e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("target"), target) != NO_ERROR) {
3497e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                target = "Manager";
3498e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3499e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
3500e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_output"));
3501e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mCurOutput = valueInt;
3502e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3503e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
3504e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_direct"));
3505e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "false") {
3506e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = false;
3507e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "true") {
3508e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mDirectOutput = true;
3509e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3510e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3511e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
3512e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_input"));
3513e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mTestInput = valueInt;
3514e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3515e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3516e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
3517e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_format"));
35183b73df74357b33869b39a1d69427673c780bd805Eric Laurent                int format = AUDIO_FORMAT_INVALID;
3519e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "PCM 16 bits") {
35203b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_16_BIT;
3521e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "PCM 8 bits") {
35223b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_PCM_8_BIT;
3523e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Compressed MP3") {
35243b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    format = AUDIO_FORMAT_MP3;
3525e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
35263b73df74357b33869b39a1d69427673c780bd805Eric Laurent                if (format != AUDIO_FORMAT_INVALID) {
3527e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
3528e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestFormat = format;
3529e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
3530e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
3531e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("format"), format);
3532e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3533e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3534e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3535e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3536e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
3537e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_channels"));
3538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int channels = 0;
3539e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3540e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (value == "Channels Stereo") {
35413b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_STEREO;
3542e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else if (value == "Channels Mono") {
35433b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    channels =  AUDIO_CHANNEL_OUT_MONO;
3544e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3545e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (channels != 0) {
3546e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
3547e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestChannels = channels;
3548e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
3549e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
3550e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("channels"), channels);
3551e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3552e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3553e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
3556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_sampleRate"));
3557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (valueInt >= 0 && valueInt <= 96000) {
3558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    int samplingRate = valueInt;
3559e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    if (target == "Manager") {
3560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mTestSamplingRate = samplingRate;
3561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    } else if (mTestOutputs[mCurOutput] != 0) {
3562e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        AudioParameter outputParam = AudioParameter();
3563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        outputParam.addInt(String8("sampling_rate"), samplingRate);
3564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
3570e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                param.remove(String8("test_cmd_policy_reopen"));
3571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3572c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                mpClientInterface->closeOutput(mpClientInterface->closeOutput(mPrimaryOutput););
3573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3574c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_module_handle_t moduleHandle = mPrimaryOutput->getModuleHandle();
3575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3576c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                removeOutput(mPrimaryOutput->mIoHandle);
3577c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                sp<SwAudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL,
3578c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                               mpClientInterface);
3579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
3580cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3581cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                config.sample_rate = outputDesc->mSamplingRate;
3582cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                config.channel_mask = outputDesc->mChannelMask;
3583cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                config.format = outputDesc->mFormat;
3584c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                audio_io_handle_t handle;
3585cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                status_t status = mpClientInterface->openOutput(moduleHandle,
3586c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                &handle,
3587cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                &config,
3588cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                &outputDesc->mDevice,
3589cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                String8(""),
3590cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                &outputDesc->mLatency,
3591cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                                outputDesc->mFlags);
3592cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                if (status != NO_ERROR) {
3593cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    ALOGE("Failed to reopen hardware output stream, "
3594cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        "samplingRate: %d, format %d, channels %d",
3595cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
3596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
3597cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    outputDesc->mSamplingRate = config.sample_rate;
3598cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    outputDesc->mChannelMask = config.channel_mask;
3599cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    outputDesc->mFormat = config.format;
3600c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mPrimaryOutput = outputDesc;
3601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    AudioParameter outputCmd = AudioParameter();
3602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    outputCmd.addInt(String8("set_id"), 0);
3603c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    mpClientInterface->setParameters(handle, outputCmd.toString());
3604c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    addOutput(handle, outputDesc);
3605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3606e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3607e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3608e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3609e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
3610e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3611e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3612e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return false;
3613e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3614e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3615e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::exit()
3616e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3617e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
3618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        AutoMutex _l(mLock);
3619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        requestExit();
3620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mWaitWorkCV.signal();
3621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    requestExitAndWait();
3623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3625e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentint AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
3626e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
3627e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
3628e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (output == mTestOutputs[i]) return i;
3629e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3630e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
3631e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3632e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent#endif //AUDIO_POLICY_TEST
3633e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3634e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent// ---
3635e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3636c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyManager::addOutput(audio_io_handle_t output, sp<SwAudioOutputDescriptor> outputDesc)
3637e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
363898cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie    outputDesc->setIoHandle(output);
36391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mOutputs.add(output, outputDesc);
36402ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung    updateMono(output); // update mono status when adding to output list
36416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
3642e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3643e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
364453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffievoid AudioPolicyManager::removeOutput(audio_io_handle_t output)
364553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
364653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    mOutputs.removeItem(output);
364753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
364853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
36491f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentvoid AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc)
3650d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
365198cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie    inputDesc->setIoHandle(input);
36521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mInputs.add(input, inputDesc);
36536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
3654d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
3655e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3656c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyManager::findIoHandlesByAddress(sp<SwAudioOutputDescriptor> desc /*in*/,
36573190e67d5c80c1e39e3be91784110af1180cd182keunyoung        const audio_devices_t device /*in*/,
36580fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi        const String8 address /*in*/,
36590fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi        SortedVector<audio_io_handle_t>& outputs /*out*/) {
36603190e67d5c80c1e39e3be91784110af1180cd182keunyoung    sp<DeviceDescriptor> devDesc =
3661a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        desc->mProfile->getSupportedDeviceByAddress(device, address);
36623190e67d5c80c1e39e3be91784110af1180cd182keunyoung    if (devDesc != 0) {
36633190e67d5c80c1e39e3be91784110af1180cd182keunyoung        ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
36643190e67d5c80c1e39e3be91784110af1180cd182keunyoung              desc->mIoHandle, address.string());
36653190e67d5c80c1e39e3be91784110af1180cd182keunyoung        outputs.add(desc->mIoHandle);
36660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi    }
36670fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi}
36680fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi
3669f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivistatus_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc,
367053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   audio_policy_dev_state_t state,
367153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   SortedVector<audio_io_handle_t>& outputs,
367253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   const String8 address)
3673e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
367453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_devices_t device = devDesc->type();
3675c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> desc;
3676cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
3677cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    if (audio_device_is_digital(device)) {
3678cc750d3604b33a92374253b12dd739dc06440aadEric Laurent        // erase all current sample rates, formats and channel masks
367920eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        devDesc->clearAudioProfiles();
3680cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    }
3681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
36823b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
3683e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // first list already open outputs that can be routed to this device
3684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
3685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
3686c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
368753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (!device_distinguishes_on_address(device)) {
36880fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
36890fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    outputs.add(mOutputs.keyAt(i));
36900fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                } else {
36910fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("  checking address match due to device 0x%x", device);
36923190e67d5c80c1e39e3be91784110af1180cd182keunyoung                    findIoHandlesByAddress(desc, device, address, outputs);
36930fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
3694e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3696e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // then look for output profiles that can be routed to this device
36971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
3698e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
3699e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
3700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
3701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
3702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3704e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
3705275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
3706a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
370753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (!device_distinguishes_on_address(device) ||
3708a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                            profile->supportDeviceAddress(address)) {
3709275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        profiles.add(profile);
3710275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
3711275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                    }
3712e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3713e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3714e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3715e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
37167b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent        ALOGV("  found %zu profiles, %zu outputs", profiles.size(), outputs.size());
37170fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi
3718e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty() && outputs.isEmpty()) {
3719e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3720e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
3721e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3722e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3723e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // open outputs for matching profiles if needed. Direct outputs are also opened to
3724e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3725e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
37261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
3727e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3728e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // nothing to do if one output is already opened for this profile
3729e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            size_t j;
37300fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            for (j = 0; j < outputs.size(); j++) {
37310fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                desc = mOutputs.valueFor(outputs.itemAt(j));
3732e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (!desc->isDuplicated() && desc->mProfile == profile) {
3733f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi                    // matching profile: save the sample rates, format and channel masks supported
3734f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi                    // by the profile in our device descriptor
37359080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    if (audio_device_is_digital(device)) {
37369080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                        devDesc->importAudioPort(profile);
37379080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    }
3738e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    break;
3739e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3740e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
37410fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            if (j != outputs.size()) {
3742e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
3743e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3744e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
374583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            ALOGV("opening output for device %08x with params %s profile %p",
374683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                      device, address.string(), profile.get());
3747c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
3748e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc->mDevice = device;
3749cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3750cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.sample_rate = desc->mSamplingRate;
3751cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.channel_mask = desc->mChannelMask;
3752cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.format = desc->mFormat;
3753cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.offload_info.sample_rate = desc->mSamplingRate;
3754cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.offload_info.channel_mask = desc->mChannelMask;
3755cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.offload_info.format = desc->mFormat;
3756cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3757322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openOutput(profile->getModuleHandle(),
3758cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &output,
3759cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &config,
3760cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &desc->mDevice,
3761cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            address,
3762cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            &desc->mLatency,
3763cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                            desc->mFlags);
3764cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
3765cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mSamplingRate = config.sample_rate;
3766cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mChannelMask = config.channel_mask;
3767cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mFormat = config.format;
3768cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent
3769d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                // Here is where the out_set_parameters() for card & device gets called
37703a4311c68348f728558e87b5db67d47605783890Eric Laurent                if (!address.isEmpty()) {
3771cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    char *param = audio_device_address_to_parameter(device, address);
3772cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    mpClientInterface->setParameters(output, String8(param));
3773cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    free(param);
3774e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
377500eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                updateAudioProfiles(device, output, profile->getAudioProfiles());
3776112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                if (!profile->hasValidAudioProfile()) {
37770fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGW("checkOutputsForDevice() missing param");
3778d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
3779cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    output = AUDIO_IO_HANDLE_NONE;
3780112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                } else if (profile->hasDynamicAudioProfile()) {
3781d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeOutput(output);
3782702b105b290d9a3c8b23f3c809a79086d784c9bePhil Burk                    output = AUDIO_IO_HANDLE_NONE;
3783112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->pickAudioProfile(config.sample_rate, config.channel_mask, config.format);
3784cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.sample_rate = config.sample_rate;
3785cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.channel_mask = config.channel_mask;
3786cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    config.offload_info.format = config.format;
3787322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent                    status = mpClientInterface->openOutput(profile->getModuleHandle(),
3788cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &output,
3789cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &config,
3790cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &desc->mDevice,
3791cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           address,
3792cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &desc->mLatency,
3793cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           desc->mFlags);
3794cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    if (status == NO_ERROR) {
3795cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        desc->mSamplingRate = config.sample_rate;
3796cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        desc->mChannelMask = config.channel_mask;
3797cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        desc->mFormat = config.format;
3798cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    } else {
3799cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        output = AUDIO_IO_HANDLE_NONE;
3800cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    }
3801d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
3802d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3803cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                if (output != AUDIO_IO_HANDLE_NONE) {
3804e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    addOutput(output, desc);
380553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (device_distinguishes_on_address(device) && address != "0") {
3806036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        sp<AudioPolicyMix> policyMix;
3807036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
3808275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                            ALOGE("checkOutputsForDevice() cannot find policy for address %s",
3809275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                                  address.string());
3810275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        }
3811036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie                        policyMix->setOutput(desc);
3812dacc06f5e8d00ace9d16a149fc41ff65323ffbb3Jean-Michel Trivi                        desc->mPolicyMix = policyMix->getMix();
3813036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie
381487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                    } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
381587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent                                    hasPrimaryOutput()) {
3816c722f30eef03e77054395ae122470cf8dba93937Eric Laurent                        // no duplicated output for direct outputs and
3817c722f30eef03e77054395ae122470cf8dba93937Eric Laurent                        // outputs used by dynamic policy mixes
3818cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
3819d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3820d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // set initial stream volume for device
3821c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        applyStreamVolumes(desc, device, 0, true);
3822d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3823d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        //TODO: configure audio effect output stage here
3824d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3825d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        // open a duplicating output thread for the new output and the primary output
3826c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        duplicatedOutput =
3827c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                mpClientInterface->openDuplicateOutput(output,
3828c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                       mPrimaryOutput->mIoHandle);
3829cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                        if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
3830d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            // add duplicated output descriptor
3831c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            sp<SwAudioOutputDescriptor> dupOutputDesc =
3832c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                    new SwAudioOutputDescriptor(NULL, mpClientInterface);
3833c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            dupOutputDesc->mOutput1 = mPrimaryOutput;
3834c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            dupOutputDesc->mOutput2 = desc;
3835d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
3836d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mFormat = desc->mFormat;
3837d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mChannelMask = desc->mChannelMask;
3838d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            dupOutputDesc->mLatency = desc->mLatency;
3839d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            addOutput(duplicatedOutput, dupOutputDesc);
3840c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                            applyStreamVolumes(dupOutputDesc, device, 0, true);
3841d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        } else {
3842d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
3843c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                    mPrimaryOutput->mIoHandle, output);
3844d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            mpClientInterface->closeOutput(output);
384553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                            removeOutput(output);
38466a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                            nextAudioPortGeneration();
3847cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                            output = AUDIO_IO_HANDLE_NONE;
3848d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                        }
3849e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
3850e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3851cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            } else {
3852cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                output = AUDIO_IO_HANDLE_NONE;
3853e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3854cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (output == AUDIO_IO_HANDLE_NONE) {
3855e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
3856e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profiles.removeAt(profile_index);
3857e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                profile_index--;
3858e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
3859e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputs.add(output);
38609080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                // Load digital format info only for digital devices
38619080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                if (audio_device_is_digital(device)) {
38629080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    devDesc->importAudioPort(profile);
38639080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                }
3864f17026dfef596cf1c8008fda20f1f2ad23a3df3aJean-Michel Trivi
386553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (device_distinguishes_on_address(device)) {
38660fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
38670fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            device, address.string());
3868c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
38690fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            NULL/*patch handle*/, address.string());
38700fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
3871e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("checkOutputsForDevice(): adding output %d", output);
3872e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3873e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3874e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
3875e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (profiles.isEmpty()) {
3876e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3877e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return BAD_VALUE;
3878e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3879d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else { // Disconnect
3880e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // check if one opened output is not needed any more after disconnecting one device
3881e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mOutputs.size(); i++) {
3882e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            desc = mOutputs.valueAt(i);
38830fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi            if (!desc->isDuplicated()) {
3884275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                // exact match on device
388553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                if (device_distinguishes_on_address(device) &&
3886c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                        (desc->supportedDevices() == device)) {
38873190e67d5c80c1e39e3be91784110af1180cd182keunyoung                    findIoHandlesByAddress(desc, device, address, outputs);
3888c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
38890fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
38900fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                            mOutputs.keyAt(i));
38910fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                    outputs.add(mOutputs.keyAt(i));
38920fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                }
3893e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3894e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3895d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
3896e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < mHwModules.size(); i++)
3897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
3898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (mHwModules[i]->mHandle == 0) {
3899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                continue;
3900e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3901e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3902e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            {
39031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
3904a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
3905d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGV("checkOutputsForDevice(): "
3906d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                            "clearing direct output profile %zu on module %zu", j, i);
3907112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->clearAudioProfiles();
3908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
3909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
3910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
3911e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
3912e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
3913e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
3914e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
39159080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLeanstatus_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor> devDesc,
391653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_policy_dev_state_t state,
391753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  SortedVector<audio_io_handle_t>& inputs,
391853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  const String8 address)
3919d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent{
39209080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean    audio_devices_t device = devDesc->type();
39211f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> desc;
3922cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
3923cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    if (audio_device_is_digital(device)) {
3924cc750d3604b33a92374253b12dd739dc06440aadEric Laurent        // erase all current sample rates, formats and channel masks
392520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        devDesc->clearAudioProfiles();
3926cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    }
3927cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
3928d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
3929d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // first list already open inputs that can be routed to this device
3930d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3931d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
3932a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (desc->mProfile->supportDevice(device)) {
3933d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
3934d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent               inputs.add(mInputs.keyAt(input_index));
3935d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
3936d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
3937d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3938d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // then look for input profiles that can be routed to this device
39391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        SortedVector< sp<IOProfile> > profiles;
3940d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
3941d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        {
3942d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_idx]->mHandle == 0) {
3943d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
3944d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
3945d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
3946d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_idx]->mInputProfiles.size();
3947d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++)
3948d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            {
3949275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
3950275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
3951a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
395253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                    if (!device_distinguishes_on_address(device) ||
3953a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                            profile->supportDeviceAddress(address)) {
3954275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        profiles.add(profile);
3955275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                        ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
3956275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                              profile_index, module_idx);
3957275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent                    }
3958d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
3959d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
3960d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
3961d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3962d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty() && inputs.isEmpty()) {
3963d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3964d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
3965d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
3966d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3967d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // open inputs for matching profiles if needed. Direct inputs are also opened to
3968d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3969d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
3970d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
39711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = profiles[profile_index];
3972d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // nothing to do if one input is already opened for this profile
3973d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            size_t input_index;
3974d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (input_index = 0; input_index < mInputs.size(); input_index++) {
3975d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                desc = mInputs.valueAt(input_index);
3976d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (desc->mProfile == profile) {
39779080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    if (audio_device_is_digital(device)) {
39789080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                        devDesc->importAudioPort(profile);
39799080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    }
3980d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    break;
3981d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
3982d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
3983d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (input_index != mInputs.size()) {
3984d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
3985d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
3986d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
3987d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGV("opening input for device 0x%X with params %s", device, address.string());
3988d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = new AudioInputDescriptor(profile);
3989d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc->mDevice = device;
3990cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3991cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.sample_rate = desc->mSamplingRate;
3992cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.channel_mask = desc->mChannelMask;
3993cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            config.format = desc->mFormat;
3994cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
3995322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent            status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
3996cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &input,
3997cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &config,
3998cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           &desc->mDevice,
3999cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           address,
4000cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           AUDIO_SOURCE_MIC,
4001cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                                                           AUDIO_INPUT_FLAG_NONE /*FIXME*/);
4002d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4003cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (status == NO_ERROR) {
4004cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mSamplingRate = config.sample_rate;
4005cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mChannelMask = config.channel_mask;
4006cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                desc->mFormat = config.format;
4007d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4008d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (!address.isEmpty()) {
4009cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    char *param = audio_device_address_to_parameter(device, address);
4010cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    mpClientInterface->setParameters(input, String8(param));
4011cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    free(param);
4012d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
401300eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                updateAudioProfiles(device, input, profile->getAudioProfiles());
4014112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                if (!profile->hasValidAudioProfile()) {
4015d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    ALOGW("checkInputsForDevice() direct input missing param");
4016d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    mpClientInterface->closeInput(input);
4017cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent                    input = AUDIO_IO_HANDLE_NONE;
4018d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4019d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4020d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                if (input != 0) {
4021d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                    addInput(input, desc);
4022d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4023d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } // endif input != 0
4024d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4025cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bfEric Laurent            if (input == AUDIO_IO_HANDLE_NONE) {
4026d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
4027d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profiles.removeAt(profile_index);
4028d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                profile_index--;
4029d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            } else {
4030d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(input);
40319080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                if (audio_device_is_digital(device)) {
40329080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                    devDesc->importAudioPort(profile);
40339080a4cd8c4e22ddae0350c0c51a20cea1a41016Paul McLean                }
4034d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): adding input %d", input);
4035d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4036d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        } // end scan profiles
4037d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4038d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        if (profiles.isEmpty()) {
4039d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4040d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            return BAD_VALUE;
4041d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4042d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } else {
4043d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Disconnect
4044d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // check if one opened input is not needed any more after disconnecting one device
4045d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4046d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            desc = mInputs.valueAt(input_index);
4047a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            if (!(desc->mProfile->supportDevice(mAvailableInputDevices.types()))) {
4048d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
4049d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                      mInputs.keyAt(input_index));
4050d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                inputs.add(mInputs.keyAt(input_index));
4051d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4052d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4053d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        // Clear any profiles associated with the disconnected device.
4054d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
4055d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            if (mHwModules[module_index]->mHandle == 0) {
4056d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                continue;
4057d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4058d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            for (size_t profile_index = 0;
4059d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index < mHwModules[module_index]->mInputProfiles.size();
4060d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                 profile_index++) {
40611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
4062a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                if (profile->supportDevice(device)) {
4063beb9e30471701d7b76bc14fd0d5dd1de95edd680Mark Salyzyn                    ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
4064d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                          profile_index, module_index);
4065112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                    profile->clearAudioProfiles();
4066d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent                }
4067d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            }
4068d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent        }
4069d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    } // end disconnect
4070d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4071d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent    return NO_ERROR;
4072d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent}
4073d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4074d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent
4075e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::closeOutput(audio_io_handle_t output)
4076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("closeOutput(%d)", output);
4078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4079c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
4080e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc == NULL) {
4081e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGW("closeOutput() unknown output %d", output);
4082e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4083e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4084036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    mPolicyMixes.closeOutput(outputDesc);
4085275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // look for duplicated outputs connected to the output being removed.
4087e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mOutputs.size(); i++) {
4088c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
4089e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (dupOutputDesc->isDuplicated() &&
4090e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                (dupOutputDesc->mOutput1 == outputDesc ||
4091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                dupOutputDesc->mOutput2 == outputDesc)) {
40921f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent            sp<AudioOutputDescriptor> outputDesc2;
4093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (dupOutputDesc->mOutput1 == outputDesc) {
4094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput2;
4095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
4096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                outputDesc2 = dupOutputDesc->mOutput1;
4097e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4098e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // As all active tracks on duplicated output will be deleted,
4099e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // and as they were also referenced on the other output, the reference
4100e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // count for their stream type must be adjusted accordingly on
4101e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            // the other output.
41023b73df74357b33869b39a1d69427673c780bd805Eric Laurent            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
4103e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                int refCount = dupOutputDesc->mRefCount[j];
41043b73df74357b33869b39a1d69427673c780bd805Eric Laurent                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
4105e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4106e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
4107e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
4108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->closeOutput(duplicatedOutput);
411053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            removeOutput(duplicatedOutput);
4111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4112e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4113e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
411405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    nextAudioPortGeneration();
411505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4116ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
411705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (index >= 0) {
411805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4119fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten        (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
412005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mAudioPatches.removeItemsAt(index);
412105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
412205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
412305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
4124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
4125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    param.add(String8("closing"), String8("true"));
4126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->setParameters(output, param.toString());
4127e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4128e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mpClientInterface->closeOutput(output);
412953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    removeOutput(output);
4130e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
413105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent}
413205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
413305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurentvoid AudioPolicyManager::closeInput(audio_io_handle_t input)
413405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent{
413505b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    ALOGV("closeInput(%d)", input);
413605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
413705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
413805b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (inputDesc == NULL) {
413905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        ALOGW("closeInput() unknown input %d", input);
414005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        return;
414105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
414205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
41436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
414405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
41458c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
414605b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    if (index >= 0) {
414705b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4148fcddb0b73931d207b21bd281a7df3ba2f230a607Glenn Kasten        (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
414905b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mAudioPatches.removeItemsAt(index);
415005b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent        mpClientInterface->onAudioPatchListUpdate();
415105b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    }
415205b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent
415305b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    mpClientInterface->closeInput(input);
415405b90f833337ab5f7b16509e5f1d339a04eb5bf6Eric Laurent    mInputs.removeItem(input);
4155e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4156e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4157c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentSortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
4158c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                audio_devices_t device,
4159c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                SwAudioOutputCollection openOutputs)
4160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> outputs;
4162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4163e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGVV("getOutputsForDevice() device %04x", device);
4164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < openOutputs.size(); i++) {
4165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("output %d isDuplicated=%d device=%04x",
41668c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                i, openOutputs.valueAt(i)->isDuplicated(),
41678c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent                openOutputs.valueAt(i)->supportedDevices());
4168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
4169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
4170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputs.add(openOutputs.keyAt(i));
4171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return outputs;
4174e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4176e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentbool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
417753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                      SortedVector<audio_io_handle_t>& outputs2)
4178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputs1.size() != outputs2.size()) {
4180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return false;
4181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < outputs1.size(); i++) {
4183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputs1[i] != outputs2[i]) {
4184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return false;
4185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return true;
4188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4189e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4190e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
4191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
4193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
4194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
4195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
4196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4197fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    // also take into account external policy-related changes: add all outputs which are
4198fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    // associated with policies in the "before" and "after" output vectors
4199fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    ALOGVV("checkOutputForStrategy(): policy related outputs");
4200fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
4201c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
4202fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        if (desc != 0 && desc->mPolicyMix != NULL) {
4203fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            srcOutputs.add(desc->mIoHandle);
4204fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
4205fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        }
4206fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    }
4207fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    for (size_t i = 0 ; i < mOutputs.size() ; i++) {
4208c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
4209fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        if (desc != 0 && desc->mPolicyMix != NULL) {
4210fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            dstOutputs.add(desc->mIoHandle);
4211fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi            ALOGVV(" new outputs: adding %d", desc->mIoHandle);
4212fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi        }
4213fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi    }
4214fe472e292ab50c121ff93dffa3b54c96feedcfefJean-Michel Trivi
4215e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (!vectorsEqual(srcOutputs,dstOutputs)) {
4216e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
4217e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, srcOutputs[0], dstOutputs[0]);
4218e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // mute strategy while moving tracks from one output to another
4219e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t i = 0; i < srcOutputs.size(); i++) {
4220c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
4221ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if (isStrategyActive(desc, strategy)) {
4222c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute(strategy, true, desc);
4223c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
4224e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4225d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            sp<AudioSourceDescriptor> source =
4226d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    getSourceForStrategyOnOutput(srcOutputs[i], strategy);
4227d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (source != 0){
4228d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                connectAudioSource(source);
4229d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
4230e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4231e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4232e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move effects associated to this strategy from previous output to new output
4233e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (strategy == STRATEGY_MEDIA) {
4234e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
4235e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            SortedVector<audio_io_handle_t> moved;
4236e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t i = 0; i < mEffects.size(); i++) {
42371f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
42381f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
42391f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                        effectDesc->mIo != fxOutput) {
42401f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                    if (moved.indexOf(effectDesc->mIo) < 0) {
4241e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        ALOGV("checkOutputForStrategy() moving effect %d to output %d",
4242e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              mEffects.keyAt(i), fxOutput);
42431f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
4244e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       fxOutput);
42451f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                        moved.add(effectDesc->mIo);
4246e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
42471f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                    effectDesc->mIo = fxOutput;
4248e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4249e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4250e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4251e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Move tracks associated to this strategy from previous output to new output
4252794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
42533b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (getStrategy((audio_stream_type_t)i) == strategy) {
42543b73df74357b33869b39a1d69427673c780bd805Eric Laurent                mpClientInterface->invalidateStream((audio_stream_type_t)i);
4255e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4256e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4257e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4258e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4259e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4260e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkOutputForAllStrategies()
4261e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
42622110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
4263966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
4264e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_PHONE);
42652110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
4266966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
4267e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION);
4268e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4269223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
4270e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_MEDIA);
4271e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    checkOutputForStrategy(STRATEGY_DTMF);
4272223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    checkOutputForStrategy(STRATEGY_REROUTING);
4273e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4274e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4275e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::checkA2dpSuspend()
4276e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
427753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
4278e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (a2dpOutput == 0) {
42793a4311c68348f728558e87b5db67d47605783890Eric Laurent        mA2dpSuspended = false;
4280e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return;
4281e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4282e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
42833a4311c68348f728558e87b5db67d47605783890Eric Laurent    bool isScoConnected =
4284ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent            ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET &
4285ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent                    ~AUDIO_DEVICE_BIT_IN) != 0) ||
4286ddbc6657fa0c55166148ca597980edbaafc418bfEric Laurent            ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);
4287e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // suspend A2DP output if:
4288e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (NOT already suspended) &&
4289e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      ((SCO device is connected &&
4290e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //       (forced usage for communication || for record is SCO))) ||
4291e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (phone state is ringing || in call)
4292e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
4293e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // restore A2DP output if:
4294e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (Already suspended) &&
4295e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      ((SCO device is NOT connected ||
4296e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //       (forced usage NOT for communication && NOT for record is SCO))) &&
4297e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      (phone state is NOT ringing && NOT in call)
4298e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //
4299e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (mA2dpSuspended) {
43003a4311c68348f728558e87b5db67d47605783890Eric Laurent        if ((!isScoConnected ||
43012110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) != AUDIO_POLICY_FORCE_BT_SCO) &&
43022110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) != AUDIO_POLICY_FORCE_BT_SCO))) &&
43032110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
43042110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
4305e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4306e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->restoreOutput(a2dpOutput);
4307e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = false;
4308e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4309e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
43103a4311c68348f728558e87b5db67d47605783890Eric Laurent        if ((isScoConnected &&
43112110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) ||
43122110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO))) ||
43132110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             ((mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
43142110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie              (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
4315e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4316e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->suspendOutput(a2dpOutput);
4317e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mA2dpSuspended = true;
4318e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4319e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4320e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4321e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4322c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
4323c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                       bool fromCache)
4324e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4325e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = AUDIO_DEVICE_NONE;
4326e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4327ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
43286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
43296a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
43306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached) {
43316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("getNewOutputDevice() device %08x forced by patch %d",
4332ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                  outputDesc->device(), outputDesc->getPatchHandle());
43336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return outputDesc->device();
43346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
43356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
43366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
4337e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // check the following by order of priority to request a routing change if necessary:
4338966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    // 1: the strategy enforced audible is active and enforced on the output:
4339e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy enforced audible
4340e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // 2: we are in call or the strategy phone is active on the output:
4341e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy phone
4342966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    // 3: the strategy for enforced audible is active but not enforced on the output:
4343966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund    //      use the device for strategy enforced audible
434428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // 4: the strategy sonification is active on the output:
4345e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy sonification
434628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    // 5: the strategy accessibility is active on the output:
434728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    //      use device for strategy accessibility
43485de234b29141334c1bb5e40bc19c11836848841bJean-Michel Trivi    // 6: the strategy "respectful" sonification is active on the output:
4349e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy "respectful" sonification
4350223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 7: the strategy media is active on the output:
4351e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy media
4352223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 8: the strategy DTMF is active on the output:
4353e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    //      use device for strategy DTMF
4354223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
4355d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    //      use device for strategy t-t-s
4356ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
43572110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
4358e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
4359e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else if (isInCall() ||
4360ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                    isStrategyActive(outputDesc, STRATEGY_PHONE)) {
4361e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
4362ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
4363966095ea014bc0f6ae9f523ee7f37f2fed2faeb5Jon Eklund        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
4364ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
4365e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
436628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
436728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
4368ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
4369e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
4370ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
4371e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
4372ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
4373e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
4374ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
4375d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
4376ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
4377223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
4378e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4379e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
43801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("getNewOutputDevice() selected device %x", device);
43811c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return device;
43821c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
43831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4384232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurentaudio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
43851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
4386232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
43876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
43888c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
43896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index >= 0) {
43906a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
43916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        if (patchDesc->mUid != mUidCached) {
43926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ALOGV("getNewInputDevice() device %08x forced by patch %d",
43938c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                  inputDesc->mDevice, inputDesc->getPatchHandle());
43946a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            return inputDesc->mDevice;
43956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
43966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
43976a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
4398232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent    audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->inputSource());
43991c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4400e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return device;
4401e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4402e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4403794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurentbool AudioPolicyManager::streamsMatchForvolume(audio_stream_type_t stream1,
4404794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent                                               audio_stream_type_t stream2) {
4405794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    return ((stream1 == stream2) ||
4406794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            ((stream1 == AUDIO_STREAM_ACCESSIBILITY) && (stream2 == AUDIO_STREAM_MUSIC)) ||
4407794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            ((stream1 == AUDIO_STREAM_MUSIC) && (stream2 == AUDIO_STREAM_ACCESSIBILITY)));
440828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent}
440928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent
4410e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentuint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
4411e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return (uint32_t)getStrategy(stream);
4412e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4413e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4414e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
4415e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // By checking the range of stream before calling getStrategy, we avoid
4416e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
4417e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // and then return STRATEGY_MEDIA, but we want to return the empty set.
4418223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
44196a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        return AUDIO_DEVICE_NONE;
44206a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
442128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent    audio_devices_t devices = AUDIO_DEVICE_NONE;
4422794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
4423794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
442428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            continue;
442528d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        }
4426794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
442728d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        audio_devices_t curDevices =
4428447a87bbfe11cc85123ddd94551c3a5ede54ea20Eric Laurent                getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
442928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs);
443028d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        for (size_t i = 0; i < outputs.size(); i++) {
443128d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
4432794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent            if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
443328d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent                curDevices |= outputDesc->device();
443428d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent            }
44356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        }
443628d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        devices |= curDevices;
4437e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
443811c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund
443911c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
444011c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund      and doesn't really need to.*/
444111c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
444211c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund        devices |= AUDIO_DEVICE_OUT_SPEAKER;
444311c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund        devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
444411c9fb1f90cc786485a53aeb1d31ec1ad1dbf840Jon Eklund    }
4445e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return devices;
4446e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4447e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
44482110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffierouting_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
44492110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
4450223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
44512110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getStrategyForStream(stream);
4452e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4453e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
44545bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviuint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
44555bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // flags to strategy mapping
4456d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4457d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
4458d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
44595bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
44605bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
44615bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
44625bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // usage to strategy mapping
44632110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
44645bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
44655bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
4466e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
4467e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    switch(stream) {
44683b73df74357b33869b39a1d69427673c780bd805Eric Laurent    case AUDIO_STREAM_MUSIC:
4469e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4470e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        updateDevicesAndOutputs();
4471e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4472e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    default:
4473e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        break;
4474e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4475e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4476e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4477d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::handleEventForBeacon(int event) {
44789459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
44799459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    // skip beacon mute management if a dedicated TTS output is available
44809459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    if (mTtsOutputAvailable) {
44819459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent        return 0;
44829459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent    }
44839459fb087c97c3cad66221821eb32755fdb9c9f5Eric Laurent
4484d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    switch(event) {
4485d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STARTING_OUTPUT:
4486d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconMuteRefCount++;
4487d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4488d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STOPPING_OUTPUT:
4489d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        if (mBeaconMuteRefCount > 0) {
4490d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mBeaconMuteRefCount--;
4491d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
4492d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4493d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STARTING_BEACON:
4494d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconPlayingRefCount++;
4495d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4496d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    case STOPPING_BEACON:
4497d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        if (mBeaconPlayingRefCount > 0) {
4498d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mBeaconPlayingRefCount--;
4499d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
4500d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        break;
4501d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
4502d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
4503d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (mBeaconMuteRefCount > 0) {
4504d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // any playback causes beacon to be muted
4505d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return setBeaconMute(true);
4506d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    } else {
4507d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // no other playback: unmute when beacon starts playing, mute when it stops
4508d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return setBeaconMute(mBeaconPlayingRefCount == 0);
4509d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
4510d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}
4511d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
4512d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Triviuint32_t AudioPolicyManager::setBeaconMute(bool mute) {
4513d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d",
4514d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            mute, mBeaconMuteRefCount, mBeaconPlayingRefCount);
4515d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    // keep track of muted state to avoid repeating mute/unmute operations
4516d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    if (mBeaconMuted != mute) {
4517d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        // mute/unmute AUDIO_STREAM_TTS on all outputs
4518d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        ALOGV("\t muting %d", mute);
4519d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        uint32_t maxLatency = 0;
4520d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        for (size_t i = 0; i < mOutputs.size(); i++) {
4521c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
4522d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
4523c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    desc,
4524d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                    0 /*delay*/, AUDIO_DEVICE_NONE);
4525d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            const uint32_t latency = desc->latency() * 2;
4526d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            if (latency > maxLatency) {
4527d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi                maxLatency = latency;
4528d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi            }
4529d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        }
4530d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        mBeaconMuted = mute;
4531d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi        return maxLatency;
4532d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    }
4533d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi    return 0;
4534d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi}
4535d9cfeb447356cb6334379eaf5da1e49424eb5979Jean-Michel Trivi
4536e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
453753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                         bool fromCache)
4538e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4539aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // Routing
4540aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // see if we have an explicit route
4541aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // scan the whole RouteMap, for each entry, convert the stream type to a strategy
4542aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // (getStrategy(stream)).
4543aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // if the strategy from the stream type in the RouteMap is the same as the argument above,
4544aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // and activity count is non-zero
4545aa9811945f575614b3482d09e4d969792701cebbPaul McLean    // the device = the device from the descriptor in the RouteMap, and exit.
4546aa9811945f575614b3482d09e4d969792701cebbPaul McLean    for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
4547aa9811945f575614b3482d09e4d969792701cebbPaul McLean        sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
454828d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        routing_strategy routeStrategy = getStrategy(route->mStreamType);
454928d09f06422841b4274d7fed6ad3441dc97382b2Eric Laurent        if ((routeStrategy == strategy) && route->isActive()) {
4550aa9811945f575614b3482d09e4d969792701cebbPaul McLean            return route->mDeviceDescriptor->type();
4551aa9811945f575614b3482d09e4d969792701cebbPaul McLean        }
4552aa9811945f575614b3482d09e4d969792701cebbPaul McLean    }
4553aa9811945f575614b3482d09e4d969792701cebbPaul McLean
4554e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (fromCache) {
4555e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
4556e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent              strategy, mDeviceForStrategy[strategy]);
4557e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return mDeviceForStrategy[strategy];
4558e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
45592110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getDeviceForStrategy(strategy);
4560e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4561e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4562e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::updateDevicesAndOutputs()
4563e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4564e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (int i = 0; i < NUM_STRATEGIES; i++) {
4565e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4566e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4567e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    mPreviousOutputs = mOutputs;
4568e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4569e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
45701f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurentuint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,
4571e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       audio_devices_t prevDevice,
4572e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                                       uint32_t delayMs)
4573e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4574e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute/unmute strategies using an incompatible device combination
4575e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if muting, wait for the audio in pcm buffer to be drained before proceeding
4576e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if unmuting, unmute only after the specified delay
4577e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
4578e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
4579e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4580e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4581e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs = 0;
4582e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t device = outputDesc->device();
45833b73df74357b33869b39a1d69427673c780bd805Eric Laurent    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
4584e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4585e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4586e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4587c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        curDevice = curDevice & outputDesc->supportedDevices();
4588e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
4589e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        bool doMute = false;
4590e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4591e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
4592e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
4593e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = true;
4594e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
4595e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            doMute = true;
4596e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            outputDesc->mStrategyMutedByDevice[i] = false;
4597e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
459899401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        if (doMute) {
4599e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            for (size_t j = 0; j < mOutputs.size(); j++) {
46001f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
4601e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                // skip output if it does not share any device with current output
4602e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if ((desc->supportedDevices() & outputDesc->supportedDevices())
4603e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        == AUDIO_DEVICE_NONE) {
4604e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    continue;
4605e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4606c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x)",
4607c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                      mute ? "muting" : "unmuting", i, curDevice);
4608c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
4609ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                if (isStrategyActive(desc, (routing_strategy)i)) {
461099401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                    if (mute) {
461199401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // FIXME: should not need to double latency if volume could be applied
461299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // immediately by the audioflinger mixer. We must account for the delay
461399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // between now and the next time the audioflinger thread for this output
461499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // will process a buffer (which corresponds to one buffer size,
461599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        // usually 1/2 or 1/4 of the latency).
461699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                        if (muteWaitMs < desc->latency() * 2) {
461799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent                            muteWaitMs = desc->latency() * 2;
4618e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        }
4619e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
4620e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
4621e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4622e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4623e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4624e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
462599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // temporary mute output if device selection changes to avoid volume bursts due to
462699401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    // different per device volumes
462799401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    if (outputDesc->isActive() && (device != prevDevice)) {
4628dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
4629dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        // temporary mute duration is conservatively set to 4 times the reported latency
4630dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
4631dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent        if (muteWaitMs < tempMuteWaitMs) {
4632dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent            muteWaitMs = tempMuteWaitMs;
463399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
4634dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent
463599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4636ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            if (isStrategyActive(outputDesc, (routing_strategy)i)) {
4637dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // make sure that we do not start the temporary mute period too early in case of
4638dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                // delayed device change
4639dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
4640c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                setStrategyMute((routing_strategy)i, false, outputDesc,
4641dc46286bf57fefc9f08ece3018b91acec7687f85Eric Laurent                                delayMs + tempMuteDurationMs, device);
464299401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent            }
464399401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent        }
464499401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent    }
464599401131e58f2ff7f5571037d0d53b6f684e5543Eric Laurent
4646e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // wait for the PCM output buffers to empty before proceeding with the rest of the command
4647e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (muteWaitMs > delayMs) {
4648e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        muteWaitMs -= delayMs;
4649e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        usleep(muteWaitMs * 1000);
4650e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
4651e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4652e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return 0;
4653e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4654e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4655c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
4656e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             audio_devices_t device,
4657e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                                             bool force,
46586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                             int delayMs,
46590fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                                             audio_patch_handle_t *patchHandle,
46600fb47759256ecdaedbc34c880238bc9d102ef160Jean-Michel Trivi                                             const char* address)
4661e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4662c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
4663e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    AudioParameter param;
4664e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    uint32_t muteWaitMs;
4665e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4666e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (outputDesc->isDuplicated()) {
4667c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs);
4668c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs);
4669e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
4670e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4671e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
4672e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // output profile
4673c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if ((device != AUDIO_DEVICE_NONE) &&
4674c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            ((device & outputDesc->supportedDevices()) == 0)) {
4675e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return 0;
4676e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4677e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4678e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // filter devices according to output selected
4679c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    device = (audio_devices_t)(device & outputDesc->supportedDevices());
4680e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4681e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    audio_devices_t prevDevice = outputDesc->mDevice;
4682e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4683aa9811945f575614b3482d09e4d969792701cebbPaul McLean    ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
4684e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4685e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device != AUDIO_DEVICE_NONE) {
4686e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mDevice = device;
4687e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4688e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
4689e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4690e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Do not change the routing if:
4691b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //      the requested device is AUDIO_DEVICE_NONE
4692b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //      OR the requested device is the same as current device
4693b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //  AND force is not specified
4694b80a2a8871d3af8619bf774a0c9ddbac8d598bf9Eric Laurent    //  AND the output is connected by a valid audio patch.
4695e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Doing this check here allows the caller to call setOutputDevice() without conditions
4696aa9811945f575614b3482d09e4d969792701cebbPaul McLean    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
4697aa9811945f575614b3482d09e4d969792701cebbPaul McLean        !force &&
4698ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi        outputDesc->getPatchHandle() != 0) {
4699c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
4700e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return muteWaitMs;
4701e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4702e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4703e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    ALOGV("setOutputDevice() changing device");
47041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
4705e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do the routing
47061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if (device == AUDIO_DEVICE_NONE) {
4707c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        resetOutputDevice(outputDesc, delayMs, NULL);
47081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    } else {
4709c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        DeviceVector deviceList;
4710c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        if ((address == NULL) || (strlen(address) == 0)) {
4711c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            deviceList = mAvailableOutputDevices.getDevicesFromType(device);
4712c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        } else {
4713c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent            deviceList = mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
4714c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent        }
4715c40d96943ddebd31578f30517457f88e6e894eb1Eric Laurent
47161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
47171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
47181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            outputDesc->toAudioPortConfig(&patch.sources[0]);
47191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
47201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 0;
47211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
47221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
47231c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                patch.num_sinks++;
47241c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
47256a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ssize_t index;
47266a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
47276a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                index = mAudioPatches.indexOfKey(*patchHandle);
47286a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
4729ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
47306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
47316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp< AudioPatch> patchDesc;
47326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
47336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
47346a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
47356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
47366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
47376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
47381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
47396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                   &afPatchHandle,
47406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                   delayMs);
47411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
47421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                    "num_sources %d num_sinks %d",
47436a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                       status, afPatchHandle, patch.num_sources, patch.num_sinks);
47441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
47456a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
474698cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&patch, mUidCached);
47476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
47486a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
47496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = patch;
47506a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
47516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
47526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchHandle) {
47536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    *patchHandle = patchDesc->mHandle;
47546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
4755ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi                outputDesc->setPatchHandle(patchDesc->mHandle);
47566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
4757b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
47581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
47591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
4760f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu
4761f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        // inform all input as well
4762f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        for (size_t i = 0; i < mInputs.size(); i++) {
4763f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu            const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
476453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (!is_virtual_input_device(inputDescriptor->mDevice)) {
4765f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                AudioParameter inputCmd = AudioParameter();
4766f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                ALOGV("%s: inform input %d of device:%d", __func__,
4767f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                      inputDescriptor->mIoHandle, device);
4768f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                inputCmd.addInt(String8(AudioParameter::keyRouting),device);
4769f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                mpClientInterface->setParameters(inputDescriptor->mIoHandle,
4770f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                                                 inputCmd.toString(),
4771f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu                                                 delayMs);
4772f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu            }
4773f5e7e79bf88b0c08c73262e7992634797a4f81a1bryant_liu        }
47741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
4775e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4776e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // update stream volumes according to new device
4777c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    applyStreamVolumes(outputDesc, device, delayMs);
4778e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4779e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return muteWaitMs;
4780e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4781e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4782c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t AudioPolicyManager::resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
47836a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               int delayMs,
47846a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                               audio_patch_handle_t *patchHandle)
47851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
47866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index;
47876a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchHandle) {
47886a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*patchHandle);
47896a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
4790ff155c642fe7d342a3110444c6103f788230af53Jean-Michel Trivi        index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
47916a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
47926a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
47931c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
47941c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
47956a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
47966a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
47971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
4798a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
47996a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    removeAudioPatch(patchDesc->mHandle);
48006a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
4801b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPatchListUpdate();
48021c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
48031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
48041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
48051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
48061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                            audio_devices_t device,
48076a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            bool force,
48086a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                            audio_patch_handle_t *patchHandle)
48091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
48101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    status_t status = NO_ERROR;
48111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
48121f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
48131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
48141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        inputDesc->mDevice = device;
48151c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
48161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
48171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        if (!deviceList.isEmpty()) {
48181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            struct audio_patch patch;
48191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            inputDesc->toAudioPortConfig(&patch.sinks[0]);
4820daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            // AUDIO_SOURCE_HOTWORD is for internal use only:
4821daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
4822df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
4823599c758b258cc5da0dba9b530425381facc37d77Eric Laurent                    !inputDesc->isSoundTrigger()) {
4824daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent                patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
4825daf92cc876a1952059794e6d0f558f0f6dd9ac8cEric Laurent            }
48261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sinks = 1;
48271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            //only one input device for now
48281c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
48291c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            patch.num_sources = 1;
48306a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            ssize_t index;
48316a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
48326a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                index = mAudioPatches.indexOfKey(*patchHandle);
48336a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            } else {
48348c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
48356a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
48366a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            sp< AudioPatch> patchDesc;
48376a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
48386a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            if (index >= 0) {
48396a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc = mAudioPatches.valueAt(index);
48406a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                afPatchHandle = patchDesc->mAfPatchHandle;
48416a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent            }
48426a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent
48431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            status_t status = mpClientInterface->createAudioPatch(&patch,
48446a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                  &afPatchHandle,
48451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent                                                                  0);
48461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
48476a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                                                          status, afPatchHandle);
48481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            if (status == NO_ERROR) {
48496a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (index < 0) {
485098cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie                    patchDesc = new AudioPatch(&patch, mUidCached);
48516a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    addAudioPatch(patchDesc->mHandle, patchDesc);
48526a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                } else {
48536a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    patchDesc->mPatch = patch;
48546a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
48556a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                patchDesc->mAfPatchHandle = afPatchHandle;
48566a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                if (patchHandle) {
48576a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                    *patchHandle = patchDesc->mHandle;
48586a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                }
48598c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                inputDesc->setPatchHandle(patchDesc->mHandle);
48606a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                nextAudioPortGeneration();
4861b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                mpClientInterface->onAudioPatchListUpdate();
48621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            }
48631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        }
48641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
48651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
48661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
48671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
48686a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurentstatus_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
48696a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent                                              audio_patch_handle_t *patchHandle)
48701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{
48711f2f2230900581e5de9cf01a883e5d9338f0df94Eric Laurent    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
48726a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    ssize_t index;
48736a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (patchHandle) {
48746a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent        index = mAudioPatches.indexOfKey(*patchHandle);
48756a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    } else {
48768c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
48776a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    }
48786a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    if (index < 0) {
48791c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent        return INVALID_OPERATION;
48801c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    }
48816a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
48826a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
48831c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
4884a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    inputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
48856a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    removeAudioPatch(patchDesc->mHandle);
48866a94d69dc4f32abb53c466a96f905bb199be6417Eric Laurent    nextAudioPortGeneration();
4887b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mpClientInterface->onAudioPatchListUpdate();
48881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    return status;
48891c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent}
48901c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
489156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
489253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  String8 address,
489353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  uint32_t& samplingRate,
4894f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                  audio_format_t& format,
4895f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                                  audio_channel_mask_t& channelMask,
489653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                  audio_input_flags_t flags)
4897e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4898e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // Choose an input profile based on the requested capture parameters: select the first available
4899e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // profile supporting all requested parameters.
4900f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    //
4901f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
4902f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung    // the best matching profile, not the first one.
4903e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4904e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    for (size_t i = 0; i < mHwModules.size(); i++)
4905e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    {
4906e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (mHwModules[i]->mHandle == 0) {
4907e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            continue;
4908e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4909e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
4910e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        {
49111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent            sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
4912d46929666d7e4b1cad45afd7dcb883ec4dd2d49fEric Laurent            // profile->log();
4913275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            if (profile->isCompatibleProfile(device, address, samplingRate,
4914cbd48023d0a0e3fd59955011538c0087a439f905Glenn Kasten                                             &samplingRate /*updatedSamplingRate*/,
4915f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             format,
4916f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             &format /*updatedFormat*/,
4917f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             channelMask,
4918f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             &channelMask /*updatedChannelMask*/,
4919f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung                                             (audio_output_flags_t) flags)) {
4920275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4921e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                return profile;
4922e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
4923e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
4924e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
4925e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NULL;
4926e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4927e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4928c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
4929c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
493053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                                  AudioMix **policyMix)
4931e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
4932036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
4933036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    audio_devices_t selectedDeviceFromMix =
4934036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie           mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
4935275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
4936036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie    if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
4937036e1e9126dcd496203434aa69e52115d8e730ccFrançois Gaffie        return selectedDeviceFromMix;
4938275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
4939c73ca6ef04136f28306784ad35f444538f081957Eric Laurent    return getDeviceForInputSource(inputSource);
4940c73ca6ef04136f28306784ad35f444538f081957Eric Laurent}
4941c73ca6ef04136f28306784ad35f444538f081957Eric Laurent
4942c73ca6ef04136f28306784ad35f444538f081957Eric Laurentaudio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
4943c73ca6ef04136f28306784ad35f444538f081957Eric Laurent{
4944466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean    for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
4945466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean         sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
49468c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent         if (inputSource == route->mSource && route->isActive()) {
4947466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean             return route->mDeviceDescriptor->type();
4948466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean         }
4949466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean     }
4950466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean
4951466dc8ed6ca6b7f585104806c48613dd34e608c9Paul McLean     return mEngine->getDeviceForInputSource(inputSource);
4952e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
4953e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
4954e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentfloat AudioPolicyManager::computeVolume(audio_stream_type_t stream,
4955d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                        int index,
4956d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                        audio_devices_t device)
4957e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
495800a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi    float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
49593d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi
49603d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // handle the case of accessibility active while a ringtone is playing: if the ringtone is much
49613d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
49623d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
49633d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    // the ringtone volume
49643d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    if ((stream == AUDIO_STREAM_ACCESSIBILITY)
49653d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState())
49663d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi            && isStreamActive(AUDIO_STREAM_RING, 0)) {
49673d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi        const float ringVolumeDB = computeVolume(AUDIO_STREAM_RING, index, device);
49683d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi        return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
49693d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi    }
49703d8b4a450b451183b4eaba321b594df4a4ae9948Jean-Michel Trivi
4971e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if a headset is connected, apply the following rules to ring tones and notifications
4972e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // to avoid sound level bursts in user's ears:
49736af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // - always attenuate notifications volume by 6dB
49746af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // - attenuate ring tones volume by 6dB unless music is not playing and
49756af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent    // speaker is part of the select devices
4976e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // - if music is playing, always limit the volume to current music volume,
4977e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // with a minimum threshold at -36dB so that notification is always perceived.
49783b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
4979e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
4980e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
4981e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADSET |
4982e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
4983e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ((stream_strategy == STRATEGY_SONIFICATION)
4984e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
49853b73df74357b33869b39a1d69427673c780bd805Eric Laurent                || (stream == AUDIO_STREAM_SYSTEM)
4986e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
49872110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                    (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
4988d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            mVolumeCurves->canBeMuted(stream)) {
4989e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // when the phone is ringing we must consider that music could have been paused just before
4990e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // by the music application and behave as if music was active if the last music track was
4991e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // just stopped
49923b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
4993e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                mLimitRingtoneVolume) {
499400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
4995e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
4996ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent            float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
4997d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                             mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
4998d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                                                              musicDevice),
4999d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                                             musicDevice);
5000ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent            float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
5001ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                    musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
500200a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            if (volumeDB > minVolDB) {
500300a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                volumeDB = minVolDB;
5004ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
5005e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
500600a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
500700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
500800a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                // on A2DP, also ensure notification volume is not too low compared to media when
500900a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                // intended to be played
501000a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                if ((volumeDB > -96.0f) &&
501100a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                        (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDB)) {
501200a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
501300a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                            stream, device,
501400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                            volumeDB, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
501500a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                    volumeDB = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
501600a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi                }
501700a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            }
50186af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent        } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
50196af1c1dc8954a555c6c6ef07d4f93e243d7f08cfEric Laurent                stream_strategy != STRATEGY_SONIFICATION) {
502000a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
5021e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5022e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5023e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
502400a2096f3bd6f938216b3691c0b581d64df52999Jean-Michel Trivi    return volumeDB;
5025e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5026e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5027e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentstatus_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
5028c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   int index,
5029c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   const sp<AudioOutputDescriptor>& outputDesc,
5030c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   audio_devices_t device,
5031c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   int delayMs,
5032c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                   bool force)
5033e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5034e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change actual stream volume if the stream is muted
5035c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->mMuteCount[stream] != 0) {
5036e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGVV("checkAndSetVolume() stream %d muted count %d",
5037c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent              stream, outputDesc->mMuteCount[stream]);
5038e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return NO_ERROR;
5039e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
50402110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    audio_policy_forced_cfg_t forceUseForComm =
50412110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie            mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
5042e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // do not change in call volume if bluetooth is connected and vice versa
50432110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
50442110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie        (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
5045e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
50462110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie             stream, forceUseForComm);
5047e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        return INVALID_OPERATION;
5048e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5049e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5050c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
5051c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        device = outputDesc->device();
5052275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
5053c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
5054ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent    float volumeDb = computeVolume(stream, index, device);
5055c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->isFixedVolume(device)) {
5056ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent        volumeDb = 0.0f;
5057e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5058e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5059ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent    outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
5060c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
50613b73df74357b33869b39a1d69427673c780bd805Eric Laurent    if (stream == AUDIO_STREAM_VOICE_CALL ||
50623b73df74357b33869b39a1d69427673c780bd805Eric Laurent        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
5063e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        float voiceVolume;
5064e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
50653b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (stream == AUDIO_STREAM_VOICE_CALL) {
5066d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);
5067e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        } else {
5068e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            voiceVolume = 1.0;
5069e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5070e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
507118fba84019d778b3c20875d93f9f36c2410ecf33Eric Laurent        if (voiceVolume != mLastVoiceVolume) {
5072e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
5073e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            mLastVoiceVolume = voiceVolume;
5074e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5075e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5076e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5077e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    return NO_ERROR;
5078e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5079e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5080c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
5081c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                audio_devices_t device,
5082c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                int delayMs,
5083c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                bool force)
5084e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5085c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGVV("applyStreamVolumes() for device %08x", device);
5086e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5087794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
50883b73df74357b33869b39a1d69427673c780bd805Eric Laurent        checkAndSetVolume((audio_stream_type_t)stream,
5089d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                          mVolumeCurves->getVolumeIndex((audio_stream_type_t)stream, device),
5090c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                          outputDesc,
5091e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          device,
5092e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          delayMs,
5093e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                          force);
5094e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5095e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5096e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5097e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStrategyMute(routing_strategy strategy,
5098c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             bool on,
5099c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             const sp<AudioOutputDescriptor>& outputDesc,
5100c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             int delayMs,
5101c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             audio_devices_t device)
5102e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
510372249d5b2f9f42a96c0e0825431e8f3f49b82644Eric Laurent    ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
510472249d5b2f9f42a96c0e0825431e8f3f49b82644Eric Laurent           strategy, on, outputDesc->getId());
5105794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
51063b73df74357b33869b39a1d69427673c780bd805Eric Laurent        if (getStrategy((audio_stream_type_t)stream) == strategy) {
5107c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
5108e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5109e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5110e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5111e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5112e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
5113c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           bool on,
5114c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           const sp<AudioOutputDescriptor>& outputDesc,
5115c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           int delayMs,
5116c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                           audio_devices_t device)
5117e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
5118e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
5119e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        device = outputDesc->device();
5120e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5121e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5122c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
5123c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent          stream, on, outputDesc->mMuteCount[stream], device);
5124e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5125e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if (on) {
5126e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
5127d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie            if (mVolumeCurves->canBeMuted(stream) &&
51283b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
51292110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
5130c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
5131e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5132e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5133e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
5134e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        outputDesc->mMuteCount[stream]++;
5135e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    } else {
5136e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mMuteCount[stream] == 0) {
5137e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ALOGV("setStreamMute() unmuting non muted stream!");
5138e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            return;
5139e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5140e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (--outputDesc->mMuteCount[stream] == 0) {
5141e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            checkAndSetVolume(stream,
5142d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie                              mVolumeCurves->getVolumeIndex(stream, device),
5143c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                              outputDesc,
5144e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              device,
5145e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                              delayMs);
5146e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5147e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5148e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5149e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
5150e07208765fcd5904165e425ec714a25c350a2f40Eric Laurentvoid AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
51513b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                      bool starting, bool stateChange)
5152e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent{
515387ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    if(!hasPrimaryOutput()) {
515487ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent        return;
515587ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent    }
515687ffa39d29d1803b48237888a9fbf3d5f2c60c21Eric Laurent
5157e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if the stream pertains to sonification strategy and we are in call we must
5158e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
5159e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // in the device used for phone strategy and play the tone if the selected device does not
5160e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // interfere with the device used for phone strategy
5161e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
5162e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    // many times as there are active tracks on the output
51633b73df74357b33869b39a1d69427673c780bd805Eric Laurent    const routing_strategy stream_strategy = getStrategy(stream);
5164e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    if ((stream_strategy == STRATEGY_SONIFICATION) ||
5165e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
5166c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
5167e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
5168e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                stream, starting, outputDesc->mDevice, stateChange);
5169e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        if (outputDesc->mRefCount[stream]) {
5170e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            int muteCount = 1;
5171e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            if (stateChange) {
5172e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                muteCount = outputDesc->mRefCount[stream];
5173e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
51743b73df74357b33869b39a1d69427673c780bd805Eric Laurent            if (audio_is_low_visibility(stream)) {
5175e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
5176e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                for (int i = 0; i < muteCount; i++) {
5177e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    setStreamMute(stream, starting, mPrimaryOutput);
5178e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5179e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            } else {
5180e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                ALOGV("handleIncallSonification() high visibility");
5181e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (outputDesc->device() &
5182e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
5183e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
5184e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    for (int i = 0; i < muteCount; i++) {
5185e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                        setStreamMute(stream, starting, mPrimaryOutput);
5186e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    }
5187e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5188e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                if (starting) {
51893b73df74357b33869b39a1d69427673c780bd805Eric Laurent                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
51903b73df74357b33869b39a1d69427673c780bd805Eric Laurent                                                 AUDIO_STREAM_VOICE_CALL);
5191e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                } else {
5192e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                    mpClientInterface->stopTone();
5193e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent                }
5194e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent            }
5195e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent        }
5196e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent    }
5197e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}
5198e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent
51995bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Triviaudio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
52005bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi{
52015bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // flags to stream type mapping
52025bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
52035bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_ENFORCED_AUDIBLE;
52045bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
52055bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
52065bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_BLUETOOTH_SCO;
52075bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
520879ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
520979ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi        return AUDIO_STREAM_TTS;
521079ad438ed25c59a37244a48899263bbc4bc92f5dJean-Michel Trivi    }
52115bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
52125bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    // usage to stream type mapping
52135bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    switch (attr->usage) {
52145bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_MEDIA:
52155bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_GAME:
52165bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
52175bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_MUSIC;
5218223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5219223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        return AUDIO_STREAM_ACCESSIBILITY;
52205bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
52215bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_SYSTEM;
52225bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_VOICE_COMMUNICATION:
52235bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_VOICE_CALL;
52245bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
52255bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
52265bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_DTMF;
52275bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
52285bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_ALARM:
52295bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_ALARM;
52305bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
52315bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_RING;
52325bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
52335bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION:
52345bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
52355bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
52365bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
52375bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_NOTIFICATION_EVENT:
52385bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_NOTIFICATION;
52395bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
52405bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    case AUDIO_USAGE_UNKNOWN:
52415bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    default:
52425bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi        return AUDIO_STREAM_MUSIC;
52435bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi    }
52445bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
5245e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
524653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiebool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
524753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
5248e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // has flags that map to a strategy?
5249e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
5250e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return true;
5251e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
5252e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
5253e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    // has known usage?
5254e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    switch (paa->usage) {
5255e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_UNKNOWN:
5256e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_MEDIA:
5257e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_VOICE_COMMUNICATION:
5258e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
5259e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ALARM:
5260e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION:
5261e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
5262e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
5263e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
5264e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
5265e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_NOTIFICATION_EVENT:
5266e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5267e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
5268e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
5269e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    case AUDIO_USAGE_GAME:
5270275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    case AUDIO_USAGE_VIRTUAL_SOURCE:
5271e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        break;
5272e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    default:
5273e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return false;
5274e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
5275e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return true;
5276e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
5277e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
5278ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffiebool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor> outputDesc,
5279ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                          routing_strategy strategy, uint32_t inPastMs,
5280ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                                          nsecs_t sysTime) const
5281ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie{
5282ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if ((sysTime == 0) && (inPastMs != 0)) {
5283ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        sysTime = systemTime();
5284ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    }
5285794fde269478b50be873d9d93574b8aa2b6afc42Eric Laurent    for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
5286ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
5287ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                (NUM_STRATEGIES == strategy)) &&
5288ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie                outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
5289ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie            return true;
5290ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        }
5291ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    }
5292ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    return false;
5293ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie}
5294ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie
52952110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffieaudio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
52962110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
52972110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return mEngine->getForceUse(usage);
52982110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
52992110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
53002110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffiebool AudioPolicyManager::isInCall()
53012110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
53022110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return isStateInCall(mEngine->getPhoneState());
53032110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
53042110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
53052110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffiebool AudioPolicyManager::isStateInCall(int state)
53062110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie{
53072110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie    return is_state_in_call(state);
53082110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie}
53092110e04cdfbf9ad85ce154ce5f778ee5ccfc95ebFrançois Gaffie
5310d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc)
5311d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
5312d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
5313d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
5314d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (sourceDesc->mDevice->equals(deviceDesc)) {
5315d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->getHandle());
5316d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            stopAudioSource(sourceDesc->getHandle());
5317d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5318d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
5319d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
5320d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {
5321d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
5322d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        bool release = false;
5323d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t j = 0; j < patchDesc->mPatch.num_sources && !release; j++)  {
5324d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const struct audio_port_config *source = &patchDesc->mPatch.sources[j];
5325d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (source->type == AUDIO_PORT_TYPE_DEVICE &&
5326d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    source->ext.device.type == deviceDesc->type()) {
5327d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                release = true;
5328d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
5329d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5330d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t j = 0; j < patchDesc->mPatch.num_sinks && !release; j++)  {
5331d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const struct audio_port_config *sink = &patchDesc->mPatch.sinks[j];
5332d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
5333d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                    sink->ext.device.type == deviceDesc->type()) {
5334d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                release = true;
5335d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
5336d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5337d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (release) {
5338d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            ALOGV("%s releasing patch %u", __FUNCTION__, patchDesc->mHandle);
5339d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            releaseAudioPatch(patchDesc->mHandle, patchDesc->mUid);
5340d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
5341d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
5342d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
5343d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
534409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk// Modify the list of surround sound formats supported.
53450709b0aba2adb719d347341ff58441347a1c1582Phil Burkvoid AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
53460709b0aba2adb719d347341ff58441347a1c1582Phil Burk    FormatVector &formats = *formatsPtr;
534707ac114c3965e16fe523f88c913e701602604589Phil Burk    // TODO Set this based on Config properties.
534807ac114c3965e16fe523f88c913e701602604589Phil Burk    const bool alwaysForceAC3 = true;
534909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
535009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
535109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
53520709b0aba2adb719d347341ff58441347a1c1582Phil Burk    ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
535309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
535409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    // Analyze original support for various formats.
535507ac114c3965e16fe523f88c913e701602604589Phil Burk    bool supportsAC3 = false;
535607ac114c3965e16fe523f88c913e701602604589Phil Burk    bool supportsOtherSurround = false;
535709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    bool supportsIEC61937 = false;
535809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
535909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        audio_format_t format = formats[formatIndex];
536009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        switch (format) {
536109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_AC3:
536207ac114c3965e16fe523f88c913e701602604589Phil Burk                supportsAC3 = true;
536307ac114c3965e16fe523f88c913e701602604589Phil Burk                break;
536409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_E_AC3:
536509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_DTS:
536609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_DTS_HD:
536707ac114c3965e16fe523f88c913e701602604589Phil Burk                supportsOtherSurround = true;
536809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                break;
536909bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            case AUDIO_FORMAT_IEC61937:
537009bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                supportsIEC61937 = true;
537109bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                break;
537209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            default:
537309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk                break;
537409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        }
537509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
537609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
537709bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    // Modify formats based on surround preferences.
537809bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    // If NEVER, remove support for surround formats.
537907ac114c3965e16fe523f88c913e701602604589Phil Burk    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
538007ac114c3965e16fe523f88c913e701602604589Phil Burk        if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
538107ac114c3965e16fe523f88c913e701602604589Phil Burk            // Remove surround sound related formats.
538207ac114c3965e16fe523f88c913e701602604589Phil Burk            for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
538307ac114c3965e16fe523f88c913e701602604589Phil Burk                audio_format_t format = formats[formatIndex];
538407ac114c3965e16fe523f88c913e701602604589Phil Burk                switch(format) {
538507ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_AC3:
538607ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_E_AC3:
538707ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_DTS:
538807ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_DTS_HD:
538907ac114c3965e16fe523f88c913e701602604589Phil Burk                    case AUDIO_FORMAT_IEC61937:
539007ac114c3965e16fe523f88c913e701602604589Phil Burk                        formats.removeAt(formatIndex);
539107ac114c3965e16fe523f88c913e701602604589Phil Burk                        break;
539207ac114c3965e16fe523f88c913e701602604589Phil Burk                    default:
539307ac114c3965e16fe523f88c913e701602604589Phil Burk                        formatIndex++; // keep it
539407ac114c3965e16fe523f88c913e701602604589Phil Burk                        break;
539507ac114c3965e16fe523f88c913e701602604589Phil Burk                }
539609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk            }
539707ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsAC3 = false;
539807ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsOtherSurround = false;
539907ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsIEC61937 = false;
540007ac114c3965e16fe523f88c913e701602604589Phil Burk        }
540107ac114c3965e16fe523f88c913e701602604589Phil Burk    } else { // AUTO or ALWAYS
540207ac114c3965e16fe523f88c913e701602604589Phil Burk        // Most TVs support AC3 even if they do not report it in the EDID.
540307ac114c3965e16fe523f88c913e701602604589Phil Burk        if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
540407ac114c3965e16fe523f88c913e701602604589Phil Burk                && !supportsAC3) {
540507ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_AC3);
540607ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsAC3 = true;
540707ac114c3965e16fe523f88c913e701602604589Phil Burk        }
540807ac114c3965e16fe523f88c913e701602604589Phil Burk
540907ac114c3965e16fe523f88c913e701602604589Phil Burk        // If ALWAYS, add support for raw surround formats if all are missing.
541007ac114c3965e16fe523f88c913e701602604589Phil Burk        // This assumes that if any of these formats are reported by the HAL
541107ac114c3965e16fe523f88c913e701602604589Phil Burk        // then the report is valid and should not be modified.
541207ac114c3965e16fe523f88c913e701602604589Phil Burk        if ((forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS)
541307ac114c3965e16fe523f88c913e701602604589Phil Burk                && !supportsOtherSurround) {
541407ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_E_AC3);
541507ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_DTS);
541607ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_DTS_HD);
541707ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsOtherSurround = true;
541807ac114c3965e16fe523f88c913e701602604589Phil Burk        }
541907ac114c3965e16fe523f88c913e701602604589Phil Burk
542007ac114c3965e16fe523f88c913e701602604589Phil Burk        // Add support for IEC61937 if any raw surround supported.
542107ac114c3965e16fe523f88c913e701602604589Phil Burk        // The HAL could do this but add it here, just in case.
542207ac114c3965e16fe523f88c913e701602604589Phil Burk        if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
542307ac114c3965e16fe523f88c913e701602604589Phil Burk            formats.add(AUDIO_FORMAT_IEC61937);
542407ac114c3965e16fe523f88c913e701602604589Phil Burk            supportsIEC61937 = true;
542509bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        }
542609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
54270709b0aba2adb719d347341ff58441347a1c1582Phil Burk}
54280709b0aba2adb719d347341ff58441347a1c1582Phil Burk
54290709b0aba2adb719d347341ff58441347a1c1582Phil Burk// Modify the list of channel masks supported.
54300709b0aba2adb719d347341ff58441347a1c1582Phil Burkvoid AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
54310709b0aba2adb719d347341ff58441347a1c1582Phil Burk    ChannelsVector &channelMasks = *channelMasksPtr;
54320709b0aba2adb719d347341ff58441347a1c1582Phil Burk    audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
54330709b0aba2adb719d347341ff58441347a1c1582Phil Burk            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
54340709b0aba2adb719d347341ff58441347a1c1582Phil Burk
54350709b0aba2adb719d347341ff58441347a1c1582Phil Burk    // If NEVER, then remove support for channelMasks > stereo.
54360709b0aba2adb719d347341ff58441347a1c1582Phil Burk    if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
54370709b0aba2adb719d347341ff58441347a1c1582Phil Burk        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
54380709b0aba2adb719d347341ff58441347a1c1582Phil Burk            audio_channel_mask_t channelMask = channelMasks[maskIndex];
54390709b0aba2adb719d347341ff58441347a1c1582Phil Burk            if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
54400709b0aba2adb719d347341ff58441347a1c1582Phil Burk                ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
54410709b0aba2adb719d347341ff58441347a1c1582Phil Burk                channelMasks.removeAt(maskIndex);
54420709b0aba2adb719d347341ff58441347a1c1582Phil Burk            } else {
54430709b0aba2adb719d347341ff58441347a1c1582Phil Burk                maskIndex++;
54440709b0aba2adb719d347341ff58441347a1c1582Phil Burk            }
54450709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
54460709b0aba2adb719d347341ff58441347a1c1582Phil Burk    // If ALWAYS, then make sure we at least support 5.1
54470709b0aba2adb719d347341ff58441347a1c1582Phil Burk    } else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
54480709b0aba2adb719d347341ff58441347a1c1582Phil Burk        bool supports5dot1 = false;
54490709b0aba2adb719d347341ff58441347a1c1582Phil Burk        // Are there any channel masks that can be considered "surround"?
54500709b0aba2adb719d347341ff58441347a1c1582Phil Burk        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); maskIndex++) {
54510709b0aba2adb719d347341ff58441347a1c1582Phil Burk            audio_channel_mask_t channelMask = channelMasks[maskIndex];
54520709b0aba2adb719d347341ff58441347a1c1582Phil Burk            if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
54530709b0aba2adb719d347341ff58441347a1c1582Phil Burk                supports5dot1 = true;
54540709b0aba2adb719d347341ff58441347a1c1582Phil Burk                break;
54550709b0aba2adb719d347341ff58441347a1c1582Phil Burk            }
54560709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
54570709b0aba2adb719d347341ff58441347a1c1582Phil Burk        // If not then add 5.1 support.
54580709b0aba2adb719d347341ff58441347a1c1582Phil Burk        if (!supports5dot1) {
54590709b0aba2adb719d347341ff58441347a1c1582Phil Burk            channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
54600709b0aba2adb719d347341ff58441347a1c1582Phil Burk            ALOGI("%s: force ALWAYS, so adding channelMask for 5.1 surround", __FUNCTION__);
54610709b0aba2adb719d347341ff58441347a1c1582Phil Burk        }
546209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk    }
546309bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk}
546409bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk
546500eeb32846df81288f12fe4c83e61d7db2842226Phil Burkvoid AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
546600eeb32846df81288f12fe4c83e61d7db2842226Phil Burk                                             audio_io_handle_t ioHandle,
5467112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                             AudioProfileVector &profiles)
5468112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie{
5469112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    String8 reply;
54700709b0aba2adb719d347341ff58441347a1c1582Phil Burk
5471112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    // Format MUST be checked first to update the list of AudioProfile
5472112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    if (profiles.hasDynamicFormat()) {
5473112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        reply = mpClientInterface->getParameters(ioHandle,
5474112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
54750709b0aba2adb719d347341ff58441347a1c1582Phil Burk        ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
547662e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent        AudioParameter repliedParameters(reply);
547762e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent        if (repliedParameters.get(
547862e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS), reply) != NO_ERROR) {
5479112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
5480112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            return;
5481112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
548209bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        FormatVector formats = formatsFromString(reply.string());
548300eeb32846df81288f12fe4c83e61d7db2842226Phil Burk        if (device == AUDIO_DEVICE_OUT_HDMI) {
54840709b0aba2adb719d347341ff58441347a1c1582Phil Burk            filterSurroundFormats(&formats);
548500eeb32846df81288f12fe4c83e61d7db2842226Phil Burk        }
548609bc4612bdd5874d744c5da1183d96fbd2ad0235Phil Burk        profiles.setFormats(formats);
5487112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
5488112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    const FormatVector &supportedFormats = profiles.getSupportedFormats();
5489112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
549020eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent    for (size_t formatIndex = 0; formatIndex < supportedFormats.size(); formatIndex++) {
5491112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        audio_format_t format = supportedFormats[formatIndex];
549220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        ChannelsVector channelMasks;
549320eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        SampleRateVector samplingRates;
5494112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        AudioParameter requestedParameters;
5495112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        requestedParameters.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), format);
5496112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
5497112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        if (profiles.hasDynamicRateFor(format)) {
5498112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            reply = mpClientInterface->getParameters(ioHandle,
5499112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                     requestedParameters.toString() + ";" +
5500112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                     AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES);
5501112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.string());
550262e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            AudioParameter repliedParameters(reply);
550362e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            if (repliedParameters.get(
550462e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                    String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES), reply) == NO_ERROR) {
550562e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                samplingRates = samplingRatesFromString(reply.string());
5506112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            }
5507112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
5508112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        if (profiles.hasDynamicChannelsFor(format)) {
5509112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            reply = mpClientInterface->getParameters(ioHandle,
5510112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                     requestedParameters.toString() + ";" +
5511112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                                     AUDIO_PARAMETER_STREAM_SUP_CHANNELS);
5512112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.string());
551362e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            AudioParameter repliedParameters(reply);
551462e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent            if (repliedParameters.get(
551562e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                    String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS), reply) == NO_ERROR) {
551662e4bc53be19e96f8e37e850b9c8a9e15b9e2ba6Eric Laurent                channelMasks = channelMasksFromString(reply.string());
55170709b0aba2adb719d347341ff58441347a1c1582Phil Burk                if (device == AUDIO_DEVICE_OUT_HDMI) {
55180709b0aba2adb719d347341ff58441347a1c1582Phil Burk                    filterSurroundChannelMasks(&channelMasks);
55190709b0aba2adb719d347341ff58441347a1c1582Phil Burk                }
5520112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie            }
5521112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        }
552220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent        profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
5523112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
5524112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie}
5525d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
5526e552edb33fb5873179ae0a46d9579d1103eb13c6Eric Laurent}; // namespace android
5527