Commit f3efbd5b authored by Ingemar Ådahl's avatar Ingemar Ådahl Committed by Commit Bot

Merge Android manifests when assembling apk

Merge all resource dependency manifests using the manifest merger from the
Android SDK, providing the functionality described in
https://developer.android.com/studio/build/manifest-merge.html.

Removing the nontrivial manifest guard in the android_aar_prebuilt() template
will be done in a follow-up change, as well as removing pre-merged manifest
tags, such as "com.google.android.gms.version" meta-data.

Bug: 643967
Change-Id: Ifdf9f3f76f5c80f1a2326dcd47045d032556936f
Reviewed-on: https://chromium-review.googlesource.com/558296Reviewed-by: default avatarBo Liu <boliu@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Commit-Queue: Ingemar Ådahl <ingemara@opera.com>
Cr-Commit-Position: refs/heads/master@{#485303}
parent ac8a9356
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
<service android:name="org.chromium.android_webview.test.AwEmbeddedTestServerService" <service android:name="org.chromium.android_webview.test.AwEmbeddedTestServerService"
android:exported="true" android:exported="true"
tools:ignore="ExportedService"> tools:ignore="ExportedService">
<intent-filter android:action="org.chromium.net.test.EMBEDDED_TEST_SERVER_SERVICE" /> <intent-filter>
<action android:name="org.chromium.net.test.EMBEDDED_TEST_SERVER_SERVICE" />
</intent-filter>
</service> </service>
</application> </application>
......
...@@ -49,12 +49,14 @@ if (enable_java_templates) { ...@@ -49,12 +49,14 @@ if (enable_java_templates) {
_data += "android_sdk_build_tools=" + _data += "android_sdk_build_tools=" +
rebase_path(android_sdk_build_tools, root_build_dir) + CR rebase_path(android_sdk_build_tools, root_build_dir) + CR
_data += "android_sdk_build_tools_version=$android_sdk_build_tools_version$CR" _data += "android_sdk_build_tools_version=$android_sdk_build_tools_version$CR"
_data +=
"android_sdk_tools_version_suffix=$android_sdk_tools_version_suffix$CR"
_data += _data +=
"android_sdk_root=" + rebase_path(android_sdk_root, root_build_dir) + CR "android_sdk_root=" + rebase_path(android_sdk_root, root_build_dir) + CR
_data += "android_sdk_version=$android_sdk_version$CR" _data += "android_sdk_version=$android_sdk_version$CR"
_data += "android_tool_prefix=" + _data += "android_tool_prefix=" +
rebase_path(android_tool_prefix, root_build_dir) + CR rebase_path(android_tool_prefix, root_build_dir) + CR
write_file("$root_build_dir/build_vars.txt", _data) write_file(android_build_vars, _data)
} }
# Copy to the lib.unstripped directory so that gdb can easily find it. # Copy to the lib.unstripped directory so that gdb can easily find it.
......
...@@ -364,7 +364,7 @@ class _ProjectContextGenerator(object): ...@@ -364,7 +364,7 @@ class _ProjectContextGenerator(object):
res_dirs.add( res_dirs.add(
os.path.join(self.EntryOutputDir(root_entry), _RES_SUBDIR)) os.path.join(self.EntryOutputDir(root_entry), _RES_SUBDIR))
variables['res_dirs'] = self._Relativize(root_entry, res_dirs) variables['res_dirs'] = self._Relativize(root_entry, res_dirs)
android_manifest = root_entry.Gradle().get('android_manifest') android_manifest = root_entry.DepsInfo().get('android_manifest')
if not android_manifest: if not android_manifest:
android_manifest = self._GenCustomManifest(root_entry) android_manifest = self._GenCustomManifest(root_entry)
variables['android_manifest'] = self._Relativize( variables['android_manifest'] = self._Relativize(
......
#!/usr/bin/env python
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Merges dependency Android manifests into a root manifest."""
import argparse
import contextlib
import os
import sys
import tempfile
import xml.dom.minidom as minidom
from util import build_utils
# Tools library directory - relative to Android SDK root
SDK_TOOLS_LIB_DIR = os.path.join('tools', 'lib')
MANIFEST_MERGER_MAIN_CLASS = 'com.android.manifmerger.Merger'
MANIFEST_MERGER_JARS = [
'common{suffix}.jar',
'manifest-merger{suffix}.jar',
'sdk-common{suffix}.jar',
'sdklib{suffix}.jar',
]
TOOLS_NAMESPACE_PREFIX = 'tools'
TOOLS_NAMESPACE = 'http://schemas.android.com/tools'
@contextlib.contextmanager
def _PatchedManifest(manifest_path):
"""Patches an Android manifest to always include the 'tools' namespace
declaration, as it is not propagated by the manifest merger from the SDK.
See https://issuetracker.google.com/issues/63411481
"""
doc = minidom.parse(manifest_path)
manifests = doc.getElementsByTagName('manifest')
assert len(manifests) == 1
manifest = manifests[0]
manifest.setAttribute('xmlns:%s' % TOOLS_NAMESPACE_PREFIX, TOOLS_NAMESPACE)
tmp_prefix = os.path.basename(manifest_path)
with tempfile.NamedTemporaryFile(prefix=tmp_prefix) as patched_manifest:
doc.writexml(patched_manifest)
patched_manifest.flush()
yield patched_manifest.name
def _BuildManifestMergerClasspath(build_vars):
return ':'.join([
os.path.join(
build_vars['android_sdk_root'],
SDK_TOOLS_LIB_DIR,
jar.format(suffix=build_vars['android_sdk_tools_version_suffix']))
for jar in MANIFEST_MERGER_JARS
])
def main(argv):
argv = build_utils.ExpandFileArgs(argv)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--build-vars',
help='Path to GN build vars file',
required=True)
parser.add_argument('--root-manifest',
help='Root manifest which to merge into',
required=True)
parser.add_argument('--output', help='Output manifest path', required=True)
parser.add_argument('--extras',
help='GN list of additional manifest to merge')
args = parser.parse_args(argv)
cmd = [
'java',
'-cp',
_BuildManifestMergerClasspath(build_utils.ReadBuildVars(args.build_vars)),
MANIFEST_MERGER_MAIN_CLASS,
'--out', args.output,
]
extras = build_utils.ParseGnList(args.extras)
if extras:
cmd += ['--libs', ':'.join(extras)]
with _PatchedManifest(args.root_manifest) as root_manifest:
cmd += ['--main', root_manifest]
build_utils.CheckOutput(cmd,
# https://issuetracker.google.com/issues/63514300: The merger doesn't set
# a nonzero exit code for failures.
fail_func=lambda returncode, stderr: returncode != 0 or
build_utils.IsTimeStale(args.output, [root_manifest] + extras))
if __name__ == '__main__':
main(sys.argv[1:])
...@@ -21,6 +21,7 @@ import zipfile ...@@ -21,6 +21,7 @@ import zipfile
import md5_check # pylint: disable=relative-import import md5_check # pylint: disable=relative-import
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
from pylib import constants
from pylib.constants import host_paths from pylib.constants import host_paths
sys.path.append(os.path.join(os.path.dirname(__file__), sys.path.append(os.path.join(os.path.dirname(__file__),
...@@ -81,6 +82,14 @@ def FindInDirectories(directories, filename_filter): ...@@ -81,6 +82,14 @@ def FindInDirectories(directories, filename_filter):
return all_files return all_files
def ReadBuildVars(build_vars_path=None):
if not build_vars_path:
build_vars_path = os.path.join(constants.GetOutDirectory(),
"build_vars.txt")
with open(build_vars_path) as f:
return dict(l.rstrip().split('=', 1) for l in f)
def ParseGnList(gn_string): def ParseGnList(gn_string):
"""Converts a command-line parameter into a list. """Converts a command-line parameter into a list.
......
...@@ -410,7 +410,8 @@ def main(argv): ...@@ -410,7 +410,8 @@ def main(argv):
deps_info['gradle_treat_as_prebuilt'] = options.gradle_treat_as_prebuilt deps_info['gradle_treat_as_prebuilt'] = options.gradle_treat_as_prebuilt
if options.android_manifest: if options.android_manifest:
gradle['android_manifest'] = options.android_manifest deps_info['android_manifest'] = options.android_manifest
if options.type in ('java_binary', 'java_library', 'android_apk'): if options.type in ('java_binary', 'java_library', 'android_apk'):
if options.java_sources_file: if options.java_sources_file:
deps_info['java_sources_file'] = options.java_sources_file deps_info['java_sources_file'] = options.java_sources_file
...@@ -706,6 +707,9 @@ def main(argv): ...@@ -706,6 +707,9 @@ def main(argv):
config['uncompressed_locales_java_list'] = ( config['uncompressed_locales_java_list'] = (
_CreateLocalePaksAssetJavaList(config['uncompressed_assets'])) _CreateLocalePaksAssetJavaList(config['uncompressed_assets']))
config['extra_android_manifests'] = filter(None, (
d.get('android_manifest') for d in all_resources_deps))
# Collect java resources # Collect java resources
java_resources_jars = [d['java_resources_jar'] for d in all_library_deps java_resources_jars = [d['java_resources_jar'] for d in all_library_deps
if 'java_resources_jar' in d] if 'java_resources_jar' in d]
......
...@@ -771,11 +771,6 @@ def _VerifyLibBuildIdsMatch(tools_prefix, *so_files): ...@@ -771,11 +771,6 @@ def _VerifyLibBuildIdsMatch(tools_prefix, *so_files):
'Your output directory is likely stale.') 'Your output directory is likely stale.')
def _ReadBuildVars(output_dir):
with open(os.path.join(output_dir, 'build_vars.txt')) as f:
return dict(l.replace('//', '').rstrip().split('=', 1) for l in f)
def main(): def main():
argparser = argparse.ArgumentParser(description='Print APK size metrics.') argparser = argparse.ArgumentParser(description='Print APK size metrics.')
argparser.add_argument('--min-pak-resource-size', type=int, default=20*1024, argparser.add_argument('--min-pak-resource-size', type=int, default=20*1024,
...@@ -814,7 +809,7 @@ def main(): ...@@ -814,7 +809,7 @@ def main():
if not args.no_output_dir: if not args.no_output_dir:
constants.CheckOutputDirectory() constants.CheckOutputDirectory()
devil_chromium.Initialize() devil_chromium.Initialize()
build_vars = _ReadBuildVars(constants.GetOutDirectory()) build_vars = build_utils.ReadBuildVars()
tools_prefix = os.path.join(constants.GetOutDirectory(), tools_prefix = os.path.join(constants.GetOutDirectory(),
build_vars['android_tool_prefix']) build_vars['android_tool_prefix'])
else: else:
......
...@@ -45,6 +45,7 @@ if (is_android) { ...@@ -45,6 +45,7 @@ if (is_android) {
default_android_sdk_root = "//third_party/android_tools/sdk" default_android_sdk_root = "//third_party/android_tools/sdk"
default_android_sdk_version = "26" default_android_sdk_version = "26"
default_android_sdk_build_tools_version = "26.0.0" default_android_sdk_build_tools_version = "26.0.0"
default_android_sdk_tools_version_suffix = "-25.3.2"
} }
if (!defined(default_lint_android_sdk_root)) { if (!defined(default_lint_android_sdk_root)) {
...@@ -104,6 +105,7 @@ if (is_android) { ...@@ -104,6 +105,7 @@ if (is_android) {
android_sdk_root = default_android_sdk_root android_sdk_root = default_android_sdk_root
android_sdk_version = default_android_sdk_version android_sdk_version = default_android_sdk_version
android_sdk_build_tools_version = default_android_sdk_build_tools_version android_sdk_build_tools_version = default_android_sdk_build_tools_version
android_sdk_tools_version_suffix = default_android_sdk_tools_version_suffix
lint_android_sdk_root = default_lint_android_sdk_root lint_android_sdk_root = default_lint_android_sdk_root
lint_android_sdk_version = default_lint_android_sdk_version lint_android_sdk_version = default_lint_android_sdk_version
...@@ -194,6 +196,9 @@ if (is_android) { ...@@ -194,6 +196,9 @@ if (is_android) {
assert(!(enable_incremental_dx && !is_java_debug)) assert(!(enable_incremental_dx && !is_java_debug))
assert(!(enable_incremental_javac && !is_java_debug)) assert(!(enable_incremental_javac && !is_java_debug))
# Path to where selected build variables are written to.
android_build_vars = "$root_build_dir/build_vars.txt"
# Host stuff ----------------------------------------------------------------- # Host stuff -----------------------------------------------------------------
# Defines the name the Android build gives to the current host CPU # Defines the name the Android build gives to the current host CPU
......
...@@ -1777,11 +1777,11 @@ if (enable_java_templates) { ...@@ -1777,11 +1777,11 @@ if (enable_java_templates) {
} }
sources = [] sources = []
} }
_android_manifest_deps = [] _android_root_manifest_deps = []
if (defined(invoker.android_manifest_dep)) { if (defined(invoker.android_manifest_dep)) {
_android_manifest_deps = [ invoker.android_manifest_dep ] _android_root_manifest_deps = [ invoker.android_manifest_dep ]
} }
_android_manifest = invoker.android_manifest _android_root_manifest = invoker.android_manifest
_rebased_build_config = rebase_path(_build_config, root_build_dir) _rebased_build_config = rebase_path(_build_config, root_build_dir)
_create_abi_split = _create_abi_split =
...@@ -1820,13 +1820,13 @@ if (enable_java_templates) { ...@@ -1820,13 +1820,13 @@ if (enable_java_templates) {
incremental_install_script_path = _incremental_install_script_path incremental_install_script_path = _incremental_install_script_path
resources_zip = resources_zip_path resources_zip = resources_zip_path
build_config = _build_config build_config = _build_config
android_manifest = _android_manifest android_manifest = _android_root_manifest
if (defined(_java_sources_file)) { if (defined(_java_sources_file)) {
java_sources_file = _java_sources_file java_sources_file = _java_sources_file
} }
deps = _android_manifest_deps deps = _android_root_manifest_deps
if (defined(invoker.deps)) { if (defined(invoker.deps)) {
possible_config_deps = invoker.deps possible_config_deps = invoker.deps
...@@ -1856,6 +1856,34 @@ if (enable_java_templates) { ...@@ -1856,6 +1856,34 @@ if (enable_java_templates) {
} }
} }
_android_manifest =
"$target_gen_dir/${_template_name}_manifest/AndroidManifest.xml"
android_manifest_target = "${_template_name}__merge_manifests"
action(android_manifest_target) {
script = "//build/android/gyp/merge_manifest.py"
sources = [
_android_root_manifest,
]
outputs = [
_android_manifest,
]
args = [
"--build-vars",
rebase_path(android_build_vars, root_build_dir),
"--root-manifest",
rebase_path(_android_root_manifest, root_build_dir),
"--output",
rebase_path(_android_manifest, root_build_dir),
"--extras",
"@FileArg($_rebased_build_config:extra_android_manifests)",
]
deps = _android_root_manifest_deps + [ ":$build_config_target" ]
}
_final_deps = [] _final_deps = []
if (enable_multidex) { if (enable_multidex) {
...@@ -1886,7 +1914,10 @@ if (enable_java_templates) { ...@@ -1886,7 +1914,10 @@ if (enable_java_templates) {
} }
build_config = _build_config build_config = _build_config
deps = _android_manifest_deps + [ ":$build_config_target" ] deps = [
":$android_manifest_target",
":$build_config_target",
]
if (defined(invoker.deps)) { if (defined(invoker.deps)) {
deps += invoker.deps deps += invoker.deps
} }
...@@ -1992,7 +2023,10 @@ if (enable_java_templates) { ...@@ -1992,7 +2023,10 @@ if (enable_java_templates) {
supports_android = true supports_android = true
requires_android = true requires_android = true
override_build_config = _build_config override_build_config = _build_config
deps = _android_manifest_deps + [ ":$build_config_target" ] deps = [
":$android_manifest_target",
":$build_config_target",
]
android_manifest = _android_manifest android_manifest = _android_manifest
srcjar_deps = _srcjar_deps srcjar_deps = _srcjar_deps
...@@ -2268,16 +2302,18 @@ if (enable_java_templates) { ...@@ -2268,16 +2302,18 @@ if (enable_java_templates) {
keystore_password = _keystore_password keystore_password = _keystore_password
# Incremental apk does not use native libs nor final dex. # Incremental apk does not use native libs nor final dex.
incremental_deps = deps + _android_manifest_deps + [ incremental_deps = deps + [
":$android_manifest_target",
":$build_config_target", ":$build_config_target",
":$process_resources_target", ":$process_resources_target",
] ]
# This target generates the input file _all_resources_zip_path. # This target generates the input file _all_resources_zip_path.
deps += _android_manifest_deps + [ deps += [
":$android_manifest_target",
":$build_config_target", ":$build_config_target",
":$process_resources_target",
":$final_dex_target_name", ":$final_dex_target_name",
":$process_resources_target",
] ]
if ((_native_libs_deps != [] || if ((_native_libs_deps != [] ||
...@@ -2311,7 +2347,9 @@ if (enable_java_templates) { ...@@ -2311,7 +2347,9 @@ if (enable_java_templates) {
out_manifest = out_manifest =
"$gen_dir/split-manifests/${android_app_abi}/AndroidManifest.xml" "$gen_dir/split-manifests/${android_app_abi}/AndroidManifest.xml"
split_name = "abi_${android_app_abi}" split_name = "abi_${android_app_abi}"
deps = _android_manifest_deps deps = [
":$android_manifest_target",
]
} }
_apk_rule = "${_template_name}__split_apk_abi_${android_app_abi}" _apk_rule = "${_template_name}__split_apk_abi_${android_app_abi}"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment