diff options
31 files changed, 278 insertions, 58 deletions
diff --git a/base/BUILD.gn b/base/BUILD.gn index 3c9089d..9e4270d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -1650,6 +1650,7 @@ if (is_android) { android_library("base_java") { srcjar_deps = [ ":base_android_java_enums_srcjar", + ":base_multidex_gen", ":base_native_libraries_gen", ] @@ -1725,6 +1726,14 @@ if (is_android) { ] } + # GYP: //base/base.gyp:base_multidex_gen + java_cpp_template("base_multidex_gen") { + sources = [ + "android/java/templates/ChromiumMultiDex.template", + ] + package_name = "org/chromium/base/multidex" + } + # GYP: //base/base.gyp:base_native_libraries_gen java_cpp_template("base_native_libraries_gen") { sources = [ diff --git a/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java b/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java index ad5cdd8..1cd2acf 100644 --- a/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java +++ b/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java @@ -11,10 +11,13 @@ import android.animation.TimeAnimator; import android.animation.TimeAnimator.TimeListener; import android.util.Log; +import org.chromium.base.annotations.MainDex; + /** * Record Android animation frame rate and save it to UMA histogram. This is mainly for monitoring * any jankiness of short Chrome Android animations. It is limited to few seconds of recording. */ +@MainDex public class AnimationFrameTimeHistogram { private static final String TAG = "AnimationFrameTimeHistogram"; private static final int MAX_FRAME_TIME_NUM = 600; // 10 sec on 60 fps. diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java index 5035b9c..9f77595 100644 --- a/base/android/java/src/org/chromium/base/ApplicationStatus.java +++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java @@ -12,6 +12,7 @@ import android.os.Bundle; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.MainDex; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -24,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; * to register / unregister listeners for state changes. */ @JNINamespace("base::android") +@MainDex public class ApplicationStatus { private static class ActivityInfo { private int mStatus = ActivityState.DESTROYED; diff --git a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java index 1c1f826..e4e6e20 100644 --- a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java +++ b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java @@ -10,6 +10,8 @@ import android.content.Context; import android.os.Bundle; import android.view.Window; +import org.chromium.base.multidex.ChromiumMultiDex; + /** * Basic application functionality that should be shared among all browser applications. */ @@ -26,6 +28,12 @@ public class BaseChromiumApplication extends Application { mShouldInitializeApplicationStatusTracking = shouldInitializeApplicationStatusTracking; } + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + ChromiumMultiDex.install(this); + } + /** * Interface to be implemented by listeners for window focus events. */ diff --git a/base/android/java/src/org/chromium/base/CommandLine.java b/base/android/java/src/org/chromium/base/CommandLine.java index bb227f1..efef22a 100644 --- a/base/android/java/src/org/chromium/base/CommandLine.java +++ b/base/android/java/src/org/chromium/base/CommandLine.java @@ -7,6 +7,8 @@ package org.chromium.base; import android.text.TextUtils; import android.util.Log; +import org.chromium.base.annotations.MainDex; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -25,6 +27,7 @@ import java.util.concurrent.atomic.AtomicReference; * file at a specific location early during startup. Applications each define their own files, e.g., * ContentShellApplication.COMMAND_LINE_FILE. **/ +@MainDex public abstract class CommandLine { /** * Allows classes who cache command line flags to be notified when those arguments are updated diff --git a/base/android/java/src/org/chromium/base/FieldTrialList.java b/base/android/java/src/org/chromium/base/FieldTrialList.java index 5fc9a1f..cfd7d5c 100644 --- a/base/android/java/src/org/chromium/base/FieldTrialList.java +++ b/base/android/java/src/org/chromium/base/FieldTrialList.java @@ -4,9 +4,12 @@ package org.chromium.base; +import org.chromium.base.annotations.MainDex; + /** * Helper to get field trial information. */ +@MainDex public class FieldTrialList { private FieldTrialList() {} diff --git a/base/android/java/src/org/chromium/base/JNIUtils.java b/base/android/java/src/org/chromium/base/JNIUtils.java index adbd36c..f971b5e 100644 --- a/base/android/java/src/org/chromium/base/JNIUtils.java +++ b/base/android/java/src/org/chromium/base/JNIUtils.java @@ -5,10 +5,12 @@ package org.chromium.base; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.MainDex; /** * This class provides JNI-related methods to the native library. */ +@MainDex public class JNIUtils { /** * This returns a ClassLoader that is capable of loading Chromium Java code. Such a ClassLoader diff --git a/base/android/java/src/org/chromium/base/MemoryPressureListener.java b/base/android/java/src/org/chromium/base/MemoryPressureListener.java index c1109ef..d61a006 100644 --- a/base/android/java/src/org/chromium/base/MemoryPressureListener.java +++ b/base/android/java/src/org/chromium/base/MemoryPressureListener.java @@ -10,6 +10,7 @@ import android.content.Context; import android.content.res.Configuration; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.MainDex; /** @@ -17,6 +18,7 @@ import org.chromium.base.annotations.CalledByNative; * It registers a ComponentCallbacks2 with the system, and dispatches into * native for levels that are considered actionable. */ +@MainDex public class MemoryPressureListener { /** * Sending an intent with this action to Chrome will cause it to issue a call to onLowMemory diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java index 01b036b..81c74f4 100644 --- a/base/android/java/src/org/chromium/base/PathUtils.java +++ b/base/android/java/src/org/chromium/base/PathUtils.java @@ -11,6 +11,7 @@ import android.os.Environment; import android.os.StrictMode; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.MainDex; import java.io.File; import java.util.concurrent.ExecutionException; @@ -18,6 +19,7 @@ import java.util.concurrent.ExecutionException; /** * This class provides the path related methods for the native library. */ +@MainDex public abstract class PathUtils { private static final String THUMBNAIL_DIRECTORY = "textures"; diff --git a/base/android/java/src/org/chromium/base/SystemMessageHandler.java b/base/android/java/src/org/chromium/base/SystemMessageHandler.java index 37d5ef0..ebcc0d9 100644 --- a/base/android/java/src/org/chromium/base/SystemMessageHandler.java +++ b/base/android/java/src/org/chromium/base/SystemMessageHandler.java @@ -10,10 +10,12 @@ import android.os.Handler; import android.os.Message; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.MainDex; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +@MainDex class SystemMessageHandler extends Handler { private static final String TAG = "cr.SysMessageHandler"; diff --git a/base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java b/base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java index 581c661..d0ab312 100644 --- a/base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java +++ b/base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java @@ -11,6 +11,7 @@ import org.chromium.base.Log; import org.chromium.base.SysUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.MainDex; import java.util.HashMap; import java.util.Locale; @@ -31,6 +32,7 @@ import javax.annotation.Nullable; * * For more on the operations performed by the Linker, see {@link Linker}. */ +@MainDex class LegacyLinker extends Linker { // Log tag for this class. private static final String TAG = "LibraryLoader"; diff --git a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDex.java b/base/android/java/templates/ChromiumMultiDex.template index 7696a14..18b3c77 100644 --- a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDex.java +++ b/base/android/java/templates/ChromiumMultiDex.template @@ -30,6 +30,7 @@ public class ChromiumMultiDex { * @param context The application context. */ @VisibleForTesting +#if defined(CONFIGURATION_NAME_Debug) public static void install(Context context) { try { // TODO(jbudorick): Back out this version check once support for K & below works. @@ -54,5 +55,9 @@ public class ChromiumMultiDex { throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return (boolean) Process.class.getMethod("isIsolated").invoke(null); } +#else + public static void install(Context context) { + } +#endif } diff --git a/base/base.gyp b/base/base.gyp index be50515..e8d449f 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -1460,6 +1460,22 @@ 'includes': [ '../build/android/java_cpp_template.gypi' ], }, { + # GN: //base:base_multidex_gen + 'target_name': 'base_multidex_gen', + 'type': 'none', + 'sources': [ + 'android/java/templates/ChromiumMultiDex.template', + ], + 'variables': { + 'package_name': 'org/chromium/base/multidex', + 'template_deps': [], + 'additional_gcc_preprocess_options': [ + '--defines', 'CONFIGURATION_NAME_<(CONFIGURATION_NAME)', + ], + }, + 'includes': ['../build/android/java_cpp_template.gypi'], + }, + { # GN: //base:base_android_java_enums_srcjar 'target_name': 'base_java_library_process_type', 'type': 'none', @@ -1481,6 +1497,7 @@ 'base_java_library_load_from_apk_status_codes', 'base_java_library_process_type', 'base_java_memory_pressure_level', + 'base_multidex_gen', 'base_native_libraries_gen', '../third_party/android_tools/android_tools.gyp:android_support_multidex_javalib', '../third_party/jsr-305/jsr-305.gyp:jsr_305_javalib', diff --git a/build/android/gyp/apk_obfuscate.py b/build/android/gyp/apk_obfuscate.py index a227945..4a13cb1 100755 --- a/build/android/gyp/apk_obfuscate.py +++ b/build/android/gyp/apk_obfuscate.py @@ -10,14 +10,22 @@ If proguard is not enabled or 'Release' is not in the configuration name, obfuscation will be a no-op. """ +import json import optparse import os import sys +import tempfile from util import build_utils from util import proguard_util +_PROGUARD_KEEP_CLASS = '''-keep class %s { + *; +} +''' + + def ParseArgs(argv): parser = optparse.OptionParser() parser.add_option('--android-sdk', help='path to the Android SDK folder') @@ -56,6 +64,12 @@ def ParseArgs(argv): parser.add_option('--stamp', help='File to touch on success') + parser.add_option('--main-dex-list-path', + help='The list of classes to retain in the main dex. ' + 'These will not be obfuscated.') + parser.add_option('--multidex-configuration-path', + help='A JSON file containing multidex build configuration.') + (options, args) = parser.parse_args(argv) if args: @@ -98,11 +112,41 @@ def DoProguard(options): proguard.libraryjars([options.android_sdk_jar]) proguard_injars = [p for p in input_jars if p not in exclude_paths] proguard.injars(proguard_injars) - proguard.configs(configs) + multidex_config = _PossibleMultidexConfig(options) + if multidex_config: + configs.append(multidex_config) + + proguard.configs(configs) proguard.CheckOutput() +def _PossibleMultidexConfig(options): + if not options.multidex_configuration_path: + return None + + with open(options.multidex_configuration_path) as multidex_config_file: + multidex_config = json.loads(multidex_config_file.read()) + + if not (multidex_config.get('enabled') and options.main_dex_list_path): + return None + + main_dex_list_config = '' + with open(options.main_dex_list_path) as main_dex_list: + for clazz in (l.strip() for l in main_dex_list): + if clazz.endswith('.class'): + clazz = clazz[:-len('.class')] + clazz = clazz.replace('/', '.') + main_dex_list_config += (_PROGUARD_KEEP_CLASS % clazz) + with tempfile.NamedTemporaryFile( + delete=False, + dir=os.path.dirname(options.main_dex_list_path), + prefix='main_dex_list_proguard', + suffix='.flags') as main_dex_config_file: + main_dex_config_file.write(main_dex_list_config) + return main_dex_config_file.name + + def main(argv): options, _ = ParseArgs(argv) diff --git a/build/android/gyp/configure_multidex.py b/build/android/gyp/configure_multidex.py new file mode 100755 index 0000000..aa85d2f --- /dev/null +++ b/build/android/gyp/configure_multidex.py @@ -0,0 +1,55 @@ +#!/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. + + +import argparse +import json +import sys + +from util import build_utils + + +def ParseArgs(): + parser = argparse.ArgumentParser() + parser.add_argument('--configuration-name', required=True, + help='The build CONFIGURATION_NAME.') + parser.add_argument('--enabled-configurations', default=[], + help='The configuration(s) for which multidex should be ' + 'enabled. If not specified and --enable-multidex is ' + 'passed, multidex will be enabled for all ' + 'configurations.') + parser.add_argument('--multidex-configuration-path', required=True, + help='The path to which the multidex configuration JSON ' + 'should be saved.') + + args = parser.parse_args() + + if args.enabled_configurations: + args.enabled_configurations = build_utils.ParseGypList( + args.enabled_configurations) + + return args + + +def main(): + args = ParseArgs() + + multidex_enabled = ( + (not args.enabled_configurations + or args.configuration_name in args.enabled_configurations)) + + config = { + 'enabled': multidex_enabled, + } + + with open(args.multidex_configuration_path, 'w') as f: + f.write(json.dumps(config)) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) + diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py index 67f43e9..2fef369 100755 --- a/build/android/gyp/dex.py +++ b/build/android/gyp/dex.py @@ -4,6 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import json import logging import optparse import os @@ -14,14 +15,6 @@ import zipfile from util import build_utils -def _CreateCombinedMainDexList(main_dex_list_paths): - main_dex_list = [] - for m in main_dex_list_paths: - with open(m) as main_dex_list_file: - main_dex_list.extend(l for l in main_dex_list_file if l) - return '\n'.join(main_dex_list) - - def _RemoveUnwantedFilesFromZip(dex_path): iz = zipfile.ZipFile(dex_path, 'r') tmp_dex_path = '%s.tmp.zip' % dex_path @@ -56,32 +49,35 @@ def _ParseArgs(args): 'is enabled.')) parser.add_option('--no-locals', help='Exclude locals list from the dex file.') - parser.add_option('--multi-dex', default=False, action='store_true', - help='Create multiple dex files.') parser.add_option('--incremental', action='store_true', help='Enable incremental builds when possible.') parser.add_option('--inputs', help='A list of additional input paths.') parser.add_option('--excluded-paths', help='A list of paths to exclude from the dex file.') - parser.add_option('--main-dex-list-paths', - help='A list of paths containing a list of the classes to ' + parser.add_option('--main-dex-list-path', + help='A file containing a list of the classes to ' 'include in the main dex.') + parser.add_option('--multidex-configuration-path', + help='A JSON file containing multidex build configuration.') options, paths = parser.parse_args(args) required_options = ('android_sdk_tools',) build_utils.CheckOptions(options, parser, required=required_options) - if options.multi_dex and not options.main_dex_list_paths: - logging.warning('--multi-dex is unused without --main-dex-list-paths') + options.multi_dex = False + if options.multidex_configuration_path: + with open(options.multidex_configuration_path) as multidex_config_file: + multidex_config = json.loads(multidex_config_file.read()) + options.multi_dex = multidex_config.get('enabled', False) + + if options.multi_dex and not options.main_dex_list_path: + logging.warning('multidex cannot be enabled without --main-dex-list-path') options.multi_dex = False - elif options.main_dex_list_paths and not options.multi_dex: - logging.warning('--main-dex-list-paths is unused without --multi-dex') + elif options.main_dex_list_path and not options.multi_dex: + logging.warning('--main-dex-list-path is unused if multidex is not enabled') - if options.main_dex_list_paths: - options.main_dex_list_paths = build_utils.ParseGypList( - options.main_dex_list_paths) if options.inputs: options.inputs = build_utils.ParseGypList(options.inputs) if options.excluded_paths: @@ -101,11 +97,7 @@ def _RunDx(changes, options, dex_cmd, paths): with build_utils.TempDir() as classes_temp_dir: # --multi-dex is incompatible with --incremental. if options.multi_dex: - combined_main_dex_list = tempfile.NamedTemporaryFile(suffix='.txt') - combined_main_dex_list.write( - _CreateCombinedMainDexList(options.main_dex_list_paths)) - combined_main_dex_list.flush() - dex_cmd.append('--main-dex-list=%s' % combined_main_dex_list.name) + dex_cmd.append('--main-dex-list=%s' % options.main_dex_list_path) else: # Use --incremental when .class files are added or modified (never when # removed). @@ -173,7 +165,7 @@ def main(args): dex_cmd.append('--no-locals') if options.multi_dex: - input_paths.extend(options.main_dex_list_paths) + input_paths.append(options.main_dex_list_path) dex_cmd += [ '--multi-dex', '--minimal-main-dex', diff --git a/build/android/gyp/main_dex_list.py b/build/android/gyp/main_dex_list.py index 6442001..7f29bfb 100755 --- a/build/android/gyp/main_dex_list.py +++ b/build/android/gyp/main_dex_list.py @@ -5,6 +5,7 @@ # found in the LICENSE file. import argparse +import json import os import sys import tempfile @@ -27,12 +28,27 @@ def main(): 'main dex.') parser.add_argument('--main-dex-list-path', required=True, help='The main dex list file to generate.') + parser.add_argument('--enabled-configurations', + help='The build configurations for which a main dex list' + ' should be generated.') + parser.add_argument('--configuration-name', + help='The current build configuration.') + parser.add_argument('--multidex-configuration-path', + help='A JSON file containing multidex build ' + 'configuration.') parser.add_argument('paths', nargs='+', help='JARs for which a main dex list should be ' 'generated.') args = parser.parse_args() + if args.multidex_configuration_path: + with open(args.multidex_configuration_path) as multidex_config_file: + multidex_config = json.loads(multidex_config_file.read()) + + if not multidex_config.get('enabled', False): + return 0 + with open(args.main_dex_list_path, 'w') as main_dex_list_file: shrinked_android_jar = os.path.abspath( @@ -58,7 +74,7 @@ def main(): main_dex_list = '' try: - build_utils.CheckOutput(proguard_cmd) + build_utils.CheckOutput(proguard_cmd, print_stderr=False) java_cmd = [ 'java', '-cp', dx_jar, diff --git a/build/android/java_cpp_template.gypi b/build/android/java_cpp_template.gypi index 3296659..f4ea0a9 100644 --- a/build/android/java_cpp_template.gypi +++ b/build/android/java_cpp_template.gypi @@ -34,6 +34,7 @@ { # Location where all generated Java sources will be placed. 'variables': { + 'additional_gcc_preprocess_options': [], 'include_path%': '<(DEPTH)', 'output_dir': '<(SHARED_INTERMEDIATE_DIR)/templates/<(_target_name)/<(package_name)', }, @@ -74,6 +75,7 @@ '--include-path=<(include_path)', '--output=<(output_path)', '--template=<(RULE_INPUT_PATH)', + '<@(additional_gcc_preprocess_options)', ], 'message': 'Generating Java from cpp template <(RULE_INPUT_PATH)', } diff --git a/build/android/main_dex_action.gypi b/build/android/main_dex_action.gypi index 06717dd..7316ae2 100644 --- a/build/android/main_dex_action.gypi +++ b/build/android/main_dex_action.gypi @@ -21,7 +21,7 @@ { 'message': 'Generating main dex classes list for <(jar_path)', 'variables': { - 'jar_path%': '', + 'jar_paths%': [], 'output_path%': '', 'main_dex_list_script': '<(DEPTH)/build/android/gyp/main_dex_list.py', 'main_dex_rules_path': '<(DEPTH)/build/android/main_dex_classes.flags', @@ -30,6 +30,7 @@ '<(jar_path)', '<(main_dex_list_script)', '<(main_dex_rules_path)', + '<(multidex_configuration_path)', ], 'outputs': [ '<(output_path)', @@ -39,6 +40,7 @@ '--main-dex-list-path', '<(output_path)', '--android-sdk-tools', '<(android_sdk_tools)', '--main-dex-rules-path', '<(main_dex_rules_path)', - '<(jar_path)', + '--multidex-configuration-path', '<(multidex_configuration_path)', + '<@(jar_paths)', ] } diff --git a/build/android/main_dex_classes.flags b/build/android/main_dex_classes.flags index d9689b2..a8d969a 100644 --- a/build/android/main_dex_classes.flags +++ b/build/android/main_dex_classes.flags @@ -1,3 +1,7 @@ -keep @**.MainDex class * { *; } + +-keepclasseswithmembers class * { + public static ** asInterface(android.os.IBinder); +} diff --git a/build/android/push_libraries.gypi b/build/android/push_libraries.gypi index 773c44f..a4a6fcd 100644 --- a/build/android/push_libraries.gypi +++ b/build/android/push_libraries.gypi @@ -44,6 +44,6 @@ '--device-dir=<(device_library_dir)', '--libraries=@FileArg(<(ordered_libraries_file):libraries)', '--stamp=<(push_stamp)', - '--configuration-name=<(configuration_name)', + '--configuration-name=<(CONFIGURATION_NAME)', ], } diff --git a/build/java.gypi b/build/java.gypi index 6f55c1b..9bc1f4b 100644 --- a/build/java.gypi +++ b/build/java.gypi @@ -65,7 +65,6 @@ 'additional_input_paths': [], 'additional_locale_input_paths': [], 'dex_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).dex.jar', - 'main_dex_list_path': '<(intermediate_dir)/main_dex_list.txt', 'generated_src_dirs': ['>@(generated_R_dirs)'], 'generated_R_dirs': [], 'has_java_resources%': 0, @@ -120,7 +119,6 @@ 'variables': { 'input_jars_paths': ['<(jar_final_path)'], 'library_dexed_jars_paths': ['<(dex_path)'], - 'main_dex_list_paths': ['<(main_dex_list_path)'], }, }, }], @@ -327,14 +325,6 @@ ] }, { - 'action_name': 'main_dex_list_for_<(_target_name)', - 'variables': { - 'jar_path': '<(javac_jar_path)', - 'output_path': '<(main_dex_list_path)', - }, - 'includes': [ 'android/main_dex_action.gypi' ], - }, - { 'action_name': 'emma_instr_jar_<(_target_name)', 'message': 'Instrumenting <(_target_name) jar', 'variables': { diff --git a/build/java_apk.gypi b/build/java_apk.gypi index 174ec4d..6b0023e 100644 --- a/build/java_apk.gypi +++ b/build/java_apk.gypi @@ -84,8 +84,6 @@ 'library_jars_paths': [], 'input_jars_paths': [], 'library_dexed_jars_paths': [], - 'main_dex_list_path': '<(intermediate_dir)/main_dex_list.txt', - 'main_dex_list_paths': ['<(main_dex_list_path)'], 'additional_src_dirs': [], 'generated_src_dirs': [], 'app_manifest_version_name%': '<(android_app_version_name)', @@ -146,6 +144,9 @@ 'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar', 'test_jar_path': '<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar', 'enable_multidex%': 0, + 'enable_multidex_configurations%': [], + 'multidex_configuration_path': '<(intermediate_dir)/multidex_config.json', + 'main_dex_list_path': '<(intermediate_dir)/main_dex_list.txt', 'emma_device_jar': '<(android_sdk_root)/tools/lib/emma_device.jar', 'android_manifest_path%': '<(java_in_dir)/AndroidManifest.xml', 'split_android_manifest_path': '<(intermediate_dir)/split-manifests/<(android_app_abi)/AndroidManifest.xml', @@ -509,7 +510,6 @@ 'libraries_top_dir': '<(intermediate_dir)/lib.stripped', 'libraries_source_dir': '<(libraries_top_dir)/lib/<(android_app_abi)', 'device_library_dir': '<(device_intermediate_dir)/lib.stripped', - 'configuration_name': '<(CONFIGURATION_NAME)', }, 'dependencies': [ '<(DEPTH)/build/android/setup.gyp:get_build_device_configurations', @@ -747,7 +747,7 @@ 'dependencies': [ '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands', '<(DEPTH)/tools/android/android_tools.gyp:android_tools', - ] + ], }], ['run_findbugs == 1', { 'actions': [ @@ -786,6 +786,38 @@ }, ], }], + ['enable_multidex == 1', { + 'actions': [ + { + 'action_name': 'main_dex_list_for_<(_target_name)', + 'variables': { + 'jar_paths': ['>@(input_jars_paths)', '<(javac_jar_path)'], + 'output_path': '<(main_dex_list_path)', + }, + 'includes': [ 'android/main_dex_action.gypi' ], + }, + { + 'action_name': 'configure_multidex_for_<(_target_name)', + 'inputs': [ + '<(DEPTH)/build/android/gyp/configure_multidex.py', + ], + 'outputs': [ + '<(multidex_configuration_path)', + ], + 'variables': { + 'additional_multidex_config_options': [], + 'enabled_configurations': ['>@(enable_multidex_configurations)'], + }, + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/configure_multidex.py', + '--configuration-name', '<(CONFIGURATION_NAME)', + '--enabled-configurations', '<(enabled_configurations)', + '--multidex-configuration-path', '<(multidex_configuration_path)', + '>@(additional_multidex_config_options)', + ], + }, + ], + }], ], 'dependencies': [ '<(DEPTH)/tools/android/md5sum/md5sum.gyp:md5sum', @@ -935,14 +967,6 @@ ], }, { - 'action_name': 'main_dex_list_for_<(_target_name)', - 'variables': { - 'jar_path': '<(javac_jar_path)', - 'output_path': '<(main_dex_list_path)', - }, - 'includes': [ 'android/main_dex_action.gypi' ], - }, - { 'action_name': 'emma_instr_jar_<(_target_name)', 'message': 'Instrumenting <(_target_name) jar', 'variables': { @@ -1023,6 +1047,18 @@ '<(test_jar_path)', ], }], + ['enable_multidex == 1', { + 'inputs': [ + '<(main_dex_list_path)', + '<(multidex_configuration_path)', + ], + 'variables': { + 'additional_obfuscate_options': [ + '--main-dex-list-path', '<(main_dex_list_path)', + '--multidex-configuration-path', '<(multidex_configuration_path)', + ], + }, + }], ], 'inputs': [ '<(DEPTH)/build/android/gyp/apk_obfuscate.py', @@ -1077,16 +1113,17 @@ }, 'conditions': [ ['enable_multidex == 1', { + 'inputs': [ + '<(main_dex_list_path)', + '<(multidex_configuration_path)', + ], 'variables': { 'dex_additional_options': [ - '--multi-dex', - '--main-dex-list-paths', '>@(main_dex_list_paths)', + '--main-dex-list-path', '<(main_dex_list_path)' + '--multidex-configuration-path', '<(multidex_configuration_path)', ], }, - 'inputs': [ - '>@(main_dex_list_paths)', - ], - }] + }], ], 'target_conditions': [ ['enable_multidex == 1 or tested_apk_is_multidex == 1', { diff --git a/chrome/android/chrome_apk.gyp b/chrome/android/chrome_apk.gyp index e92491d..5f11ad8 100644 --- a/chrome/android/chrome_apk.gyp +++ b/chrome/android/chrome_apk.gyp @@ -200,6 +200,8 @@ 'native_lib_target': 'libchrome_public', 'java_in_dir': 'java', 'resource_dir': '../../chrome/android/java/res_chromium', + 'enable_multidex': 1, + 'enable_multidex_configurations': ['Debug'], 'conditions': [ # Only attempt loading the library from the APK for 64 bit devices # until the number of 32 bit devices which don't support this diff --git a/content/public/android/java/src/org/chromium/content/browser/FileDescriptorInfo.java b/content/public/android/java/src/org/chromium/content/browser/FileDescriptorInfo.java index 37f093f..7d93c53 100644 --- a/content/public/android/java/src/org/chromium/content/browser/FileDescriptorInfo.java +++ b/content/public/android/java/src/org/chromium/content/browser/FileDescriptorInfo.java @@ -8,10 +8,13 @@ import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; +import org.chromium.base.annotations.MainDex; + /** * Parcelable class that contains file descriptor and file region information to * be passed to child processes. */ +@MainDex public final class FileDescriptorInfo implements Parcelable { public final int mId; public final ParcelFileDescriptor mFd; diff --git a/content/public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java b/content/public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java index 9d83104..3fcc675 100644 --- a/content/public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java +++ b/content/public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java @@ -9,6 +9,7 @@ import android.content.Context; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.MainDex; import java.util.concurrent.FutureTask; @@ -20,6 +21,7 @@ import java.util.concurrent.FutureTask; * content/browser/geolocation/android_location_api_adapter.h. * Based on android.webkit.GeolocationService.java */ +@MainDex @VisibleForTesting public class LocationProviderAdapter { diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java index a225dc8..1c36430 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java @@ -9,6 +9,7 @@ import org.chromium.base.ObserverList.RewindableIterator; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.MainDex; import org.chromium.content_public.browser.WebContentsObserver; /** @@ -16,6 +17,7 @@ import org.chromium.content_public.browser.WebContentsObserver; * avoiding redundant JNI-related work when there are multiple Java-based observers. */ @JNINamespace("content") +@MainDex class WebContentsObserverProxy extends WebContentsObserver { private long mNativeWebContentsObserverProxy; private final ObserverList<WebContentsObserver> mObservers; diff --git a/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java b/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java index 52599da..a20ea0a 100644 --- a/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java +++ b/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java @@ -6,6 +6,7 @@ package org.chromium.mojo.system.impl; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.MainDex; import org.chromium.mojo.system.AsyncWaiter; import org.chromium.mojo.system.Core; import org.chromium.mojo.system.DataPipe; @@ -33,6 +34,7 @@ import java.util.List; * Implementation of {@link Core}. */ @JNINamespace("mojo::android") +@MainDex public class CoreImpl implements Core, AsyncWaiter { /** * Discard flag for the |MojoReadData| operation. diff --git a/sync/android/java/src/org/chromium/sync/notifier/RandomizedInvalidationClientNameGenerator.java b/sync/android/java/src/org/chromium/sync/notifier/RandomizedInvalidationClientNameGenerator.java index 171fa51..0c26f6f 100644 --- a/sync/android/java/src/org/chromium/sync/notifier/RandomizedInvalidationClientNameGenerator.java +++ b/sync/android/java/src/org/chromium/sync/notifier/RandomizedInvalidationClientNameGenerator.java @@ -6,6 +6,8 @@ package org.chromium.sync.notifier; import android.util.Base64; +import org.chromium.base.annotations.MainDex; + import java.util.Random; /** @@ -15,6 +17,7 @@ import java.util.Random; * blocking" feature. That's unfortunate, but better than using a hard-coded ID. A hard-coded ID * could prevent invalidations from being delivered. */ +@MainDex class RandomizedInvalidationClientNameGenerator implements InvalidationClientNameGenerator { private static final Random RANDOM = new Random(); diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index 1a71485..fce9313 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java @@ -23,6 +23,7 @@ import org.chromium.base.ContentUriUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.MainDex; import org.chromium.ui.R; import org.chromium.ui.UiUtils; @@ -37,6 +38,7 @@ import java.util.List; * a set of accepted file types. The path of the selected file is passed to the native dialog. */ @JNINamespace("ui") +@MainDex public class SelectFileDialog implements WindowAndroid.IntentCallback, WindowAndroid.PermissionCallback { private static final String TAG = "SelectFileDialog"; diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java index 0cf00b1..da3d254 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java @@ -12,6 +12,7 @@ import android.util.SparseArray; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.MainDex; import org.chromium.ui.resources.ResourceLoader.ResourceLoaderCallback; import org.chromium.ui.resources.dynamics.DynamicResource; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; @@ -25,6 +26,7 @@ import org.chromium.ui.resources.system.SystemResourceLoader; * This class does not hold any resource state, but passes it directly to native as they are loaded. */ @JNINamespace("ui") +@MainDex public class ResourceManager implements ResourceLoaderCallback { private final SparseArray<ResourceLoader> mResourceLoaders = new SparseArray<ResourceLoader>(); private final SparseArray<SparseArray<LayoutResource>> mLoadedResources = |