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,9 +19,11 @@
<service android:name="org.chromium.android_webview.test.AwEmbeddedTestServerService"
android:exported="true"
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>
</application>
</manifest>
\ No newline at end of file
</manifest>
......@@ -49,12 +49,14 @@ if (enable_java_templates) {
_data += "android_sdk_build_tools=" +
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_tools_version_suffix=$android_sdk_tools_version_suffix$CR"
_data +=
"android_sdk_root=" + rebase_path(android_sdk_root, root_build_dir) + CR
_data += "android_sdk_version=$android_sdk_version$CR"
_data += "android_tool_prefix=" +
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.
......
......@@ -364,7 +364,7 @@ class _ProjectContextGenerator(object):
res_dirs.add(
os.path.join(self.EntryOutputDir(root_entry), _RES_SUBDIR))
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:
android_manifest = self._GenCustomManifest(root_entry)
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
import md5_check # pylint: disable=relative-import
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
from pylib import constants
from pylib.constants import host_paths
sys.path.append(os.path.join(os.path.dirname(__file__),
......@@ -81,6 +82,14 @@ def FindInDirectories(directories, filename_filter):
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):
"""Converts a command-line parameter into a list.
......
......@@ -410,7 +410,8 @@ def main(argv):
deps_info['gradle_treat_as_prebuilt'] = options.gradle_treat_as_prebuilt
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.java_sources_file:
deps_info['java_sources_file'] = options.java_sources_file
......@@ -706,6 +707,9 @@ def main(argv):
config['uncompressed_locales_java_list'] = (
_CreateLocalePaksAssetJavaList(config['uncompressed_assets']))
config['extra_android_manifests'] = filter(None, (
d.get('android_manifest') for d in all_resources_deps))
# Collect java resources
java_resources_jars = [d['java_resources_jar'] for d in all_library_deps
if 'java_resources_jar' in d]
......
......@@ -771,11 +771,6 @@ def _VerifyLibBuildIdsMatch(tools_prefix, *so_files):
'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():
argparser = argparse.ArgumentParser(description='Print APK size metrics.')
argparser.add_argument('--min-pak-resource-size', type=int, default=20*1024,
......@@ -814,7 +809,7 @@ def main():
if not args.no_output_dir:
constants.CheckOutputDirectory()
devil_chromium.Initialize()
build_vars = _ReadBuildVars(constants.GetOutDirectory())
build_vars = build_utils.ReadBuildVars()
tools_prefix = os.path.join(constants.GetOutDirectory(),
build_vars['android_tool_prefix'])
else:
......
......@@ -45,6 +45,7 @@ if (is_android) {
default_android_sdk_root = "//third_party/android_tools/sdk"
default_android_sdk_version = "26"
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)) {
......@@ -104,6 +105,7 @@ if (is_android) {
android_sdk_root = default_android_sdk_root
android_sdk_version = default_android_sdk_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_version = default_lint_android_sdk_version
......@@ -194,6 +196,9 @@ if (is_android) {
assert(!(enable_incremental_dx && !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 -----------------------------------------------------------------
# Defines the name the Android build gives to the current host CPU
......
......@@ -1777,11 +1777,11 @@ if (enable_java_templates) {
}
sources = []
}
_android_manifest_deps = []
_android_root_manifest_deps = []
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)
_create_abi_split =
......@@ -1820,13 +1820,13 @@ if (enable_java_templates) {
incremental_install_script_path = _incremental_install_script_path
resources_zip = resources_zip_path
build_config = _build_config
android_manifest = _android_manifest
android_manifest = _android_root_manifest
if (defined(_java_sources_file)) {
java_sources_file = _java_sources_file
}
deps = _android_manifest_deps
deps = _android_root_manifest_deps
if (defined(invoker.deps)) {
possible_config_deps = invoker.deps
......@@ -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 = []
if (enable_multidex) {
......@@ -1886,7 +1914,10 @@ if (enable_java_templates) {
}
build_config = _build_config
deps = _android_manifest_deps + [ ":$build_config_target" ]
deps = [
":$android_manifest_target",
":$build_config_target",
]
if (defined(invoker.deps)) {
deps += invoker.deps
}
......@@ -1992,7 +2023,10 @@ if (enable_java_templates) {
supports_android = true
requires_android = true
override_build_config = _build_config
deps = _android_manifest_deps + [ ":$build_config_target" ]
deps = [
":$android_manifest_target",
":$build_config_target",
]
android_manifest = _android_manifest
srcjar_deps = _srcjar_deps
......@@ -2268,17 +2302,19 @@ if (enable_java_templates) {
keystore_password = _keystore_password
# 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",
":$process_resources_target",
]
# This target generates the input file _all_resources_zip_path.
deps += _android_manifest_deps + [
":$build_config_target",
":$process_resources_target",
":$final_dex_target_name",
]
deps += [
":$android_manifest_target",
":$build_config_target",
":$final_dex_target_name",
":$process_resources_target",
]
if ((_native_libs_deps != [] ||
_extra_native_libs_even_when_incremental != []) &&
......@@ -2311,7 +2347,9 @@ if (enable_java_templates) {
out_manifest =
"$gen_dir/split-manifests/${android_app_abi}/AndroidManifest.xml"
split_name = "abi_${android_app_abi}"
deps = _android_manifest_deps
deps = [
":$android_manifest_target",
]
}
_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