Loading services/audiopolicy/enginedefault/src/Engine.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -479,6 +479,37 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy, return devices; } DeviceVector Engine::getPreferredAvailableDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const { DeviceVector preferredAvailableDevVec = {}; AudioDeviceTypeAddrVector preferredDevices; const status_t status = getDevicesForRoleAndCapturePreset( inputSource, DEVICE_ROLE_PREFERRED, preferredDevices); if (status == NO_ERROR) { // Only use preferred devices when they are all available. preferredAvailableDevVec = availableInputDevices.getDevicesFromDeviceTypeAddrVec(preferredDevices); if (preferredAvailableDevVec.size() == preferredDevices.size()) { ALOGVV("%s using pref device %s for source %u", __func__, preferredAvailableDevVec.toString().c_str(), inputSource); return preferredAvailableDevVec; } } return preferredAvailableDevVec; } DeviceVector Engine::getDisabledDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const { DeviceVector disabledDevices = {}; AudioDeviceTypeAddrVector disabledDevicesTypeAddr; const status_t status = getDevicesForRoleAndCapturePreset( inputSource, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr); if (status == NO_ERROR) { disabledDevices = availableInputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr); } return disabledDevices; } sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) const { Loading Loading @@ -510,6 +541,20 @@ sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) } } // Use the preferred device for the input source if it is available. DeviceVector preferredInputDevices = getPreferredAvailableDevicesForInputSource( availableDevices, inputSource); if (!preferredInputDevices.isEmpty()) { // Currently, only support single device for input. The public JAVA API also only // support setting single device as preferred device. In that case, returning the // first device is OK here. return preferredInputDevices[0]; } // Remove the disabled device for the input source from the available input device list. DeviceVector disabledInputDevices = getDisabledDevicesForInputSource( availableDevices, inputSource); availableDevices.remove(disabledInputDevices); audio_devices_t commDeviceType = getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE); Loading services/audiopolicy/enginedefault/src/Engine.h +4 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,10 @@ private: const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; DeviceVector getDisabledDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; DeviceVector getPreferredAvailableDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const; DeviceVector getDisabledDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const; DeviceStrategyMap mDevicesForStrategies; Loading services/audiopolicy/tests/audiopolicymanager_tests.cpp +102 −0 Original line number Diff line number Diff line Loading @@ -2833,6 +2833,108 @@ TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCaptureP mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices)); } TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) { const audio_source_t source = AUDIO_SOURCE_MIC; const device_role_t role = DEVICE_ROLE_PREFERRED; const std::string address = "card=1;device=0"; const std::string deviceName = "randomName"; ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); auto availableDevices = mManager->getAvailableInputDevices(); ASSERT_GT(availableDevices.size(), 1); audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER; attr.source = source; audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId); ASSERT_NE(nullptr, selectedDevice); sp<DeviceDescriptor> preferredDevice = nullptr; for (const auto& device : availableDevices) { if (device != selectedDevice) { preferredDevice = device; break; } } ASSERT_NE(nullptr, preferredDevice); // After setting preferred device for capture preset, the selected device for input should be // the preferred device. ASSERT_EQ(NO_ERROR, mManager->setDevicesRoleForCapturePreset(source, role, {preferredDevice->getDeviceTypeAddr()})); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId)); // After clearing preferred device for capture preset, the selected device for input should be // the same as original one. ASSERT_EQ(NO_ERROR, mManager->clearDevicesRoleForCapturePreset(source, role)); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId)); ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); } TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) { const audio_source_t source = AUDIO_SOURCE_MIC; const device_role_t role = DEVICE_ROLE_DISABLED; const std::string address = "card=1;device=0"; const std::string deviceName = "randomName"; ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); auto availableDevices = mManager->getAvailableInputDevices(); ASSERT_GT(availableDevices.size(), 1); audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER; attr.source = source; audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId); ASSERT_NE(nullptr, selectedDevice); // After setting disabled device for capture preset, the disabled device must not be // selected for input. ASSERT_EQ(NO_ERROR, mManager->setDevicesRoleForCapturePreset(source, role, {selectedDevice->getDeviceTypeAddr()})); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId)); // After clearing disabled device for capture preset, the selected device for input should be // the original one. ASSERT_EQ(NO_ERROR, mManager->clearDevicesRoleForCapturePreset(source, role)); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId)); ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); } INSTANTIATE_TEST_CASE_P( DevicesRoleForCapturePresetOperation, AudioPolicyManagerDevicesRoleForCapturePresetTest, Loading services/audiopolicy/tests/resources/test_audio_policy_configuration.xml +3 −1 Original line number Diff line number Diff line Loading @@ -77,12 +77,14 @@ </devicePort> <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink"> </devicePort> <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source"> </devicePort> </devicePorts> <routes> <route type="mix" sink="Speaker" sources="primary output,voip_rx"/> <route type="mix" sink="primary input" sources="Built-In Mic,Hdmi-In Mic"/> sources="Built-In Mic,Hdmi-In Mic,USB Device In"/> <route type="mix" sink="voip_tx" sources="Built-In Mic"/> <route type="mix" sink="Hdmi" Loading Loading
services/audiopolicy/enginedefault/src/Engine.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -479,6 +479,37 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy, return devices; } DeviceVector Engine::getPreferredAvailableDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const { DeviceVector preferredAvailableDevVec = {}; AudioDeviceTypeAddrVector preferredDevices; const status_t status = getDevicesForRoleAndCapturePreset( inputSource, DEVICE_ROLE_PREFERRED, preferredDevices); if (status == NO_ERROR) { // Only use preferred devices when they are all available. preferredAvailableDevVec = availableInputDevices.getDevicesFromDeviceTypeAddrVec(preferredDevices); if (preferredAvailableDevVec.size() == preferredDevices.size()) { ALOGVV("%s using pref device %s for source %u", __func__, preferredAvailableDevVec.toString().c_str(), inputSource); return preferredAvailableDevVec; } } return preferredAvailableDevVec; } DeviceVector Engine::getDisabledDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const { DeviceVector disabledDevices = {}; AudioDeviceTypeAddrVector disabledDevicesTypeAddr; const status_t status = getDevicesForRoleAndCapturePreset( inputSource, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr); if (status == NO_ERROR) { disabledDevices = availableInputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr); } return disabledDevices; } sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) const { Loading Loading @@ -510,6 +541,20 @@ sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) } } // Use the preferred device for the input source if it is available. DeviceVector preferredInputDevices = getPreferredAvailableDevicesForInputSource( availableDevices, inputSource); if (!preferredInputDevices.isEmpty()) { // Currently, only support single device for input. The public JAVA API also only // support setting single device as preferred device. In that case, returning the // first device is OK here. return preferredInputDevices[0]; } // Remove the disabled device for the input source from the available input device list. DeviceVector disabledInputDevices = getDisabledDevicesForInputSource( availableDevices, inputSource); availableDevices.remove(disabledInputDevices); audio_devices_t commDeviceType = getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE); Loading
services/audiopolicy/enginedefault/src/Engine.h +4 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,10 @@ private: const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; DeviceVector getDisabledDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; DeviceVector getPreferredAvailableDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const; DeviceVector getDisabledDevicesForInputSource( const DeviceVector& availableInputDevices, audio_source_t inputSource) const; DeviceStrategyMap mDevicesForStrategies; Loading
services/audiopolicy/tests/audiopolicymanager_tests.cpp +102 −0 Original line number Diff line number Diff line Loading @@ -2833,6 +2833,108 @@ TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCaptureP mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices)); } TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) { const audio_source_t source = AUDIO_SOURCE_MIC; const device_role_t role = DEVICE_ROLE_PREFERRED; const std::string address = "card=1;device=0"; const std::string deviceName = "randomName"; ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); auto availableDevices = mManager->getAvailableInputDevices(); ASSERT_GT(availableDevices.size(), 1); audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER; attr.source = source; audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId); ASSERT_NE(nullptr, selectedDevice); sp<DeviceDescriptor> preferredDevice = nullptr; for (const auto& device : availableDevices) { if (device != selectedDevice) { preferredDevice = device; break; } } ASSERT_NE(nullptr, preferredDevice); // After setting preferred device for capture preset, the selected device for input should be // the preferred device. ASSERT_EQ(NO_ERROR, mManager->setDevicesRoleForCapturePreset(source, role, {preferredDevice->getDeviceTypeAddr()})); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId)); // After clearing preferred device for capture preset, the selected device for input should be // the same as original one. ASSERT_EQ(NO_ERROR, mManager->clearDevicesRoleForCapturePreset(source, role)); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId)); ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); } TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) { const audio_source_t source = AUDIO_SOURCE_MIC; const device_role_t role = DEVICE_ROLE_DISABLED; const std::string address = "card=1;device=0"; const std::string deviceName = "randomName"; ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); auto availableDevices = mManager->getAvailableInputDevices(); ASSERT_GT(availableDevices.size(), 1); audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER; attr.source = source; audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId); ASSERT_NE(nullptr, selectedDevice); // After setting disabled device for capture preset, the disabled device must not be // selected for input. ASSERT_EQ(NO_ERROR, mManager->setDevicesRoleForCapturePreset(source, role, {selectedDevice->getDeviceTypeAddr()})); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId)); // After clearing disabled device for capture preset, the selected device for input should be // the original one. ASSERT_EQ(NO_ERROR, mManager->clearDevicesRoleForCapturePreset(source, role)); selectedDeviceId = AUDIO_PORT_HANDLE_NONE; ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 48000)); ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId)); ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState( AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT)); } INSTANTIATE_TEST_CASE_P( DevicesRoleForCapturePresetOperation, AudioPolicyManagerDevicesRoleForCapturePresetTest, Loading
services/audiopolicy/tests/resources/test_audio_policy_configuration.xml +3 −1 Original line number Diff line number Diff line Loading @@ -77,12 +77,14 @@ </devicePort> <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink"> </devicePort> <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source"> </devicePort> </devicePorts> <routes> <route type="mix" sink="Speaker" sources="primary output,voip_rx"/> <route type="mix" sink="primary input" sources="Built-In Mic,Hdmi-In Mic"/> sources="Built-In Mic,Hdmi-In Mic,USB Device In"/> <route type="mix" sink="voip_tx" sources="Built-In Mic"/> <route type="mix" sink="Hdmi" Loading