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