diff options
author | agrieve <agrieve@chromium.org> | 2015-05-22 14:32:09 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-22 21:32:41 +0000 |
commit | ac94e41f40bfc5252dc23dd72549d985ca221168 (patch) | |
tree | 534d46c9b2f6558e0cd85e749dcc25bc752beaaf /build/android | |
parent | e62fd3d1df77c792693f065c99bc2fb67a42e7bd (diff) | |
download | chromium_src-ac94e41f40bfc5252dc23dd72549d985ca221168.zip chromium_src-ac94e41f40bfc5252dc23dd72549d985ca221168.tar.gz chromium_src-ac94e41f40bfc5252dc23dd72549d985ca221168.tar.bz2 |
Add create_density_splits option to java_apk.gypi / android_apk (gn)
BUG=488324
Review URL: https://codereview.chromium.org/1133603004
Cr-Commit-Position: refs/heads/master@{#331177}
Diffstat (limited to 'build/android')
-rw-r--r-- | build/android/finalize_splits_action.gypi | 70 | ||||
-rwxr-xr-x | build/android/gyp/finalize_apk.py | 18 | ||||
-rwxr-xr-x | build/android/gyp/finalize_splits.py | 44 | ||||
-rwxr-xr-x | build/android/gyp/package_resources.py | 79 | ||||
-rw-r--r-- | build/android/package_resources_action.gypi | 14 |
5 files changed, 217 insertions, 8 deletions
diff --git a/build/android/finalize_splits_action.gypi b/build/android/finalize_splits_action.gypi new file mode 100644 index 0000000..0d0fe88 --- /dev/null +++ b/build/android/finalize_splits_action.gypi @@ -0,0 +1,70 @@ +# Copyright 2015 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. + +# This file is meant to be included into an action to provide an action that +# signs and zipaligns split APKs. +# +# Required variables: +# apk_name - Base name of the apk. +# Optional variables: +# density_splits - Whether to process density splits +# language_splits - Whether to language splits + +{ + 'variables': { + 'keystore_path%': '<(DEPTH)/build/android/ant/chromium-debug.keystore', + 'keystore_name%': 'chromiumdebugkey', + 'keystore_password%': 'chromium', + 'zipalign_path%': '<(android_sdk_tools)/zipalign', + 'density_splits%': 0, + 'language_splits%': 0, + 'resource_packaged_apk_name': '<(apk_name)-resources.ap_', + 'resource_packaged_apk_path': '<(intermediate_dir)/<(resource_packaged_apk_name)', + 'base_output_path': '<(PRODUCT_DIR)/apks/<(apk_name)', + }, + 'inputs': [ + '<(DEPTH)/build/android/gyp/finalize_splits.py', + '<(DEPTH)/build/android/gyp/finalize_apk.py', + '<(DEPTH)/build/android/gyp/util/build_utils.py', + '<(keystore_path)', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/finalize_splits.py', + '--resource-packaged-apk-path=<(resource_packaged_apk_path)', + '--base-output-path=<(base_output_path)', + '--zipalign-path=<(zipalign_path)', + '--key-path=<(keystore_path)', + '--key-name=<(keystore_name)', + '--key-passwd=<(keystore_password)', + ], + 'conditions': [ + ['density_splits == 1', { + 'message': 'Signing/aligning <(_target_name) density splits', + 'inputs': [ + '<(resource_packaged_apk_path)-hdpi', + '<(resource_packaged_apk_path)-xhdpi', + '<(resource_packaged_apk_path)-xxhdpi', + '<(resource_packaged_apk_path)-tvdpi', + ], + 'outputs': [ + '<(base_output_path)-density-hdpi.apk', + '<(base_output_path)-density-xhdpi.apk', + '<(base_output_path)-density-xxhdpi.apk', + '<(base_output_path)-density-tvdpi.apk', + ], + 'action': [ + '--densities=hdpi,xhdpi,xxhdpi,tvdpi', + ], + }], + # TODO(agrieve): Implement language splits + ['language_splits == 1', { + 'message': 'Signing/aligning <(_target_name) language splits', + 'inputs': [ + ], + 'outputs': [ + ], + }], + ], +} + diff --git a/build/android/gyp/finalize_apk.py b/build/android/gyp/finalize_apk.py index 0a096d3..0a80035 100755 --- a/build/android/gyp/finalize_apk.py +++ b/build/android/gyp/finalize_apk.py @@ -86,6 +86,17 @@ def main(): options, _ = parser.parse_args() + FinalizeApk(options) + + if options.depfile: + build_utils.WriteDepfile( + options.depfile, build_utils.GetPythonDependencies()) + + if options.stamp: + build_utils.Touch(options.stamp) + + +def FinalizeApk(options): with tempfile.NamedTemporaryFile() as signed_apk_path_tmp, \ tempfile.NamedTemporaryFile() as apk_to_sign_tmp: @@ -116,13 +127,6 @@ def main(): # Align uncompressed items to 4 bytes AlignApk(options.zipalign_path, signed_apk_path, options.final_apk_path) - if options.depfile: - build_utils.WriteDepfile( - options.depfile, build_utils.GetPythonDependencies()) - - if options.stamp: - build_utils.Touch(options.stamp) - if __name__ == '__main__': sys.exit(main()) diff --git a/build/android/gyp/finalize_splits.py b/build/android/gyp/finalize_splits.py new file mode 100755 index 0000000..97a65fa --- /dev/null +++ b/build/android/gyp/finalize_splits.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Copyright 2015 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. +"""Signs and zipaligns split APKs. + +This script is require only by GYP (not GN). +""" + +import optparse +import sys + +import finalize_apk + +def main(): + parser = optparse.OptionParser() + parser.add_option('--zipalign-path', help='Path to the zipalign tool.') + parser.add_option('--resource-packaged-apk-path', + help='Base path to input .ap_s.') + parser.add_option('--base-output-path', + help='Path to output .apk, minus extension.') + parser.add_option('--key-path', help='Path to keystore for signing.') + parser.add_option('--key-passwd', help='Keystore password') + parser.add_option('--key-name', help='Keystore name') + parser.add_option('--densities', + help='Comma separated list of densities finalize.') + + options, _ = parser.parse_args() + options.load_library_from_zip = 0 + + if options.densities: + for density in options.densities.split(','): + options.unsigned_apk_path = ("%s-%s" % + (options.resource_packaged_apk_path, density)) + options.final_apk_path = ("%s-density-%s.apk" % + (options.base_output_path, density)) + finalize_apk.FinalizeApk(options) + else: + raise Exception('Language splits not yet implemented') + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/build/android/gyp/package_resources.py b/build/android/gyp/package_resources.py index 5393766..a73d9d5 100755 --- a/build/android/gyp/package_resources.py +++ b/build/android/gyp/package_resources.py @@ -16,9 +16,52 @@ https://android.googlesource.com/platform/sdk/+/master/files/ant/build.xml import optparse import os import shutil +import zipfile from util import build_utils + +# List is generated from the chrome_apk.apk_intermediates.ap_ via: +# unzip -l $FILE_AP_ | cut -c31- | grep res/draw | cut -d'/' -f 2 | sort \ +# | uniq | grep -- -tvdpi- | cut -c10- +# and then manually sorted. +# Note that we can't just do a cross-product of dimentions because the filenames +# become too big and aapt fails to create the files. +# This leaves all default drawables (mdpi) in the main apk. Android gets upset +# though if any drawables are missing from the default drawables/ directory. +DENSITY_SPLITS = { + 'hdpi': ( + 'hdpi-v4', # Order matters for output file names. + 'ldrtl-hdpi-v4', + 'sw600dp-hdpi-v13', + 'ldrtl-hdpi-v17', + 'ldrtl-sw600dp-hdpi-v17', + 'hdpi-v21', + ), + 'xhdpi': ( + 'xhdpi-v4', + 'ldrtl-xhdpi-v4', + 'sw600dp-xhdpi-v13', + 'ldrtl-xhdpi-v17', + 'ldrtl-sw600dp-xhdpi-v17', + 'xhdpi-v21', + ), + 'xxhdpi': ( + 'xxhdpi-v4', + 'ldrtl-xxhdpi-v4', + 'sw600dp-xxhdpi-v13', + 'ldrtl-xxhdpi-v17', + 'ldrtl-sw600dp-xxhdpi-v17', + 'xxhdpi-v21', + ), + 'tvdpi': ( + 'tvdpi-v4', + 'sw600dp-tvdpi-v13', + 'ldrtl-sw600dp-tvdpi-v17', + ), +} + + def ParseArgs(): """Parses command line options. @@ -48,6 +91,10 @@ def ParseArgs(): help='directories containing assets to be packaged') parser.add_option('--no-compress', help='disables compression for the ' 'given comma separated list of extensions') + parser.add_option( + '--create-density-splits', + action='store_true', + help='Enables density splits') parser.add_option('--apk-path', help='Path to output (partial) apk.') @@ -114,6 +161,29 @@ def PackageArgsForExtractedZip(d): return package_command +def RenameDensitySplits(apk_path): + """Renames all density splits to have shorter / predictable names.""" + for density, config in DENSITY_SPLITS.iteritems(): + src_path = '%s_%s' % (apk_path, '_'.join(config)) + dst_path = '%s-%s' % (apk_path, density) + if os.path.exists(dst_path): + os.unlink(dst_path) + os.rename(src_path, dst_path) + + +def CheckDensityMissedConfigs(apk_path): + """Raises an exception if apk_path contains any density-specifc files.""" + triggers = ['-%s' % density for density in DENSITY_SPLITS] + with zipfile.ZipFile(apk_path) as main_apk_zip: + for name in main_apk_zip.namelist(): + for trigger in triggers: + if trigger in name and not 'mipmap-' in name: + raise Exception(('Found density in main apk that should have been ' + + 'put into a split: %s\nYou need to update ' + + 'package_resources.py to include this new ' + + 'config.') % name) + + def main(): options = ParseArgs() android_jar = os.path.join(options.android_sdk, 'android.jar') @@ -128,7 +198,6 @@ def main(): '--no-crunch', '-f', '--auto-add-overlay', - '-I', android_jar, '-F', options.apk_path, '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN, @@ -152,12 +221,20 @@ def main(): build_utils.ExtractAll(z, path=subdir) package_command += PackageArgsForExtractedZip(subdir) + if options.create_density_splits: + for config in DENSITY_SPLITS.itervalues(): + package_command.extend(('--split', ','.join(config))) + if 'Debug' in options.configuration_name: package_command += ['--debug-mode'] build_utils.CheckOutput( package_command, print_stdout=False, print_stderr=False) + if options.create_density_splits: + CheckDensityMissedConfigs(options.apk_path) + RenameDensitySplits(options.apk_path) + if options.depfile: build_utils.WriteDepfile( options.depfile, diff --git a/build/android/package_resources_action.gypi b/build/android/package_resources_action.gypi index fe1645f..cd6c59c 100644 --- a/build/android/package_resources_action.gypi +++ b/build/android/package_resources_action.gypi @@ -12,6 +12,8 @@ # app_manifest_version_code - set the apps version number. # Optional variables: # asset_location - The directory where assets are located (if any). +# create_density_splits - Whether to create density-based apk splits. Splits +# are supported only for minSdkVersion >= 21. # resource_zips - List of paths to resource zip files. # shared_resources - Make a resource package that can be loaded by a different # application at runtime to access the package's resources. @@ -20,6 +22,7 @@ { 'variables': { 'asset_location%': '', + 'create_density_splits%': 0, 'resource_zips%': [], 'shared_resources%': 0, 'extensions_to_not_compress%': '', @@ -61,6 +64,17 @@ '--asset-dir', '<(asset_location)', ], }], + ['create_density_splits == 1', { + 'action': [ + '--create-density-splits', + ], + 'outputs': [ + '<(resource_packaged_apk_path)-hdpi', + '<(resource_packaged_apk_path)-xhdpi', + '<(resource_packaged_apk_path)-xxhdpi', + '<(resource_packaged_apk_path)-tvdpi', + ], + }], ['resource_zips != []', { 'action': [ '--resource-zips', '>(resource_zips)', |