OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 """Creates an AndroidManifest.xml for an incremental APK. | 6 """Creates an AndroidManifest.xml for an incremental APK. |
7 | 7 |
8 Given the manifest file for the real APK, generates an AndroidManifest.xml with | 8 Given the manifest file for the real APK, generates an AndroidManifest.xml with |
9 the application class changed to IncrementalApplication. | 9 the application class changed to IncrementalApplication. |
10 """ | 10 """ |
11 | 11 |
12 import argparse | 12 import argparse |
13 import os | 13 import os |
14 import sys | 14 import sys |
15 from xml.etree import ElementTree | 15 from xml.etree import ElementTree |
16 | 16 |
17 sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir, 'gyp')) | 17 sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir, 'gyp')) |
18 from util import build_utils | 18 from util import build_utils |
19 | 19 |
20 _ANDROID_NAMESPACE = 'http://schemas.android.com/apk/res/android' | 20 _ANDROID_NAMESPACE = 'http://schemas.android.com/apk/res/android' |
21 ElementTree.register_namespace('android', _ANDROID_NAMESPACE) | 21 ElementTree.register_namespace('android', _ANDROID_NAMESPACE) |
22 | 22 |
23 _INCREMENTAL_APP_NAME = 'org.chromium.incrementalinstall.BootstrapApplication' | 23 _INCREMENTAL_APP_NAME = 'org.chromium.incrementalinstall.BootstrapApplication' |
24 _META_DATA_NAME = 'incremental-install-real-app' | 24 _META_DATA_NAME = 'incremental-install-real-app' |
| 25 _DEFAULT_APPLICATION_CLASS = 'android.app.Application' |
25 | 26 |
26 | 27 |
27 def _AddNamespace(name): | 28 def _AddNamespace(name): |
28 """Adds the android namespace prefix to the given identifier.""" | 29 """Adds the android namespace prefix to the given identifier.""" |
29 return '{%s}%s' % (_ANDROID_NAMESPACE, name) | 30 return '{%s}%s' % (_ANDROID_NAMESPACE, name) |
30 | 31 |
31 def _ParseArgs(): | 32 def _ParseArgs(): |
32 parser = argparse.ArgumentParser() | 33 parser = argparse.ArgumentParser() |
33 build_utils.AddDepfileOption(parser) | 34 build_utils.AddDepfileOption(parser) |
34 parser.add_argument('--src-manifest', | 35 parser.add_argument('--src-manifest', |
35 help='The main manifest of the app', | 36 help='The main manifest of the app', |
36 required=True) | 37 required=True) |
37 parser.add_argument('--out-manifest', | 38 parser.add_argument('--out-manifest', |
38 help='The output manifest', | 39 help='The output manifest', |
39 required=True) | 40 required=True) |
40 parser.add_argument('--disable-isolated-processes', | 41 parser.add_argument('--disable-isolated-processes', |
41 help='Changes all android:isolatedProcess to false. ' | 42 help='Changes all android:isolatedProcess to false. ' |
42 'This is required on Android M+', | 43 'This is required on Android M+', |
43 action='store_true') | 44 action='store_true') |
44 return parser.parse_args() | 45 return parser.parse_args() |
45 | 46 |
46 | 47 |
47 def _ProcessManifest(main_manifest, main_manifest_path, | 48 def _ProcessManifest(main_manifest, disable_isolated_processes): |
48 disable_isolated_processes): | |
49 """Returns a transformed AndroidManifest.xml for use with _incremental apks. | 49 """Returns a transformed AndroidManifest.xml for use with _incremental apks. |
50 | 50 |
51 Args: | 51 Args: |
52 main_manifest: Manifest contents to transform. | 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 | 53 disable_isolated_processes: Whether to set all isolatedProcess attributes to |
55 false | 54 false |
56 | 55 |
57 Returns: | 56 Returns: |
58 The transformed AndroidManifest.xml. | 57 The transformed AndroidManifest.xml. |
59 """ | 58 """ |
60 if disable_isolated_processes: | 59 if disable_isolated_processes: |
61 main_manifest = main_manifest.replace('isolatedProcess="true"', | 60 main_manifest = main_manifest.replace('isolatedProcess="true"', |
62 'isolatedProcess="false"') | 61 'isolatedProcess="false"') |
63 | 62 |
64 doc = ElementTree.fromstring(main_manifest) | 63 doc = ElementTree.fromstring(main_manifest) |
65 app_node = doc.find('application') | 64 app_node = doc.find('application') |
66 if app_node is None: | 65 if app_node is None: |
67 raise Exception('Could not find <application> in %s' % main_manifest_path) | 66 app_node = ElementTree.SubElement(doc, 'application') |
68 real_app_class = app_node.get(_AddNamespace('name')) | 67 |
69 if real_app_class is None: | 68 real_app_class = app_node.get(_AddNamespace('name'), |
70 raise Exception('Could not find android:name in <application> in %s' % | 69 _DEFAULT_APPLICATION_CLASS) |
71 main_manifest_path) | |
72 app_node.set(_AddNamespace('name'), _INCREMENTAL_APP_NAME) | 70 app_node.set(_AddNamespace('name'), _INCREMENTAL_APP_NAME) |
73 | 71 |
74 meta_data_node = ElementTree.SubElement(app_node, 'meta-data') | 72 meta_data_node = ElementTree.SubElement(app_node, 'meta-data') |
75 meta_data_node.set(_AddNamespace('name'), _META_DATA_NAME) | 73 meta_data_node.set(_AddNamespace('name'), _META_DATA_NAME) |
76 meta_data_node.set(_AddNamespace('value'), real_app_class) | 74 meta_data_node.set(_AddNamespace('value'), real_app_class) |
77 return ElementTree.tostring(doc, encoding='UTF-8') | 75 return ElementTree.tostring(doc, encoding='UTF-8') |
78 | 76 |
79 | 77 |
80 def main(): | 78 def main(): |
81 options = _ParseArgs() | 79 options = _ParseArgs() |
82 with open(options.src_manifest) as f: | 80 with open(options.src_manifest) as f: |
83 main_manifest_data = f.read() | 81 main_manifest_data = f.read() |
84 new_manifest_data = _ProcessManifest(main_manifest_data, options.src_manifest, | 82 new_manifest_data = _ProcessManifest(main_manifest_data, |
85 options.disable_isolated_processes) | 83 options.disable_isolated_processes) |
86 with open(options.out_manifest, 'w') as f: | 84 with open(options.out_manifest, 'w') as f: |
87 f.write(new_manifest_data) | 85 f.write(new_manifest_data) |
88 | 86 |
89 if options.depfile: | 87 if options.depfile: |
90 build_utils.WriteDepfile( | 88 build_utils.WriteDepfile( |
91 options.depfile, | 89 options.depfile, |
92 [options.src_manifest] + build_utils.GetPythonDependencies()) | 90 [options.src_manifest] + build_utils.GetPythonDependencies()) |
93 | 91 |
94 | 92 |
95 if __name__ == '__main__': | 93 if __name__ == '__main__': |
96 main() | 94 main() |
OLD | NEW |