# # Copyright (C) 2017 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. # """Extracts values from the AndroidManifest.xml file.""" import argparse import os.path import xml.etree.ElementTree def parse_args(): """Parse and return command line arguments.""" parser = argparse.ArgumentParser() parser.add_argument( 'property', metavar='PROPERTY', choices=('minSdkVersion', 'debuggable'), help='Property to extract from the manifest file.') parser.add_argument( 'manifest_file', metavar='MANIFEST_FILE', type=os.path.abspath, help='Path to the AndroidManifest.xml file.') return parser.parse_args() def get_rpath_attribute(root, element_path, attribute, default=None): """Returns the value of an attribute at an rpath. If more than one element exists with the same name, only the first is checked. Args: root: The XML element to search from. path: The path to the element. attribute: The name of the attribute to fetch. Returns: The attribute's value as a string if found, else the value of `default`. """ ns_url = 'http://schemas.android.com/apk/res/android' ns = { 'android': ns_url, } elem = root.find(element_path, ns) if elem is None: return '' # ElementTree elements don't have the same helpful namespace parameter that # the find family does :( attrib_name = attribute.replace('android:', '{' + ns_url + '}') return elem.get(attrib_name, default) def get_minsdkversion(root): """Finds and returns the value of android:minSdkVersion in the manifest. Returns: String form of android:minSdkVersion if found, else the empty string. """ return get_rpath_attribute(root, './uses-sdk', 'android:minSdkVersion', '') def get_debuggable(root): """Finds and returns the value of android:debuggable in the manifest. Returns: String form of android:debuggable if found, else the empty string. """ debuggable = get_rpath_attribute( root, './application', 'android:debuggable', '') # Though any such manifest would be invalid, the awk script rewrote bogus # values to false. Missing attributes should also be false. if debuggable != 'true': debuggable = 'false' return debuggable def main(): args = parse_args() tree = xml.etree.ElementTree.parse(args.manifest_file) if args.property == 'minSdkVersion': print get_minsdkversion(tree.getroot()) elif args.property == 'debuggable': print get_debuggable(tree.getroot()) else: raise ValueError if __name__ == '__main__': main()