Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a56b5c26 authored by François Gaffie's avatar François Gaffie Committed by Eric Laurent
Browse files

audiopolicy: engineconfigurable: Migrate to XML criteria and criterion type defintion



Test: make
Change-Id: Ia7eb6b86dffb31bcb4191f5e265e85135934dc36
Signed-off-by: default avatarFrançois Gaffie <francois.gaffie@renault.com>
parent f19cf79e
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -7,10 +7,10 @@
#
################################################################################################

ifeq (1, 0)

LOCAL_PATH := $(call my-dir)

ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)

PFW_CORE := external/parameter-framework
BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
@@ -25,7 +25,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework
LOCAL_SRC_FILES := $(LOCAL_MODULE).in

AUDIO_PATTERN = @TUNING_ALLOWED@
@@ -46,7 +47,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := PolicyClass.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)

@@ -54,12 +56,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE := PolicySubsystem.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
LOCAL_REQUIRED_MODULES := \
    PolicySubsystem-CommonTypes.xml \
    PolicySubsystem-Volume.xml \
    libpolicy-subsystem \
    libpolicy-subsystem

LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)

@@ -67,7 +69,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)

@@ -76,14 +79,15 @@ include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy
LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
LOCAL_ADDITIONAL_DEPENDENCIES := \
LOCAL_REQUIRED_MODULES := \
        PolicyClass.xml \
        PolicySubsystem.xml \
        ParameterFrameworkConfigurationPolicy.xml

ifeq ($(pfw_rebuild_settings),true)
PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
PFW_EDD_FILES := \
        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
@@ -107,18 +111,23 @@ LOCAL_SRC_FILES := Settings/$(LOCAL_MODULE_STEM)
include $(BUILD_PREBUILT)
endif # pfw_rebuild_settings

endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 0)

######### Policy PFW Settings - No Output #########
ifeq (0, 1)

include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy.no-output
LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
LOCAL_ADDITIONAL_DEPENDENCIES := \
LOCAL_REQUIRED_MODULES := \
        PolicyClass.xml \
        PolicySubsystem.xml \
        ParameterFrameworkConfigurationPolicy.xml

PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
PFW_EDD_FILES := \
        $(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
@@ -128,19 +137,22 @@ PFW_EDD_FILES := \
        $(LOCAL_PATH)/Settings/volumes.pfw

include $(BUILD_PFW_SETTINGS)

endif # ifeq (0, 1)
######### Policy PFW Settings - No Input #########
ifeq (0, 1)

include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy.no-input
LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
LOCAL_ADDITIONAL_DEPENDENCIES := \
LOCAL_REQUIRED_MODULES := \
        PolicyClass.xml \
        PolicySubsystem.xml \
        ParameterFrameworkConfigurationPolicy.xml

PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
PFW_EDD_FILES := \
        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
+9 −9
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -37,7 +37,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -65,7 +65,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -93,7 +93,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -121,7 +121,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -149,7 +149,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -177,7 +177,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -205,7 +205,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
@@ -233,7 +233,7 @@ domain: DeviceForStrategy
				bluetooth_sco = 0
				bluetooth_sco_headset = 0
				bluetooth_sco_carkit = 0
				bluetooth_a2dp = 0>
				bluetooth_a2dp = 0
				bluetooth_a2dp_headphones = 0
				bluetooth_a2dp_speaker = 0
				hdmi = 0
+7 −0
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@
            <BitParameter Name="speaker_safe" Size="1" Pos="22"/>
            <BitParameter Name="ip" Size="1" Pos="23"/>
            <BitParameter Name="bus" Size="1" Pos="24"/>
            <BitParameter Name="proxy" Size="1" Pos="25"/>
            <BitParameter Name="usb_headset" Size="1" Pos="26"/>
            <BitParameter Name="hearing_aid" Size="1" Pos="27"/>
            <BitParameter Name="echo_canceller" Size="1" Pos="28"/>
            <BitParameter Name="stub" Size="1" Pos="30"/>
        </BitParameterBlock>
    </ComponentType>
@@ -67,6 +71,9 @@
            <BitParameter Name="loopback" Size="1" Pos="18"/>
            <BitParameter Name="ip" Size="1" Pos="19"/>
            <BitParameter Name="bus" Size="1" Pos="20"/>
            <BitParameter Name="proxy" Size="1" Pos="21"/>
            <BitParameter Name="usb_headset" Size="1" Pos="22"/>
            <BitParameter Name="bluetooth_ble" Size="1" Pos="23"/>
            <BitParameter Name="stub" Size="1" Pos="30"/>
        </BitParameterBlock>
    </ComponentType>
+31 −0
Original line number Diff line number Diff line
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

python_binary_host {
    name: "buildPolicyCriterionTypes.py",
    owner: "renault",
    main: "buildPolicyCriterionTypes.py",
    srcs: [
        "buildPolicyCriterionTypes.py",
    ],
    version: {
        py2: {
            enabled: true,
        },
        py3: {
            enabled: false,
        },
    },
}
+243 −0
Original line number Diff line number Diff line
#!/usr/bin/python

#
# Copyright 2018, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import argparse
import re
import sys
import tempfile
import os
import logging
import subprocess
import xml.etree.ElementTree as ET
import xml.etree.ElementInclude as EI
import xml.dom.minidom as MINIDOM
from collections import OrderedDict

#
# Helper script that helps to feed at build time the XML criterion types file used by
# the engineconfigurable to start the parameter-framework.
# It prevents to fill them manually and avoid divergences with android.
#
# The Device Types criterion types are fed from audio-base.h file with the option
#           --androidaudiobaseheader <path/to/android/audio/base/file/audio-base.h>
#
# The Device Addresses criterion types are fed from the audio policy configuration file
# in order to discover all the devices for which the address matter.
#           --audiopolicyconfigurationfile <path/to/audio_policy_configuration.xml>
#
# The reference file of criterion types must also be set as an input of the script:
#           --criteriontypes <path/to/criterion/file/audio_criterion_types.xml.in>
#
# At last, the output of the script shall be set also:
#           --outputfile <path/to/out/vendor/etc/audio_criterion_types.xml>
#

def parseArgs():
    argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
        audio criterion type file generator.\n\
        Exit with the number of (recoverable or not) error that occured.")
    argparser.add_argument('--androidaudiobaseheader',
            help="Android Audio Base C header file, Mandatory.",
            metavar="ANDROID_AUDIO_BASE_HEADER",
            type=argparse.FileType('r'),
            required=True)
    argparser.add_argument('--audiopolicyconfigurationfile',
            help="Android Audio Policy Configuration file, Mandatory.",
            metavar="(AUDIO_POLICY_CONFIGURATION_FILE)",
            type=argparse.FileType('r'),
            required=True)
    argparser.add_argument('--criteriontypes',
            help="Criterion types XML base file, in \
            '<criterion_types> \
                <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/>' \
        format. Mandatory.",
            metavar="CRITERION_TYPE_FILE",
            type=argparse.FileType('r'),
            required=True)
    argparser.add_argument('--outputfile',
            help="Criterion types outputfile file. Mandatory.",
            metavar="CRITERION_TYPE_OUTPUT_FILE",
            type=argparse.FileType('w'),
            required=True)
    argparser.add_argument('--verbose',
            action='store_true')

    return argparser.parse_args()


def generateXmlCriterionTypesFile(criterionTypes, addressCriteria, criterionTypesFile, outputFile):

    logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
    criterion_types_in_tree = ET.parse(criterionTypesFile)

    criterion_types_root = criterion_types_in_tree.getroot()

    for criterion_name, values_dict in criterionTypes.items():
        for criterion_type in criterion_types_root.findall('criterion_type'):
            if criterion_type.get('name') == criterion_name:
                values_node = ET.SubElement(criterion_type, "values")
                ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
                for key, value in ordered_values.items():
                    value_node = ET.SubElement(values_node, "value")
                    value_node.set('numerical', str(value))
                    value_node.set('literal', key)

    if addressCriteria:
        for criterion_name, values_list in addressCriteria.items():
            for criterion_type in criterion_types_root.findall('criterion_type'):
                if criterion_type.get('name') == criterion_name:
                    values_node = ET.SubElement(criterion_type, "values")
                    index = 0
                    for value in values_list:
                        value_node = ET.SubElement(values_node, "value", literal=value)
                        value_node.set('numerical', str(1 << index))
                        index += 1

    xmlstr = ET.tostring(criterion_types_root, encoding='utf8', method='xml')
    reparsed = MINIDOM.parseString(xmlstr)
    prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
    prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
    outputFile.write(prettyXmlStr.encode('utf-8'))

def capitalizeLine(line):
    return ' '.join((w.capitalize() for w in line.split(' ')))


#
# Parse the audio policy configuration file and output a dictionary of device criteria addresses
#
def parseAndroidAudioPolicyConfigurationFile(audiopolicyconfigurationfile):

    logging.info("Checking Audio Policy Configuration file {}".format(audiopolicyconfigurationfile))
    #
    # extract all devices addresses from audio policy configuration file
    #
    address_criteria_mapping_table = {
        'sink' : "OutputDevicesAddressesType",
        'source' : "InputDevicesAddressesType" }

    address_criteria = {
        'OutputDevicesAddressesType' : [],
        'InputDevicesAddressesType' : [] }

    oldWorkingDir = os.getcwd()
    print "Current working directory %s" % oldWorkingDir

    newDir = os.path.join(oldWorkingDir , audiopolicyconfigurationfile.name)

    policy_in_tree = ET.parse(audiopolicyconfigurationfile)
    os.chdir(os.path.dirname(os.path.normpath(newDir)))

    print "new working directory %s" % os.getcwd()

    policy_root = policy_in_tree.getroot()
    EI.include(policy_root)

    os.chdir(oldWorkingDir)

    for device in policy_root.iter('devicePort'):
        for key in address_criteria_mapping_table.keys():
            if device.get('role') == key and device.get('address') :
                logging.info("{}: <{}>".format(key, device.get('address')))
                address_criteria[address_criteria_mapping_table[key]].append(device.get('address'))

    for criteria in address_criteria:
        values = ','.join(address_criteria[criteria])
        logging.info("{}: <{}>".format(criteria, values))

    return address_criteria

#
# Parse the audio-base.h file and output a dictionary of android dependent criterion types:
#   -Android Mode
#   -Output devices type
#   -Input devices type
#
def parseAndroidAudioFile(androidaudiobaseheaderFile):
    #
    # Adaptation table between Android Enumeration prefix and Audio PFW Criterion type names
    #
    criterion_mapping_table = {
        'AUDIO_MODE' : "AndroidModeType",
        'AUDIO_DEVICE_OUT' : "OutputDevicesMaskType",
        'AUDIO_DEVICE_IN' : "InputDevicesMaskType"}

    all_criteria = {
        'AndroidModeType' : {},
        'OutputDevicesMaskType' : {},
        'InputDevicesMaskType' : {} }

    #
    # _CNT, _MAX, _ALL and _NONE are prohibited values as ther are just helpers for enum users.
    #
    ignored_values = [ 'CNT', 'MAX', 'ALL', 'NONE' ]

    criteria_pattern = re.compile(
        r"\s*(?P<type>(?:"+'|'.join(criterion_mapping_table.keys()) + "))\_" \
        r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*=\s*" \
        r"(?P<values>(?:0[xX])?[0-9a-fA-F]+)")

    logging.info("Checking Android Header file {}".format(androidaudiobaseheaderFile))

    for line_number, line in enumerate(androidaudiobaseheaderFile):
        match = criteria_pattern.match(line)
        if match:
            logging.debug("The following line is VALID: {}:{}\n{}".format(
                androidaudiobaseheaderFile.name, line_number, line))

            criterion_name = criterion_mapping_table[match.groupdict()['type']]
            literal = ''.join((w.capitalize() for w in match.groupdict()['literal'].split('_')))
            numerical_value = match.groupdict()['values']

            # for AUDIO_DEVICE_IN: need to remove sign bit
            if criterion_name == "InputDevicesMaskType":
                numerical_value = str(int(numerical_value, 0) & ~2147483648)

            # Remove duplicated numerical values
            if int(numerical_value, 0) in all_criteria[criterion_name].values():
                logging.info("criterion {} duplicated values:".format(criterion_name))
                logging.info("{}:{}".format(numerical_value, literal))
                logging.info("KEEPING LATEST")
                for key in all_criteria[criterion_name].keys():
                    if all_criteria[criterion_name][key] == int(numerical_value, 0):
                        del all_criteria[criterion_name][key]

            all_criteria[criterion_name][literal] = int(numerical_value, 0)

            logging.debug("type:{},".format(criterion_name))
            logging.debug("iteral:{},".format(literal))
            logging.debug("values:{}.".format(numerical_value))

    return all_criteria


def main():
    logging.root.setLevel(logging.INFO)
    args = parseArgs()

    all_criteria = parseAndroidAudioFile(args.androidaudiobaseheader)

    address_criteria = parseAndroidAudioPolicyConfigurationFile(args.audiopolicyconfigurationfile)

    criterion_types = args.criteriontypes

    generateXmlCriterionTypesFile(all_criteria, address_criteria, criterion_types, args.outputfile)

# If this file is directly executed
if __name__ == "__main__":
    exit(main())
Loading