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