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