blob: f69d346db92935ae4ada8e184e1dbca019a24903 [file] [log] [blame]
Francois Gaffie31987fb2019-09-03 11:57:33 +02001#!/usr/bin/python3
Francois Gaffie7d602f02019-02-13 10:37:49 +01002
3#
4# Copyright 2019, The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import argparse
Francois Gaffie7d602f02019-02-13 10:37:49 +010020import sys
Francois Gaffie7d602f02019-02-13 10:37:49 +010021import os
22import logging
Francois Gaffie7d602f02019-02-13 10:37:49 +010023import xml.etree.ElementTree as ET
24import xml.etree.ElementInclude as EI
25import xml.dom.minidom as MINIDOM
Francois Gaffie7d602f02019-02-13 10:37:49 +010026
27#
28# Helper script that helps to feed at build time the XML Product Strategies Structure file file used
29# by the engineconfigurable to start the parameter-framework.
30# It prevents to fill them manually and avoid divergences with android.
31#
32# The Product Strategies Structure file is fed from the audio policy engine configuration file
33# in order to discover all the strategies available for the current platform.
34# --audiopolicyengineconfigurationfile <path/to/audio_policy_engine_configuration.xml>
35#
36# The reference file of ProductStrategies structure must also be set as an input of the script:
37# --productstrategiesstructurefile <path/to/structure/file/ProductStrategies.xml.in>
38#
39# At last, the output of the script shall be set also:
40# --outputfile <path/to/out/<system|vendor|odm>/etc/ProductStrategies.xml>
41#
42
43def parseArgs():
44 argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
Francois Gaffie31987fb2019-09-03 11:57:33 +020045 product strategies structure file generator.\n\
46 Exit with the number of (recoverable or not) \
47 error that occured.")
Francois Gaffie7d602f02019-02-13 10:37:49 +010048 argparser.add_argument('--audiopolicyengineconfigurationfile',
Francois Gaffie31987fb2019-09-03 11:57:33 +020049 help="Android Audio Policy Engine Configuration file, Mandatory.",
50 metavar="(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)",
51 type=argparse.FileType('r'),
52 required=True)
Francois Gaffie7d602f02019-02-13 10:37:49 +010053 argparser.add_argument('--productstrategiesstructurefile',
Francois Gaffie31987fb2019-09-03 11:57:33 +020054 help="Product Strategies Structure XML base file, Mandatory.",
55 metavar="STRATEGIES_STRUCTURE_FILE",
56 type=argparse.FileType('r'),
57 required=True)
Francois Gaffie7d602f02019-02-13 10:37:49 +010058 argparser.add_argument('--outputfile',
Francois Gaffie31987fb2019-09-03 11:57:33 +020059 help="Product Strategies Structure output file, Mandatory.",
60 metavar="STRATEGIES_STRUCTURE_OUTPUT_FILE",
61 type=argparse.FileType('w'),
62 required=True)
Francois Gaffie7d602f02019-02-13 10:37:49 +010063 argparser.add_argument('--verbose',
Francois Gaffie31987fb2019-09-03 11:57:33 +020064 action='store_true')
Francois Gaffie7d602f02019-02-13 10:37:49 +010065
66 return argparser.parse_args()
67
68
Francois Gaffie31987fb2019-09-03 11:57:33 +020069def generateXmlStructureFile(strategies, strategy_structure_in_file, output_file):
Francois Gaffie7d602f02019-02-13 10:37:49 +010070
Francois Gaffie31987fb2019-09-03 11:57:33 +020071 logging.info("Importing strategy_structure_in_file {}".format(strategy_structure_in_file))
72 strategies_in_tree = ET.parse(strategy_structure_in_file)
Francois Gaffie7d602f02019-02-13 10:37:49 +010073
74 strategies_root = strategies_in_tree.getroot()
75 strategy_components = strategies_root.find('ComponentType')
76
77 for strategy_name in strategies:
78 context_mapping = "".join(map(str, ["Name:", strategy_name]))
79 strategy_pfw_name = strategy_name.replace('STRATEGY_', '').lower()
Francois Gaffie31987fb2019-09-03 11:57:33 +020080 ET.SubElement(strategy_components, "Component",
81 Name=strategy_pfw_name, Type="ProductStrategy",
82 Mapping=context_mapping)
Francois Gaffie7d602f02019-02-13 10:37:49 +010083
84 xmlstr = ET.tostring(strategies_root, encoding='utf8', method='xml')
85 reparsed = MINIDOM.parseString(xmlstr)
86 prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
87 prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
Francois Gaffie31987fb2019-09-03 11:57:33 +020088 output_file.write(prettyXmlStr)
Francois Gaffie7d602f02019-02-13 10:37:49 +010089
90def capitalizeLine(line):
91 return ' '.join((w.capitalize() for w in line.split(' ')))
92
93
94#
95# Parse the audio policy configuration file and output a dictionary of device criteria addresses
96#
97def parseAndroidAudioPolicyEngineConfigurationFile(audiopolicyengineconfigurationfile):
98
Francois Gaffie31987fb2019-09-03 11:57:33 +020099 logging.info("Checking Audio Policy Engine Configuration file {}".format(
100 audiopolicyengineconfigurationfile))
Francois Gaffie7d602f02019-02-13 10:37:49 +0100101 #
102 # extract all product strategies name from audio policy engine configuration file
103 #
104 strategy_names = []
105
Francois Gaffie31987fb2019-09-03 11:57:33 +0200106 old_working_dir = os.getcwd()
107 print("Current working directory %s" % old_working_dir)
Francois Gaffie7d602f02019-02-13 10:37:49 +0100108
Francois Gaffie31987fb2019-09-03 11:57:33 +0200109 new_dir = os.path.join(old_working_dir, audiopolicyengineconfigurationfile.name)
Francois Gaffie7d602f02019-02-13 10:37:49 +0100110
111 policy_engine_in_tree = ET.parse(audiopolicyengineconfigurationfile)
Francois Gaffie31987fb2019-09-03 11:57:33 +0200112 os.chdir(os.path.dirname(os.path.normpath(new_dir)))
Francois Gaffie7d602f02019-02-13 10:37:49 +0100113
Francois Gaffie31987fb2019-09-03 11:57:33 +0200114 print("new working directory %s" % os.getcwd())
Francois Gaffie7d602f02019-02-13 10:37:49 +0100115
116 policy_engine_root = policy_engine_in_tree.getroot()
117 EI.include(policy_engine_root)
118
Francois Gaffie31987fb2019-09-03 11:57:33 +0200119 os.chdir(old_working_dir)
Francois Gaffie7d602f02019-02-13 10:37:49 +0100120
121 for strategy in policy_engine_root.iter('ProductStrategy'):
122 strategy_names.append(strategy.get('name'))
123
124 return strategy_names
125
126
127def main():
128 logging.root.setLevel(logging.INFO)
129 args = parseArgs()
130
Francois Gaffie31987fb2019-09-03 11:57:33 +0200131 strategies = parseAndroidAudioPolicyEngineConfigurationFile(
132 args.audiopolicyengineconfigurationfile)
Francois Gaffie7d602f02019-02-13 10:37:49 +0100133
134 product_strategies_structure = args.productstrategiesstructurefile
135
136 generateXmlStructureFile(strategies, product_strategies_structure, args.outputfile)
137
138# If this file is directly executed
139if __name__ == "__main__":
François Gaffiedf7f0a22019-04-02 17:42:15 +0200140 sys.exit(main())