【Android Audio】Parameter Framework - pfw配置介绍

Parameter Framework - Android AudioPolicy Engine

使用 libaudiopolicyengineconfigurable.so 来取缔默认安卓音频引擎 libaudiopolicyenginedefault.so,因为默认安卓音频引擎是通过代码来决定策略,然而 libaudiopolicyengineconfigurable 采用读取pfw类型的文件来实现音频策略配置。

1. 优势

不需要修改代码,直接修改pfw配置文件就可以修改音频策略

2. 启用Parameter framework

Android U之前的版本
audio_policy_configuration.xml文件中 globalConfiguration字段增加字段: engine_library="configurable"
<globalConfiguration speaker_drc_enabled="false" engine_library="configurable" />
Android U之后的版本
使用aidl的hal,读取config的时候检测 audio_policy_engine_criterion_types.xmlaudio_policy_engine_criteria.xml文件存在就会启用

hardware\interfaces\audio\aidl\default\EngineConfigXmlConverter.cpp

void EngineConfigXmlConverter::init() {
...
    if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) {
        AudioHalEngineConfig::CapSpecificConfig capSpecificConfig;
        capSpecificConfig.criteriaV2 =
                std::make_optional<>(VALUE_OR_FATAL((convertCapCriteriaCollectionToAidl(
                        getXsdcConfig()->getCriteria(), getXsdcConfig()->getCriterion_types()))));
...

3. 功能

当前主要是3大配置

    <InstanceDefinition>
        <Component Name="streams" Type="Streams"/>
        <Component Name="input_sources" Type="InputSources"/>
        <Component Name="product_strategies" Type="ProductStrategies"/>
    </InstanceDefinition>

3.1 输入(input_sources)

device_for_input_source.pfw
不同的audio_source_t使用什么样的输入设备

<ComponentType Name="InputSources" Description="associated to audio_source_t definition,
					 identifier mapping must match the value of the enum">
	<Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
	<Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
	<Component Name="voice_uplink" Type="InputSource"
								   Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
	<Component Name="voice_downlink" Type="InputSource"
									 Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
	<Component Name="voice_call" Type="InputSource"
								 Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
	<Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
	<Component Name="voice_recognition" Type="InputSource"
										Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
	<Component Name="voice_communication" Type="InputSource"
										  Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
	<Component Name="remote_submix" Type="InputSource"
									Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
	<Component Name="unprocessed" Type="InputSource"
									Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
	<Component Name="voice_performance" Type="InputSource"
									Mapping="Name:AUDIO_SOURCE_VOICE_PERFORMANCE"/>
	<Component Name="echo_reference" Type="InputSource"
									Mapping="Name:AUDIO_SOURCE_ECHO_REFERENCE"/>
	<Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
	<Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
</ComponentType>

3.2 输出设备优先级(product_strategies)

device_for_product_strategy_phone.pfwdevice_for_product_strategy_media.pfw
不同的product_strategy_t使用什么样的输出设备

<ComponentType Name="ProductStrategies" Description="">
	<Component Name="phone" Type="ProductStrategy" Mapping="Name:STRATEGY_PHONE"/>
	<Component Name="sonification" Type="ProductStrategy" Mapping="Name:STRATEGY_SONIFICATION"/>
	<Component Name="enforced_audible" Type="ProductStrategy" Mapping="Name:STRATEGY_ENFORCED_AUDIBLE"/>
	<Component Name="accessibility" Type="ProductStrategy" Mapping="Name:STRATEGY_ACCESSIBILITY"/>
	<Component Name="sonification_respectful" Type="ProductStrategy" Mapping="Name:STRATEGY_SONIFICATION_RESPECTFUL"/>
	<Component Name="media" Type="ProductStrategy" Mapping="Name:STRATEGY_MEDIA"/>
	<Component Name="dtmf" Type="ProductStrategy" Mapping="Name:STRATEGY_DTMF"/>
	<Component Name="transmitted_through_speaker" Type="ProductStrategy" Mapping="Name:STRATEGY_TRANSMITTED_THROUGH_SPEAKER"/>
	<Component Name="assistant" Type="ProductStrategy" Mapping="Name:STRATEGY_ASSISTANT"/>
</ComponentType>

3.3 音量曲线切换(streams)

volumes.pfw
不同的audio_stream_type_t使用哪个stream type的音量曲线
eg: system的stream可以使用music的音量曲线

<ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
	<Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
	<Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
	<Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
	<Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
	<Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
	<Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
	<Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
	<Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
			   Description="Sounds that cannot be muted by user and must be routed to speaker"/>
	<Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
	<Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
					 Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
	<Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
					 Description="For accessibility talk back prompts"/>
	<Component Name="assistant" Type="Stream" Mapping="Name:AUDIO_STREAM_ASSISTANT"
					 Description="used by a virtual assistant like Google Assistant, Bixby, etc."/>
	<Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
					 Description="For dynamic policy output mixes"/>
	<Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
					 Description="For internal audio flinger tracks. Fixed volume"/>
</ComponentType>

4. 配置pfw文件

4.1 supDomain

  • supDomain定义是对Strategy进行分类命名,可以任意修改
  • 可以定义多级supDomain,生成的xml中是以"."分隔
    (eg: DeviceForProductStrategy.Media)
supDomain: DeviceForProductStrategy
	supDomain: Media
		domain: Device1
			conf: ForceUseBtA2dpSpeaker
				AvailableOutputDevices Includes BLUETOOTH_A2DP_SPEAKER
				ForceUseForMedia Is BT_A2DP
				component: /Policy/policy/product_strategies/vx_1005/selected_output_devices/mask
					speaker = 0
					spdif = 0
					bluetooth_a2dp_speaker = 1
...

4.2 domain

  • supDomain下面可以配置多个domain
  • 多个domain的device是共存的
  • 同一supDomain中不同的domain中不能配置相同的device
    eg:下面Assistant的Strategy中配置了2个domain(Device1、Device2),ARC可以跟其他device共存
supDomain: DeviceForProductStrategy
	supDomain: Assistant
		domain: Device1
			conf: RemoteSubmix
				AvailableOutputDevices Includes REMOTE_SUBMIX
				AvailableOutputDevicesAddresses Includes 0
				component: /Policy/policy/product_strategies/assistant/selected_output_devices/mask
					speaker = 0
					remote_submix = 1
...
		domain: Device2
			#
			# these following domains consists in device(s) that can co-exist with others
			# e.g. ARC, SPDIF, AUX_LINE
			#
			conf: Selected
				AvailableOutputDevices Includes HDMI_ARC
				component: /Policy/policy/product_strategies/assistant/selected_output_devices/mask
					hdmi_arc = 1

			conf: NotSelected
				component: /Policy/policy/product_strategies/assistant/selected_output_devices/mask
					hdmi_arc = 0
...

4.3 config

  • 每一个domain下面的config相当于代码中的switch-case语句。放在前面的config先被执行到。
  • 满足config条件才会被使用,之后不再执行同一domain下的config。如果不满足条件则进行下一个config条件检查。
domain: Device1
	conf: ForceUseBtA2dpSpeaker
		AvailableOutputDevices Includes BLUETOOTH_A2DP_SPEAKER
		ForceUseForMedia Is BT_A2DP
		component: /Policy/policy/product_strategies/vx_1005/selected_output_devices/mask
			speaker = 0
			spdif = 0
			hdmi = 0
			hdmi_arc = 0
			bluetooth_a2dp_speaker = 1
			usb_device = 0
	conf: UsbDevice
		AvailableOutputDevices Includes USB_DEVICE
		component: /Policy/policy/product_strategies/vx_1005/selected_output_devices/mask
			speaker = 0
			spdif = 0
			hdmi = 0
			hdmi_arc = 0
            bluetooth_a2dp_speaker = 0
			usb_device = 1
4.3.1 criterion (准则/标准)

每个criterion 定义: pfw中所有能使用的准则类型 audio_policy_engine_criteria.xml

frameworks/av/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml

<criteria>
    <criterion name="AvailableInputDevices" type="InputDevicesMaskType" default="none"/>
    <criterion name="AvailableOutputDevices" type="OutputDevicesMaskType" default="none"/>
    <criterion name="ForceUseForMedia" type="ForceUseForMediaType" default="ForceNone"/>
...
</criteria>
4.3.2 每个criterion的值:每个准则类型的值

/vendor/etc/audio_policy_engine_criteria.xmlaudio_policy_engine_criterion_typespython脚本根据audio_policy_engine_criterion_types.xml.in文件自动生成。

  • Android 16使用Google最新的capBuildPolicyCriterionTypes.py,之前安卓版本使用buildPolicyCriterionTypes.py的Python脚本。

frameworks/av/services/audiopolicy/engineconfigurable/tools/

frameworks/av/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in

<criterion_types>
        <criterion_type name="OutputDevicesMaskType" type="inclusive">
                <values>
                        <value literal="EARPIECE" android_type="0x1"/>
                        <value literal="SPEAKER" android_type="0x2"/>
                        <value literal="WIRED_HEADSET" android_type="0x4"/>
                        <value literal="WIRED_HEADPHONE" android_type="0x8"/>
                        <value literal="BLUETOOTH_SCO" android_type="0x10"/>
                        <value literal="BLUETOOTH_SCO_HEADSET" android_type="0x20"/>
                        <value literal="BLUETOOTH_SCO_CARKIT" android_type="0x40"/>
                        <value literal="BLUETOOTH_A2DP" android_type="0x80"/>
                        <value literal="BLUETOOTH_A2DP_HEADPHONES" android_type="0x100"/>
                        <value literal="BLUETOOTH_A2DP_SPEAKER" android_type="0x200"/>
                </values>
        </criterion_type>
...
    <criterion_type name="ForceUseForMediaType" type="exclusive">
        <values>
            <value literal="ForceNone" numerical="0"/>
            <value literal="ForceSpeaker" numerical="1"/>
            <value literal="ForceHeadphones" numerical="2"/>
            <value literal="ForceBtA2dp" numerical="4"/>
            <value literal="ForceWiredAccessory" numerical="5"/>
            <value literal="ForceAnalogDock" numerical="8"/>
            <value literal="ForceDigitalDock" numerical="9"/>
            <value literal="ForceNoBtA2dp" numerical="10"/>
        </values>
    </criterion_type>
...

4.3.3 使用criterion

例如:配置输出设备策略

    conf: UsbDevice
        AvailableOutputDevices Includes USB_DEVICE
		AvailableOutputDevices Excludes WIRED_HEADPHONE
        ANY
            ForceUseForCommunication Is BT_SCO
            ALL
                ForceUseForCommunication Is SPEAKER
                TelephonyMode IsNot IN_CALL
				component: /Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
...
					usb_accessory = 0
					usb_device = 1
					usb_headset = 0
					speaker = 0
...

上面的config转化为伪代码的case:

if (AvailableOutputDevices 存在 USB_DEVICE) {
    if (AvailableOutputDevices 不存在 WIRED_HEADPHONE) {
        if (ForceUseForCommunication == BT_SCO ||
        (ForceUseForCommunication == SPEAKER && TelephonyMode != IN_CALL)) {
            return USB_DEVICE;
        }
    }
}

当前Google pfw支持3个SubSystem(Stream、InputSource、ProductStrategy)

frameworks\av\services\audiopolicy\engineconfigurable\parameter-framework\plugin\PolicySubsystem.cpp

    // Provide creators to upper layer
    addSubsystemObjectFactory(
        new TSubsystemObjectFactory<Stream>(
            mStreamComponentName,
            (1 << MappingKeyName))
        );
    addSubsystemObjectFactory(
        new TSubsystemObjectFactory<InputSource>(
            mInputSourceComponentName,
            (1 << MappingKeyName))
        );
    addSubsystemObjectFactory(
        new TSubsystemObjectFactory<ProductStrategy>(
            mProductStrategyComponentName, (1 << MappingKeyName))
        );

分别通过下面3个函数推送到Engine中

frameworks\av\services\audiopolicy\engineconfigurable\parameter-framework\plugin\

Stream::sendToHW
Engine::setVolumeProfileForStream
InputSource::sendToHW
Engine::setDeviceForInputSource
ProductStrategy::sendToHW
Engine::setDeviceTypesForProductStrategy
Engine::setDeviceAddressForProductStrategy

/vendor/etc/parameter-framework/Structure/Policy/PolicySubsystem-CommonTypes.xml

5.1 快速debug

修改完对应的pfw文件之后
parameter framework的pfw所在路径下mm -j,将/vendor/etc/parameter-framework/目录替换到平台即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值