音訊策略配置檔案分析
<globalConfiguration speaker_drc_enabled="true"/> <modules> <!-- Primary Audio HAL --> <module name="primary" halVersion="2.0"> <attachedDevices> <item>Earpiece</item> <item>Speaker</item> <item>Built-In Mic</item> <item>Built-In Back Mic</item> <item>FM Tuner</item> <item>In Call-Voice</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="low_latency" role="source" flags="AUDIO_OUTPUT_FLAG_FAST"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="compressed_offload" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING"> <profile name="" format="AUDIO_FORMAT_MP3" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_AAC_LC" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000" channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_AAC_HE_V1" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000" channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_AAC_HE_V2" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000" channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/> </mixPort> <mixPort name="voip_rx" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_AMR_NB" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_AMR_WB" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_QCELP" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_EVRC" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_EVRCB" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_EVRCWB" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> <profile name="" format="AUDIO_FORMAT_EVRCNW" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> </mixPort> <mixPort name="primary input" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_AMR_NB" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_AMR_WB" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_QCELP" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_EVRC" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_EVRCB" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_EVRCWB" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> <profile name="" format="AUDIO_FORMAT_EVRCNW" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> </mixPort> </mixPorts> <devicePorts> <!-- Output devices declaration, i.e. Sink DEVICE PORT --> <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Line" type="AUDIO_DEVICE_OUT_LINE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> </devicePort> <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> </devicePort> <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> </devicePort> <devicePort tagName="BT SCO All" type="AUDIO_DEVICE_OUT_ALL_SCO" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> </devicePort> <devicePort tagName="Proxy" type="AUDIO_DEVICE_OUT_PROXY" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,16000,22050,32000,44100,48000, 64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/> </devicePort> <devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> </devicePort> <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> </devicePort> <devicePort tagName="In Call-Voice" type="AUDIO_DEVICE_IN_VOICE_CALL" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT,AUDIO_FORMAT_AMR_NB,AUDIO_FORMAT_AMR_WB,AUDIO_FORMAT_QCELP, AUDIO_FORMAT_EVRC,AUDIO_FORMAT_EVRCB,AUDIO_FORMAT_EVRCWB,AUDIO_FORMAT_EVRCNW" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> </devicePort> <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/> </devicePort> <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> </devicePort> <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> </devicePorts> <!-- route declaration, i.e. list all available sources for a given sink --> <routes> <route type="mix" sink="Earpiece" sources="primary output,low_latency,compressed_offload,voip_rx,BT SCO Headset Mic"/> <route type="mix" sink="Speaker" sources="primary output,low_latency,compressed_offload,voip_rx,BT SCO Headset Mic"/> <route type="mix" sink="Wired Headset" sources="primary output,low_latency,compressed_offload,voip_rx,BT SCO Headset Mic"/> <route type="mix" sink="Wired Headphones" sources="primary output,low_latency,compressed_offload,voip_rx,BT SCO Headset Mic"/> <route type="mix" sink="Line" sources="primary output,low_latency,compressed_offload,voip_rx"/> <route type="mix" sink="Proxy" sources="primary output,low_latency,compressed_offload"/> <route type="mix" sink="FM" sources="primary output"/> <route type="mix" sink="BT SCO All" sources="primary output,low_latency,compressed_offload,voip_rx"/> <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic,BT SCO Headset Mic,Built-In Back Mic, FM Tuner,In Call-Voice"/> </routes> </module> </modules>
Primary模組支援的輸出裝置按位與0x212007F
AUDIO_DEVICE_OUT_EARPIECE = 0x1,
AUDIO_DEVICE_OUT_SPEAKER = 0x2,
AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20 ,
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
AUDIO_DEVICE_OUT_ALL_SCO = 0x70
AUDIO_DEVICE_OUT_LINE = 0x20000,
AUDIO_DEVICE_OUT_FM = 0x100000,
AUDIO_DEVICE_OUT_PROXY = 0x2000000,
Primary模組支援的輸入裝置按位與0x800020DC
AUDIO_DEVICE_BIT_IN = 0x80000000 ,
AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4,
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8,
AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10,
AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40,
AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80,
AUDIO_DEVICE_IN_FM_TUNER = AUDIO_DEVICE_BIT_IN | 0x2000,
預設模組
HW module primary, output profiles 4, input profiles 1
output devices 0x212007f, name primary output, avaiable 0x3 //支援所有輸出裝置
output devices 0x202007f, name low_latency, avaiable 0x3 //不支援AUDIO_DEVICE_OUT_FM
output devices 0x202007f, name compressed_offload, avaiable 0x3 //不支援AUDIO_DEVICE_OUT_FM
output devices 0x2007f, name voip_rx, avaiable 0x3 //不支援AUDIO_DEVICE_OUT_PROXY和AUDIO_DEVICE_OUT_FM
input devices 0x800020dc, name primary input, availabe 0x21c4 //支援所有輸入裝置
每個profile是否支援某種裝置取決於兩個方面:
一是必須有定義該裝置的devicePort宣告;
二是必須有該mixPort到devicePort的路由;
如name為low_latency的profile不支援裝置AUDIO_DEVICE_OUT_FM,其原因是因為沒有low_latency到AUDIO_DEVICE_OUT_FM的路由,系統只有primary output到AUDIO_DEVICE_OUT_FM的路由。
//定義輸出流
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
//定義輸出裝置
<devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
//定義輸出流的輸出裝置的路由
<route type="mix" sink="FM" sources="primary output"/>
藍芽模組
HW module a2dp, output profiles 1, input profiles 1
output devices 0x380, name a2dp output, avaiable 0x3
input devices 0x80020000, name a2dp input, availabe 0x21c4
USB模組
HW module usb, output profiles 2, input profiles 1
output devices 0x2000, name usb_accessory output, avaiable 0x3
output devices 0x4000, name usb_device output, avaiable 0x3
input devices 0x80001000, name usb_device input, availabe 0x21c4
通過audio_policy_configuration.xml檔案初始化輸入輸出系統。
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
mUidCached = getuid();
mpClientInterface = clientInterface;
bool speakerDrcEnabled = false;
mVolumeCurves = new VolumeCurvesCollection();
AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
mDefaultOutputDevice, speakerDrcEnabled,
static_cast<VolumeCurvesCollection *>(mVolumeCurves));
PolicySerializer serializer;
if (serializer.deserialize(AUDIO_POLICY_XML_CONFIG_FILE, config) != NO_ERROR) {
ALOGE("could not load audio policy configuration file, setting defaults");
config.setDefault();
}
// must be done after reading the policy (since conditionned by Speaker Drc Enabling)
mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
// Once policy config has been parsed, retrieve an instance of the engine and initialize it.
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
// Retrieve the Policy Manager Interface
mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
(void) status;
audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
// 依次載入 HwModule 並開啟其所含 profile 的 outputStream 及 inputStream
for (size_t i = 0; i < mHwModules.size(); i++) {
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
if (mHwModules[i]->mHandle == 0) {
ALOGW("could not open HW module %s", mHwModules[i]->getName());
continue;
}
//開啟所有可用的輸出裝置
for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
{
const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
if (!outProfile->hasSupportedDevices()) {
ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
continue;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
mTtsOutputAvailable = true;
}
//不開啟direct型別的輸出裝置
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
}
audio_devices_t profileType = outProfile->getSupportedDevicesType();
if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
//使用預設輸出裝置speaker
profileType = mDefaultOutputDevice->type();
} else {
//返回第一個匹配的裝置
profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
}
if ((profileType & outputDeviceTypes) == 0) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
: String8("");
outputDesc->mDevice = profileType;
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = outputDesc->mSamplingRate;
config.channel_mask = outputDesc->mChannelMask;
config.format = outputDesc->mFormat;
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
&output,
&config,
&outputDesc->mDevice,
address,
&outputDesc->mLatency,
outputDesc->mFlags);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for device %08x on hw module %s",
outputDesc->mDevice,
mHwModules[i]->getName());
} else {
outputDesc->mSamplingRate = config.sample_rate;
outputDesc->mChannelMask = config.channel_mask;
outputDesc->mFormat = config.format;
for (size_t k = 0; k < supportedDevices.size(); k++) {
ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
mAvailableOutputDevices[index]->attach(mHwModules[i]);
}
}
if (mPrimaryOutput == 0 &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
addOutput(output, outputDesc);
setOutputDevice(outputDesc,
outputDesc->mDevice,
true,
0,
NULL,
address.string());
}
}
//開啟所有可用的輸入裝置
for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
{
const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
if (!inProfile->hasSupportedDevices()) {
ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
continue;
}
//返回第一個匹配的輸入裝置
audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
if ((profileType & inputDeviceTypes) == 0) {
continue;
}
sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);
inputDesc->mDevice = profileType;
// find the address
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
// the inputs vector must be of size 1, but we don't want to crash here
String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = inputDesc->mSamplingRate;
config.channel_mask = inputDesc->mChannelMask;
config.format = inputDesc->mFormat;
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
&input,
&config,
&inputDesc->mDevice,
address,
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE);
if (status == NO_ERROR) {
const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
for (size_t k = 0; k < supportedDevices.size(); k++) {
ssize_t index = mAvailableInputDevices.indexOf(supportedDevices[k]);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0) {
sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
if (!devDesc->isAttached()) {
devDesc->attach(mHwModules[i]);
devDesc->importAudioPort(inProfile);
}
}
}
mpClientInterface->closeInput(input);
} else {
ALOGW("Cannot open input stream for device %08x on hw module %s",
inputDesc->mDevice,
mHwModules[i]->getName());
}
}
}
// make sure all attached devices have been allocated a unique ID
for (size_t i = 0; i < mAvailableOutputDevices.size();) {
if (!mAvailableOutputDevices[i]->isAttached()) {
ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
for (size_t i = 0; i < mAvailableInputDevices.size();) {
if (!mAvailableInputDevices[i]->isAttached()) {
ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
mAvailableInputDevices.remove(mAvailableInputDevices[i]);
continue;
}
// The device is now validated and can be appended to the available devices of the engine
mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
i++;
}
// make sure default device is reachable
if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
}
updateDevicesAndOutputs();
}