Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/python
      2 
      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 
     19 import argparse
     20 import re
     21 import sys
     22 import tempfile
     23 import os
     24 import logging
     25 import subprocess
     26 import xml.etree.ElementTree as ET
     27 import xml.etree.ElementInclude as EI
     28 import xml.dom.minidom as MINIDOM
     29 from collections import OrderedDict
     30 
     31 #
     32 # Helper script that helps to feed at build time the XML Product Strategies Structure file file used
     33 # by the engineconfigurable to start the parameter-framework.
     34 # It prevents to fill them manually and avoid divergences with android.
     35 #
     36 # The Product Strategies Structure file is fed from the audio policy engine configuration file
     37 # in order to discover all the strategies available for the current platform.
     38 #           --audiopolicyengineconfigurationfile <path/to/audio_policy_engine_configuration.xml>
     39 #
     40 # The reference file of ProductStrategies structure must also be set as an input of the script:
     41 #           --productstrategiesstructurefile <path/to/structure/file/ProductStrategies.xml.in>
     42 #
     43 # At last, the output of the script shall be set also:
     44 #           --outputfile <path/to/out/<system|vendor|odm>/etc/ProductStrategies.xml>
     45 #
     46 
     47 def parseArgs():
     48     argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
     49         product strategies structure file generator.\n\
     50         Exit with the number of (recoverable or not) error that occured.")
     51     argparser.add_argument('--audiopolicyengineconfigurationfile',
     52             help="Android Audio Policy Engine Configuration file, Mandatory.",
     53             metavar="(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)",
     54             type=argparse.FileType('r'),
     55             required=True)
     56     argparser.add_argument('--productstrategiesstructurefile',
     57             help="Product Strategies Structure XML base file, Mandatory.",
     58             metavar="STRATEGIES_STRUCTURE_FILE",
     59             type=argparse.FileType('r'),
     60             required=True)
     61     argparser.add_argument('--outputfile',
     62             help="Product Strategies Structure output file, Mandatory.",
     63             metavar="STRATEGIES_STRUCTURE_OUTPUT_FILE",
     64             type=argparse.FileType('w'),
     65             required=True)
     66     argparser.add_argument('--verbose',
     67             action='store_true')
     68 
     69     return argparser.parse_args()
     70 
     71 
     72 def generateXmlStructureFile(strategies, strategyStructureInFile, outputFile):
     73 
     74     logging.info("Importing strategyStructureInFile {}".format(strategyStructureInFile))
     75     strategies_in_tree = ET.parse(strategyStructureInFile)
     76 
     77     strategies_root = strategies_in_tree.getroot()
     78     strategy_components = strategies_root.find('ComponentType')
     79 
     80     for strategy_name in strategies:
     81         context_mapping = "".join(map(str, ["Name:", strategy_name]))
     82         strategy_pfw_name = strategy_name.replace('STRATEGY_', '').lower()
     83         strategy_component_node = ET.SubElement(strategy_components, "Component", Name=strategy_pfw_name, Type="ProductStrategy", Mapping=context_mapping)
     84 
     85     xmlstr = ET.tostring(strategies_root, encoding='utf8', method='xml')
     86     reparsed = MINIDOM.parseString(xmlstr)
     87     prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
     88     prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
     89     outputFile.write(prettyXmlStr.encode('utf-8'))
     90 
     91 def capitalizeLine(line):
     92     return ' '.join((w.capitalize() for w in line.split(' ')))
     93 
     94 
     95 #
     96 # Parse the audio policy configuration file and output a dictionary of device criteria addresses
     97 #
     98 def parseAndroidAudioPolicyEngineConfigurationFile(audiopolicyengineconfigurationfile):
     99 
    100     logging.info("Checking Audio Policy Engine Configuration file {}".format(audiopolicyengineconfigurationfile))
    101     #
    102     # extract all product strategies name from audio policy engine configuration file
    103     #
    104     strategy_names = []
    105 
    106     oldWorkingDir = os.getcwd()
    107     print "Current working directory %s" % oldWorkingDir
    108 
    109     newDir = os.path.join(oldWorkingDir , audiopolicyengineconfigurationfile.name)
    110 
    111     policy_engine_in_tree = ET.parse(audiopolicyengineconfigurationfile)
    112     os.chdir(os.path.dirname(os.path.normpath(newDir)))
    113 
    114     print "new working directory %s" % os.getcwd()
    115 
    116     policy_engine_root = policy_engine_in_tree.getroot()
    117     EI.include(policy_engine_root)
    118 
    119     os.chdir(oldWorkingDir)
    120 
    121     for strategy in policy_engine_root.iter('ProductStrategy'):
    122         strategy_names.append(strategy.get('name'))
    123 
    124     return strategy_names
    125 
    126 
    127 def main():
    128     logging.root.setLevel(logging.INFO)
    129     args = parseArgs()
    130 
    131     strategies = parseAndroidAudioPolicyEngineConfigurationFile(args.audiopolicyengineconfigurationfile)
    132 
    133     product_strategies_structure = args.productstrategiesstructurefile
    134 
    135     generateXmlStructureFile(strategies, product_strategies_structure, args.outputfile)
    136 
    137 # If this file is directly executed
    138 if __name__ == "__main__":
    139     sys.exit(main())
    140