1*333d2b36SAndroid Build Coastguard Worker#!/usr/bin/env python 2*333d2b36SAndroid Build Coastguard Worker# 3*333d2b36SAndroid Build Coastguard Worker# Copyright (C) 2018 The Android Open Source Project 4*333d2b36SAndroid Build Coastguard Worker# 5*333d2b36SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*333d2b36SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*333d2b36SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*333d2b36SAndroid Build Coastguard Worker# 9*333d2b36SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*333d2b36SAndroid Build Coastguard Worker# 11*333d2b36SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*333d2b36SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*333d2b36SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*333d2b36SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*333d2b36SAndroid Build Coastguard Worker# limitations under the License. 16*333d2b36SAndroid Build Coastguard Worker# 17*333d2b36SAndroid Build Coastguard Worker"""A tool for inserting values from the build system into a manifest.""" 18*333d2b36SAndroid Build Coastguard Worker 19*333d2b36SAndroid Build Coastguard Workerimport argparse 20*333d2b36SAndroid Build Coastguard Workerimport sys 21*333d2b36SAndroid Build Coastguard Workerfrom xml.dom import minidom 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Workerfrom manifest import * 25*333d2b36SAndroid Build Coastguard Worker 26*333d2b36SAndroid Build Coastguard Workerdef parse_args(): 27*333d2b36SAndroid Build Coastguard Worker """Parse commandline arguments.""" 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 30*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--minSdkVersion', default='', dest='min_sdk_version', 31*333d2b36SAndroid Build Coastguard Worker help='specify minSdkVersion used by the build system') 32*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--replaceMaxSdkVersionPlaceholder', default='', dest='max_sdk_version', 33*333d2b36SAndroid Build Coastguard Worker help='specify maxSdkVersion used by the build system') 34*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--targetSdkVersion', default='', dest='target_sdk_version', 35*333d2b36SAndroid Build Coastguard Worker help='specify targetSdkVersion used by the build system') 36*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--raise-min-sdk-version', dest='raise_min_sdk_version', action='store_true', 37*333d2b36SAndroid Build Coastguard Worker help='raise the minimum sdk version in the manifest if necessary') 38*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--library', dest='library', action='store_true', 39*333d2b36SAndroid Build Coastguard Worker help='manifest is for a static library') 40*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--uses-library', dest='uses_libraries', action='append', 41*333d2b36SAndroid Build Coastguard Worker help='specify additional <uses-library> tag to add. android:required is set to true') 42*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--optional-uses-library', dest='optional_uses_libraries', action='append', 43*333d2b36SAndroid Build Coastguard Worker help='specify additional <uses-library> tag to add. android:required is set to false') 44*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true', 45*333d2b36SAndroid Build Coastguard Worker help='manifest is for a package built against the platform') 46*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--logging-parent', dest='logging_parent', default='', 47*333d2b36SAndroid Build Coastguard Worker help=('specify logging parent as an additional <meta-data> tag. ' 48*333d2b36SAndroid Build Coastguard Worker 'This value is ignored if the logging_parent meta-data tag is present.')) 49*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--use-embedded-dex', dest='use_embedded_dex', action='store_true', 50*333d2b36SAndroid Build Coastguard Worker help=('specify if the app wants to use embedded dex and avoid extracted,' 51*333d2b36SAndroid Build Coastguard Worker 'locally compiled code. Must not conflict if already declared ' 52*333d2b36SAndroid Build Coastguard Worker 'in the manifest.')) 53*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--extract-native-libs', dest='extract_native_libs', 54*333d2b36SAndroid Build Coastguard Worker default=None, type=lambda x: (str(x).lower() == 'true'), 55*333d2b36SAndroid Build Coastguard Worker help=('specify if the app wants to use embedded native libraries. Must not conflict ' 56*333d2b36SAndroid Build Coastguard Worker 'if already declared in the manifest.')) 57*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--has-no-code', dest='has_no_code', action='store_true', 58*333d2b36SAndroid Build Coastguard Worker help=('adds hasCode="false" attribute to application. Ignored if application elem ' 59*333d2b36SAndroid Build Coastguard Worker 'already has a hasCode attribute.')) 60*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--test-only', dest='test_only', action='store_true', 61*333d2b36SAndroid Build Coastguard Worker help=('adds testOnly="true" attribute to application. Assign true value if application elem ' 62*333d2b36SAndroid Build Coastguard Worker 'already has a testOnly attribute.')) 63*333d2b36SAndroid Build Coastguard Worker parser.add_argument('--override-placeholder-version', dest='new_version', 64*333d2b36SAndroid Build Coastguard Worker help='Overrides the versionCode if it\'s set to the placeholder value of 0') 65*333d2b36SAndroid Build Coastguard Worker parser.add_argument('input', help='input AndroidManifest.xml file') 66*333d2b36SAndroid Build Coastguard Worker parser.add_argument('output', help='output AndroidManifest.xml file') 67*333d2b36SAndroid Build Coastguard Worker return parser.parse_args() 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Worker 70*333d2b36SAndroid Build Coastguard Workerdef raise_min_sdk_version(doc, min_sdk_version, target_sdk_version, library): 71*333d2b36SAndroid Build Coastguard Worker """Ensure the manifest contains a <uses-sdk> tag with a minSdkVersion. 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Worker Args: 74*333d2b36SAndroid Build Coastguard Worker doc: The XML document. May be modified by this function. 75*333d2b36SAndroid Build Coastguard Worker min_sdk_version: The requested minSdkVersion attribute. 76*333d2b36SAndroid Build Coastguard Worker target_sdk_version: The requested targetSdkVersion attribute. 77*333d2b36SAndroid Build Coastguard Worker library: True if the manifest is for a library. 78*333d2b36SAndroid Build Coastguard Worker Raises: 79*333d2b36SAndroid Build Coastguard Worker RuntimeError: invalid manifest 80*333d2b36SAndroid Build Coastguard Worker """ 81*333d2b36SAndroid Build Coastguard Worker 82*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 83*333d2b36SAndroid Build Coastguard Worker 84*333d2b36SAndroid Build Coastguard Worker for uses_sdk in get_or_create_uses_sdks(doc, manifest): 85*333d2b36SAndroid Build Coastguard Worker # Get or insert the minSdkVersion attribute. If it is already present, make 86*333d2b36SAndroid Build Coastguard Worker # sure it as least the requested value. 87*333d2b36SAndroid Build Coastguard Worker min_attr = uses_sdk.getAttributeNodeNS(android_ns, 'minSdkVersion') 88*333d2b36SAndroid Build Coastguard Worker if min_attr is None: 89*333d2b36SAndroid Build Coastguard Worker min_attr = doc.createAttributeNS(android_ns, 'android:minSdkVersion') 90*333d2b36SAndroid Build Coastguard Worker min_attr.value = min_sdk_version 91*333d2b36SAndroid Build Coastguard Worker uses_sdk.setAttributeNode(min_attr) 92*333d2b36SAndroid Build Coastguard Worker else: 93*333d2b36SAndroid Build Coastguard Worker if compare_version_gt(min_sdk_version, min_attr.value): 94*333d2b36SAndroid Build Coastguard Worker min_attr.value = min_sdk_version 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker # Insert the targetSdkVersion attribute if it is missing. If it is already 97*333d2b36SAndroid Build Coastguard Worker # present leave it as is. 98*333d2b36SAndroid Build Coastguard Worker target_attr = uses_sdk.getAttributeNodeNS(android_ns, 'targetSdkVersion') 99*333d2b36SAndroid Build Coastguard Worker if target_attr is None: 100*333d2b36SAndroid Build Coastguard Worker target_attr = doc.createAttributeNS(android_ns, 'android:targetSdkVersion') 101*333d2b36SAndroid Build Coastguard Worker if library: 102*333d2b36SAndroid Build Coastguard Worker # TODO(b/117122200): libraries shouldn't set targetSdkVersion at all, but 103*333d2b36SAndroid Build Coastguard Worker # ManifestMerger treats minSdkVersion="Q" as targetSdkVersion="Q" if it 104*333d2b36SAndroid Build Coastguard Worker # is empty. Set it to something low so that it will be overridden by the 105*333d2b36SAndroid Build Coastguard Worker # main manifest, but high enough that it doesn't cause implicit 106*333d2b36SAndroid Build Coastguard Worker # permissions grants. 107*333d2b36SAndroid Build Coastguard Worker target_attr.value = '16' 108*333d2b36SAndroid Build Coastguard Worker else: 109*333d2b36SAndroid Build Coastguard Worker target_attr.value = target_sdk_version 110*333d2b36SAndroid Build Coastguard Worker uses_sdk.setAttributeNode(target_attr) 111*333d2b36SAndroid Build Coastguard Worker 112*333d2b36SAndroid Build Coastguard Worker 113*333d2b36SAndroid Build Coastguard Workerdef add_logging_parent(doc, logging_parent_value): 114*333d2b36SAndroid Build Coastguard Worker """Add logging parent as an additional <meta-data> tag. 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Worker Args: 117*333d2b36SAndroid Build Coastguard Worker doc: The XML document. May be modified by this function. 118*333d2b36SAndroid Build Coastguard Worker logging_parent_value: A string representing the logging 119*333d2b36SAndroid Build Coastguard Worker parent value. 120*333d2b36SAndroid Build Coastguard Worker Raises: 121*333d2b36SAndroid Build Coastguard Worker RuntimeError: Invalid manifest 122*333d2b36SAndroid Build Coastguard Worker """ 123*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Worker logging_parent_key = 'android.content.pm.LOGGING_PARENT' 126*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 127*333d2b36SAndroid Build Coastguard Worker indent = get_indent(application.firstChild, 2) 128*333d2b36SAndroid Build Coastguard Worker 129*333d2b36SAndroid Build Coastguard Worker last = application.lastChild 130*333d2b36SAndroid Build Coastguard Worker if last is not None and last.nodeType != minidom.Node.TEXT_NODE: 131*333d2b36SAndroid Build Coastguard Worker last = None 132*333d2b36SAndroid Build Coastguard Worker 133*333d2b36SAndroid Build Coastguard Worker if not find_child_with_attribute(application, 'meta-data', android_ns, 134*333d2b36SAndroid Build Coastguard Worker 'name', logging_parent_key): 135*333d2b36SAndroid Build Coastguard Worker ul = doc.createElement('meta-data') 136*333d2b36SAndroid Build Coastguard Worker ul.setAttributeNS(android_ns, 'android:name', logging_parent_key) 137*333d2b36SAndroid Build Coastguard Worker ul.setAttributeNS(android_ns, 'android:value', logging_parent_value) 138*333d2b36SAndroid Build Coastguard Worker application.insertBefore(doc.createTextNode(indent), last) 139*333d2b36SAndroid Build Coastguard Worker application.insertBefore(ul, last) 140*333d2b36SAndroid Build Coastguard Worker last = application.lastChild 141*333d2b36SAndroid Build Coastguard Worker 142*333d2b36SAndroid Build Coastguard Worker # align the closing tag with the opening tag if it's not 143*333d2b36SAndroid Build Coastguard Worker # indented 144*333d2b36SAndroid Build Coastguard Worker if last and last.nodeType != minidom.Node.TEXT_NODE: 145*333d2b36SAndroid Build Coastguard Worker indent = get_indent(application.previousSibling, 1) 146*333d2b36SAndroid Build Coastguard Worker application.appendChild(doc.createTextNode(indent)) 147*333d2b36SAndroid Build Coastguard Worker 148*333d2b36SAndroid Build Coastguard Worker 149*333d2b36SAndroid Build Coastguard Workerdef add_uses_libraries(doc, new_uses_libraries, required): 150*333d2b36SAndroid Build Coastguard Worker """Add additional <uses-library> tags 151*333d2b36SAndroid Build Coastguard Worker 152*333d2b36SAndroid Build Coastguard Worker Args: 153*333d2b36SAndroid Build Coastguard Worker doc: The XML document. May be modified by this function. 154*333d2b36SAndroid Build Coastguard Worker new_uses_libraries: The names of libraries to be added by this function. 155*333d2b36SAndroid Build Coastguard Worker required: The value of android:required attribute. Can be true or false. 156*333d2b36SAndroid Build Coastguard Worker Raises: 157*333d2b36SAndroid Build Coastguard Worker RuntimeError: Invalid manifest 158*333d2b36SAndroid Build Coastguard Worker """ 159*333d2b36SAndroid Build Coastguard Worker 160*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 161*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 162*333d2b36SAndroid Build Coastguard Worker indent = get_indent(application.firstChild, 2) 163*333d2b36SAndroid Build Coastguard Worker 164*333d2b36SAndroid Build Coastguard Worker last = application.lastChild 165*333d2b36SAndroid Build Coastguard Worker if last is not None and last.nodeType != minidom.Node.TEXT_NODE: 166*333d2b36SAndroid Build Coastguard Worker last = None 167*333d2b36SAndroid Build Coastguard Worker 168*333d2b36SAndroid Build Coastguard Worker for name in new_uses_libraries: 169*333d2b36SAndroid Build Coastguard Worker if find_child_with_attribute(application, 'uses-library', android_ns, 170*333d2b36SAndroid Build Coastguard Worker 'name', name) is not None: 171*333d2b36SAndroid Build Coastguard Worker # If the uses-library tag of the same 'name' attribute value exists, 172*333d2b36SAndroid Build Coastguard Worker # respect it. 173*333d2b36SAndroid Build Coastguard Worker continue 174*333d2b36SAndroid Build Coastguard Worker 175*333d2b36SAndroid Build Coastguard Worker ul = doc.createElement('uses-library') 176*333d2b36SAndroid Build Coastguard Worker ul.setAttributeNS(android_ns, 'android:name', name) 177*333d2b36SAndroid Build Coastguard Worker ul.setAttributeNS(android_ns, 'android:required', str(required).lower()) 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker application.insertBefore(doc.createTextNode(indent), last) 180*333d2b36SAndroid Build Coastguard Worker application.insertBefore(ul, last) 181*333d2b36SAndroid Build Coastguard Worker 182*333d2b36SAndroid Build Coastguard Worker # align the closing tag with the opening tag if it's not 183*333d2b36SAndroid Build Coastguard Worker # indented 184*333d2b36SAndroid Build Coastguard Worker if application.lastChild.nodeType != minidom.Node.TEXT_NODE: 185*333d2b36SAndroid Build Coastguard Worker indent = get_indent(application.previousSibling, 1) 186*333d2b36SAndroid Build Coastguard Worker application.appendChild(doc.createTextNode(indent)) 187*333d2b36SAndroid Build Coastguard Worker 188*333d2b36SAndroid Build Coastguard Worker 189*333d2b36SAndroid Build Coastguard Workerdef add_uses_non_sdk_api(doc): 190*333d2b36SAndroid Build Coastguard Worker """Add android:usesNonSdkApi=true attribute to <application>. 191*333d2b36SAndroid Build Coastguard Worker 192*333d2b36SAndroid Build Coastguard Worker Args: 193*333d2b36SAndroid Build Coastguard Worker doc: The XML document. May be modified by this function. 194*333d2b36SAndroid Build Coastguard Worker Raises: 195*333d2b36SAndroid Build Coastguard Worker RuntimeError: Invalid manifest 196*333d2b36SAndroid Build Coastguard Worker """ 197*333d2b36SAndroid Build Coastguard Worker 198*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 199*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 200*333d2b36SAndroid Build Coastguard Worker attr = application.getAttributeNodeNS(android_ns, 'usesNonSdkApi') 201*333d2b36SAndroid Build Coastguard Worker if attr is None: 202*333d2b36SAndroid Build Coastguard Worker attr = doc.createAttributeNS(android_ns, 'android:usesNonSdkApi') 203*333d2b36SAndroid Build Coastguard Worker attr.value = 'true' 204*333d2b36SAndroid Build Coastguard Worker application.setAttributeNode(attr) 205*333d2b36SAndroid Build Coastguard Worker 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Workerdef add_use_embedded_dex(doc): 208*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 209*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 210*333d2b36SAndroid Build Coastguard Worker attr = application.getAttributeNodeNS(android_ns, 'useEmbeddedDex') 211*333d2b36SAndroid Build Coastguard Worker if attr is None: 212*333d2b36SAndroid Build Coastguard Worker attr = doc.createAttributeNS(android_ns, 'android:useEmbeddedDex') 213*333d2b36SAndroid Build Coastguard Worker attr.value = 'true' 214*333d2b36SAndroid Build Coastguard Worker application.setAttributeNode(attr) 215*333d2b36SAndroid Build Coastguard Worker elif attr.value != 'true': 216*333d2b36SAndroid Build Coastguard Worker raise RuntimeError('existing attribute mismatches the option of --use-embedded-dex') 217*333d2b36SAndroid Build Coastguard Worker 218*333d2b36SAndroid Build Coastguard Worker 219*333d2b36SAndroid Build Coastguard Workerdef add_extract_native_libs(doc, extract_native_libs): 220*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 221*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 222*333d2b36SAndroid Build Coastguard Worker value = str(extract_native_libs).lower() 223*333d2b36SAndroid Build Coastguard Worker attr = application.getAttributeNodeNS(android_ns, 'extractNativeLibs') 224*333d2b36SAndroid Build Coastguard Worker if attr is None: 225*333d2b36SAndroid Build Coastguard Worker attr = doc.createAttributeNS(android_ns, 'android:extractNativeLibs') 226*333d2b36SAndroid Build Coastguard Worker attr.value = value 227*333d2b36SAndroid Build Coastguard Worker application.setAttributeNode(attr) 228*333d2b36SAndroid Build Coastguard Worker elif attr.value != value: 229*333d2b36SAndroid Build Coastguard Worker raise RuntimeError('existing attribute extractNativeLibs="%s" conflicts with --extract-native-libs="%s"' % 230*333d2b36SAndroid Build Coastguard Worker (attr.value, value)) 231*333d2b36SAndroid Build Coastguard Worker 232*333d2b36SAndroid Build Coastguard Worker 233*333d2b36SAndroid Build Coastguard Workerdef set_has_code_to_false(doc): 234*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 235*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 236*333d2b36SAndroid Build Coastguard Worker attr = application.getAttributeNodeNS(android_ns, 'hasCode') 237*333d2b36SAndroid Build Coastguard Worker if attr is not None: 238*333d2b36SAndroid Build Coastguard Worker # Do nothing if the application already has a hasCode attribute. 239*333d2b36SAndroid Build Coastguard Worker continue 240*333d2b36SAndroid Build Coastguard Worker attr = doc.createAttributeNS(android_ns, 'android:hasCode') 241*333d2b36SAndroid Build Coastguard Worker attr.value = 'false' 242*333d2b36SAndroid Build Coastguard Worker application.setAttributeNode(attr) 243*333d2b36SAndroid Build Coastguard Worker 244*333d2b36SAndroid Build Coastguard Worker 245*333d2b36SAndroid Build Coastguard Workerdef set_test_only_flag_to_true(doc): 246*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 247*333d2b36SAndroid Build Coastguard Worker for application in get_or_create_applications(doc, manifest): 248*333d2b36SAndroid Build Coastguard Worker attr = application.getAttributeNodeNS(android_ns, 'testOnly') 249*333d2b36SAndroid Build Coastguard Worker if attr is not None: 250*333d2b36SAndroid Build Coastguard Worker # Do nothing If the application already has a testOnly attribute. 251*333d2b36SAndroid Build Coastguard Worker continue 252*333d2b36SAndroid Build Coastguard Worker attr = doc.createAttributeNS(android_ns, 'android:testOnly') 253*333d2b36SAndroid Build Coastguard Worker attr.value = 'true' 254*333d2b36SAndroid Build Coastguard Worker application.setAttributeNode(attr) 255*333d2b36SAndroid Build Coastguard Worker 256*333d2b36SAndroid Build Coastguard Worker 257*333d2b36SAndroid Build Coastguard Workerdef set_max_sdk_version(doc, max_sdk_version): 258*333d2b36SAndroid Build Coastguard Worker """Replace the maxSdkVersion attribute value for permission and 259*333d2b36SAndroid Build Coastguard Worker uses-permission tags if the value was originally set to 'current'. 260*333d2b36SAndroid Build Coastguard Worker Used for cts test cases where the maxSdkVersion should equal to 261*333d2b36SAndroid Build Coastguard Worker Build.SDK_INT. 262*333d2b36SAndroid Build Coastguard Worker 263*333d2b36SAndroid Build Coastguard Worker Args: 264*333d2b36SAndroid Build Coastguard Worker doc: The XML document. May be modified by this function. 265*333d2b36SAndroid Build Coastguard Worker max_sdk_version: The requested maxSdkVersion attribute. 266*333d2b36SAndroid Build Coastguard Worker """ 267*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 268*333d2b36SAndroid Build Coastguard Worker for tag in ['permission', 'uses-permission']: 269*333d2b36SAndroid Build Coastguard Worker children = get_children_with_tag(manifest, tag) 270*333d2b36SAndroid Build Coastguard Worker for child in children: 271*333d2b36SAndroid Build Coastguard Worker max_attr = child.getAttributeNodeNS(android_ns, 'maxSdkVersion') 272*333d2b36SAndroid Build Coastguard Worker if max_attr and max_attr.value == 'current': 273*333d2b36SAndroid Build Coastguard Worker max_attr.value = max_sdk_version 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Worker 276*333d2b36SAndroid Build Coastguard Workerdef override_placeholder_version(doc, new_version): 277*333d2b36SAndroid Build Coastguard Worker """Replace the versionCode attribute value if it\'s currently 278*333d2b36SAndroid Build Coastguard Worker set to the placeholder version of 0. 279*333d2b36SAndroid Build Coastguard Worker 280*333d2b36SAndroid Build Coastguard Worker Args: 281*333d2b36SAndroid Build Coastguard Worker doc: The XML document. May be modified by this function. 282*333d2b36SAndroid Build Coastguard Worker new_version: The new version to set if versionCode is equal to 0. 283*333d2b36SAndroid Build Coastguard Worker """ 284*333d2b36SAndroid Build Coastguard Worker manifest = parse_manifest(doc) 285*333d2b36SAndroid Build Coastguard Worker version = manifest.getAttribute("android:versionCode") 286*333d2b36SAndroid Build Coastguard Worker if version == '0': 287*333d2b36SAndroid Build Coastguard Worker manifest.setAttribute("android:versionCode", new_version) 288*333d2b36SAndroid Build Coastguard Worker 289*333d2b36SAndroid Build Coastguard Worker 290*333d2b36SAndroid Build Coastguard Workerdef main(): 291*333d2b36SAndroid Build Coastguard Worker """Program entry point.""" 292*333d2b36SAndroid Build Coastguard Worker try: 293*333d2b36SAndroid Build Coastguard Worker args = parse_args() 294*333d2b36SAndroid Build Coastguard Worker 295*333d2b36SAndroid Build Coastguard Worker doc = minidom.parse(args.input) 296*333d2b36SAndroid Build Coastguard Worker 297*333d2b36SAndroid Build Coastguard Worker ensure_manifest_android_ns(doc) 298*333d2b36SAndroid Build Coastguard Worker 299*333d2b36SAndroid Build Coastguard Worker if args.raise_min_sdk_version: 300*333d2b36SAndroid Build Coastguard Worker raise_min_sdk_version(doc, args.min_sdk_version, args.target_sdk_version, args.library) 301*333d2b36SAndroid Build Coastguard Worker 302*333d2b36SAndroid Build Coastguard Worker if args.max_sdk_version: 303*333d2b36SAndroid Build Coastguard Worker set_max_sdk_version(doc, args.max_sdk_version) 304*333d2b36SAndroid Build Coastguard Worker 305*333d2b36SAndroid Build Coastguard Worker if args.uses_libraries: 306*333d2b36SAndroid Build Coastguard Worker add_uses_libraries(doc, args.uses_libraries, True) 307*333d2b36SAndroid Build Coastguard Worker 308*333d2b36SAndroid Build Coastguard Worker if args.optional_uses_libraries: 309*333d2b36SAndroid Build Coastguard Worker add_uses_libraries(doc, args.optional_uses_libraries, False) 310*333d2b36SAndroid Build Coastguard Worker 311*333d2b36SAndroid Build Coastguard Worker if args.uses_non_sdk_api: 312*333d2b36SAndroid Build Coastguard Worker add_uses_non_sdk_api(doc) 313*333d2b36SAndroid Build Coastguard Worker 314*333d2b36SAndroid Build Coastguard Worker if args.logging_parent: 315*333d2b36SAndroid Build Coastguard Worker add_logging_parent(doc, args.logging_parent) 316*333d2b36SAndroid Build Coastguard Worker 317*333d2b36SAndroid Build Coastguard Worker if args.use_embedded_dex: 318*333d2b36SAndroid Build Coastguard Worker add_use_embedded_dex(doc) 319*333d2b36SAndroid Build Coastguard Worker 320*333d2b36SAndroid Build Coastguard Worker if args.has_no_code: 321*333d2b36SAndroid Build Coastguard Worker set_has_code_to_false(doc) 322*333d2b36SAndroid Build Coastguard Worker 323*333d2b36SAndroid Build Coastguard Worker if args.test_only: 324*333d2b36SAndroid Build Coastguard Worker set_test_only_flag_to_true(doc) 325*333d2b36SAndroid Build Coastguard Worker 326*333d2b36SAndroid Build Coastguard Worker if args.extract_native_libs is not None: 327*333d2b36SAndroid Build Coastguard Worker add_extract_native_libs(doc, args.extract_native_libs) 328*333d2b36SAndroid Build Coastguard Worker 329*333d2b36SAndroid Build Coastguard Worker if args.new_version: 330*333d2b36SAndroid Build Coastguard Worker override_placeholder_version(doc, args.new_version) 331*333d2b36SAndroid Build Coastguard Worker 332*333d2b36SAndroid Build Coastguard Worker with open(args.output, 'w') as f: 333*333d2b36SAndroid Build Coastguard Worker write_xml(f, doc) 334*333d2b36SAndroid Build Coastguard Worker 335*333d2b36SAndroid Build Coastguard Worker # pylint: disable=broad-except 336*333d2b36SAndroid Build Coastguard Worker except Exception as err: 337*333d2b36SAndroid Build Coastguard Worker print('error: ' + str(err), file=sys.stderr) 338*333d2b36SAndroid Build Coastguard Worker sys.exit(-1) 339*333d2b36SAndroid Build Coastguard Worker 340*333d2b36SAndroid Build Coastguard Worker 341*333d2b36SAndroid Build Coastguard Workerif __name__ == '__main__': 342*333d2b36SAndroid Build Coastguard Worker main() 343