3 # Copyright 2015 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6 """Creates an AndroidManifest.xml for an incremental APK.
8 Given the manifest file for the real APK, generates an AndroidManifest.xml with
9 the application class changed to IncrementalApplication.
15 from xml
.etree
import ElementTree
17 sys
.path
.append(os
.path
.join(os
.path
.dirname(__file__
), os
.path
.pardir
, 'gyp'))
18 from util
import build_utils
20 _ANDROID_NAMESPACE
= 'http://schemas.android.com/apk/res/android'
21 ElementTree
.register_namespace('android', _ANDROID_NAMESPACE
)
23 _INCREMENTAL_APP_NAME
= 'org.chromium.incrementalinstall.BootstrapApplication'
24 _META_DATA_NAME
= 'incremental-install-real-app'
27 def _AddNamespace(name
):
28 """Adds the android namespace prefix to the given identifier."""
29 return '{%s}%s' % (_ANDROID_NAMESPACE
, name
)
32 parser
= argparse
.ArgumentParser()
33 build_utils
.AddDepfileOption(parser
)
34 parser
.add_argument('--src-manifest',
35 help='The main manifest of the app',
37 parser
.add_argument('--out-manifest',
38 help='The output manifest',
40 parser
.add_argument('--disable-isolated-processes',
41 help='Changes all android:isolatedProcess to false. '
42 'This is required on Android M+',
44 return parser
.parse_args()
47 def _ProcessManifest(main_manifest
, main_manifest_path
,
48 disable_isolated_processes
):
49 """Returns a transformed AndroidManifest.xml for use with _incremental apks.
52 main_manifest: Manifest contents to transform.
53 main_manifest_path: Path to main_manifest (used for error messages).
54 disable_isolated_processes: Whether to set all isolatedProcess attributes to
58 The transformed AndroidManifest.xml.
60 if disable_isolated_processes
:
61 main_manifest
= main_manifest
.replace('isolatedProcess="true"',
62 'isolatedProcess="false"')
64 doc
= ElementTree
.fromstring(main_manifest
)
65 app_node
= doc
.find('application')
67 raise Exception('Could not find <application> in %s' % main_manifest_path
)
68 real_app_class
= app_node
.get(_AddNamespace('name'))
69 if real_app_class
is None:
70 raise Exception('Could not find android:name in <application> in %s' %
72 app_node
.set(_AddNamespace('name'), _INCREMENTAL_APP_NAME
)
74 meta_data_node
= ElementTree
.SubElement(app_node
, 'meta-data')
75 meta_data_node
.set(_AddNamespace('name'), _META_DATA_NAME
)
76 meta_data_node
.set(_AddNamespace('value'), real_app_class
)
77 return ElementTree
.tostring(doc
, encoding
='UTF-8')
81 options
= _ParseArgs()
82 with
open(options
.src_manifest
) as f
:
83 main_manifest_data
= f
.read()
84 new_manifest_data
= _ProcessManifest(main_manifest_data
, options
.src_manifest
,
85 options
.disable_isolated_processes
)
86 with
open(options
.out_manifest
, 'w') as f
:
87 f
.write(new_manifest_data
)
90 build_utils
.WriteDepfile(
92 [options
.src_manifest
] + build_utils
.GetPythonDependencies())
95 if __name__
== '__main__':