@ -4397,7 +4397,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
mpClientInterface ( clientInterface ) ,
mLimitRingtoneVolume ( false ) , mLastVoiceVolume ( - 1.0f ) ,
mA2dpSuspended ( false ) ,
mConfig ( mHwModulesAll , m Available OutputDevices, m Available InputDevices, mDefaultOutputDevice ) ,
mConfig ( mHwModulesAll , m OutputDevicesAll , m InputDevicesAll , mDefaultOutputDevice ) ,
mAudioPortGeneration ( 1 ) ,
mBeaconMuteRefCount ( 0 ) ,
mBeaconPlayingRefCount ( 0 ) ,
@ -4442,9 +4442,69 @@ status_t AudioPolicyManager::initialize() {
return status ;
}
// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
// after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
// open all output streams needed to access attached devices
onNewAudioModulesAvailable ( ) ;
// make sure default device is reachable
if ( mDefaultOutputDevice = = 0 | | ! mAvailableOutputDevices . contains ( mDefaultOutputDevice ) ) {
ALOGE_IF ( mDefaultOutputDevice ! = 0 , " Default device %s is unreachable " ,
mDefaultOutputDevice - > toString ( ) . c_str ( ) ) ;
status = NO_INIT ;
}
// If microphones address is empty, set it according to device type
for ( size_t i = 0 ; i < mAvailableInputDevices . size ( ) ; i + + ) {
if ( mAvailableInputDevices [ i ] - > address ( ) . empty ( ) ) {
if ( mAvailableInputDevices [ i ] - > type ( ) = = AUDIO_DEVICE_IN_BUILTIN_MIC ) {
mAvailableInputDevices [ i ] - > setAddress ( AUDIO_BOTTOM_MICROPHONE_ADDRESS ) ;
} else if ( mAvailableInputDevices [ i ] - > type ( ) = = AUDIO_DEVICE_IN_BACK_MIC ) {
mAvailableInputDevices [ i ] - > setAddress ( AUDIO_BACK_MICROPHONE_ADDRESS ) ;
}
}
}
if ( mPrimaryOutput = = 0 ) {
ALOGE ( " Failed to open primary output " ) ;
status = NO_INIT ;
}
// Silence ALOGV statements
property_set ( " log.tag. " LOG_TAG , " D " ) ;
updateDevicesAndOutputs ( ) ;
return status ;
}
AudioPolicyManager : : ~ AudioPolicyManager ( )
{
for ( size_t i = 0 ; i < mOutputs . size ( ) ; i + + ) {
mOutputs . valueAt ( i ) - > close ( ) ;
}
for ( size_t i = 0 ; i < mInputs . size ( ) ; i + + ) {
mInputs . valueAt ( i ) - > close ( ) ;
}
mAvailableOutputDevices . clear ( ) ;
mAvailableInputDevices . clear ( ) ;
mOutputs . clear ( ) ;
mInputs . clear ( ) ;
mHwModules . clear ( ) ;
mHwModulesAll . clear ( ) ;
mManualSurroundFormats . clear ( ) ;
}
status_t AudioPolicyManager : : initCheck ( )
{
return hasPrimaryOutput ( ) ? NO_ERROR : NO_INIT ;
}
// ---
void AudioPolicyManager : : onNewAudioModulesAvailable ( )
{
for ( const auto & hwModule : mHwModulesAll ) {
if ( std : : find ( mHwModules . begin ( ) , mHwModules . end ( ) , hwModule ) ! = mHwModules . end ( ) ) {
continue ;
}
hwModule - > setHandle ( mpClientInterface - > loadHwModule ( hwModule - > getName ( ) ) ) ;
if ( hwModule - > getHandle ( ) = = AUDIO_MODULE_HANDLE_NONE ) {
ALOGW ( " could not open HW module %s " , hwModule - > getName ( ) ) ;
@ -4473,7 +4533,7 @@ status_t AudioPolicyManager::initialize() {
continue ;
}
const DeviceVector & supportedDevices = outProfile - > getSupportedDevices ( ) ;
DeviceVector availProfileDevices = supportedDevices . filter ( m Available OutputDevices) ;
DeviceVector availProfileDevices = supportedDevices . filter ( m OutputDevicesAll ) ;
sp < DeviceDescriptor > supportedDevice = 0 ;
if ( supportedDevices . contains ( mDefaultOutputDevice ) ) {
supportedDevice = mDefaultOutputDevice ;
@ -4485,7 +4545,7 @@ status_t AudioPolicyManager::initialize() {
}
supportedDevice = availProfileDevices . itemAt ( 0 ) ;
}
if ( ! m Available OutputDevices. contains ( supportedDevice ) ) {
if ( ! m OutputDevicesAll . contains ( supportedDevice ) ) {
continue ;
}
sp < SwAudioOutputDescriptor > outputDesc = new SwAudioOutputDescriptor ( outProfile ,
@ -4503,6 +4563,8 @@ status_t AudioPolicyManager::initialize() {
// give a valid ID to an attached device once confirmed it is reachable
if ( ! device - > isAttached ( ) ) {
device - > attach ( hwModule ) ;
mAvailableOutputDevices . add ( device ) ;
setEngineDeviceConnectionState ( device , AUDIO_POLICY_DEVICE_STATE_AVAILABLE ) ;
}
}
if ( mPrimaryOutput = = 0 & &
@ -4531,7 +4593,7 @@ status_t AudioPolicyManager::initialize() {
// chose first device present in profile's SupportedDevices also part of
// available input devices
const DeviceVector & supportedDevices = inProfile - > getSupportedDevices ( ) ;
DeviceVector availProfileDevices = supportedDevices . filter ( m Available InputDevices) ;
DeviceVector availProfileDevices = supportedDevices . filter ( m InputDevicesAll ) ;
if ( availProfileDevices . isEmpty ( ) ) {
ALOGE ( " %s: Input device list is empty! " , __FUNCTION__ ) ;
continue ;
@ -4556,81 +4618,15 @@ status_t AudioPolicyManager::initialize() {
if ( ! device - > isAttached ( ) ) {
device - > attach ( hwModule ) ;
device - > importAudioPortAndPickAudioProfile ( inProfile , true ) ;
}
}
inputDesc - > close ( ) ;
}
}
// make sure all attached devices have been allocated a unique ID
auto checkAndSetAvailable = [ this ] ( auto & devices ) {
for ( size_t i = 0 ; i < devices . size ( ) ; ) {
const auto & device = devices [ i ] ;
if ( ! device - > isAttached ( ) ) {
ALOGW ( " device %s is unreachable " , device - > toString ( ) . c_str ( ) ) ;
devices . remove ( device ) ;
continue ;
}
// Device is now validated and can be appended to the available devices of the engine
mAvailableInputDevices . add ( device ) ;
setEngineDeviceConnectionState ( device , AUDIO_POLICY_DEVICE_STATE_AVAILABLE ) ;
i + + ;
}
} ;
checkAndSetAvailable ( mAvailableOutputDevices ) ;
checkAndSetAvailable ( mAvailableInputDevices ) ;
// make sure default device is reachable
if ( mDefaultOutputDevice = = 0 | | ! mAvailableOutputDevices . contains ( mDefaultOutputDevice ) ) {
ALOGE_IF ( mDefaultOutputDevice ! = 0 , " Default device %s is unreachable " ,
mDefaultOutputDevice - > toString ( ) . c_str ( ) ) ;
status = NO_INIT ;
}
// If microphones address is empty, set it according to device type
for ( size_t i = 0 ; i < mAvailableInputDevices . size ( ) ; i + + ) {
if ( mAvailableInputDevices [ i ] - > address ( ) . empty ( ) ) {
if ( mAvailableInputDevices [ i ] - > type ( ) = = AUDIO_DEVICE_IN_BUILTIN_MIC ) {
mAvailableInputDevices [ i ] - > setAddress ( AUDIO_BOTTOM_MICROPHONE_ADDRESS ) ;
} else if ( mAvailableInputDevices [ i ] - > type ( ) = = AUDIO_DEVICE_IN_BACK_MIC ) {
mAvailableInputDevices [ i ] - > setAddress ( AUDIO_BACK_MICROPHONE_ADDRESS ) ;
}
}
}
if ( mPrimaryOutput = = 0 ) {
ALOGE ( " Failed to open primary output " ) ;
status = NO_INIT ;
}
// Silence ALOGV statements
property_set ( " log.tag. " LOG_TAG , " D " ) ;
updateDevicesAndOutputs ( ) ;
return status ;
}
AudioPolicyManager : : ~ AudioPolicyManager ( )
{
for ( size_t i = 0 ; i < mOutputs . size ( ) ; i + + ) {
mOutputs . valueAt ( i ) - > close ( ) ;
}
for ( size_t i = 0 ; i < mInputs . size ( ) ; i + + ) {
mInputs . valueAt ( i ) - > close ( ) ;
inputDesc - > close ( ) ;
}
mAvailableOutputDevices . clear ( ) ;
mAvailableInputDevices . clear ( ) ;
mOutputs . clear ( ) ;
mInputs . clear ( ) ;
mHwModules . clear ( ) ;
mHwModulesAll . clear ( ) ;
mManualSurroundFormats . clear ( ) ;
}
status_t AudioPolicyManager : : initCheck ( )
{
return hasPrimaryOutput ( ) ? NO_ERROR : NO_INIT ;
}
// ---
void AudioPolicyManager : : addOutput ( audio_io_handle_t output ,
const sp < SwAudioOutputDescriptor > & outputDesc )
{