Commit 524c5cdd authored by Andrew Grieve's avatar Andrew Grieve Committed by Commit Bot

Android: Remove ApplicationStatus from @MainDex

ApplicationStatus ends up pulling in a *lot* of code, because it ends up
pulling in all of its listeners.

This reduces the main dex size by 3400 methods.

To get ApplicationStatus to not be included:
 * Made @MainDex applicable to methods
   * Changed ContextUtils and ChromeApplication to annotate methods
     rather than entire class.
 * Stopped using mainDexClasses.rules, in order to avoid -keep'ing all
   of ChromeApplication.attachBaseContext(). Really, all that's needed
   to be kept is the part of attachBaseContext() before the
   ChromiumMultiDexInstaller.install() call.

Bug: 820570
Change-Id: I39220b99f6d89b2429ba7406619a485179a3b2fc
Reviewed-on: https://chromium-review.googlesource.com/963307
Commit-Queue: agrieve <agrieve@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarJohn Budorick <jbudorick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543831}
parent 747b7b56
...@@ -14,7 +14,6 @@ import android.view.Window; ...@@ -14,7 +14,6 @@ import android.view.Window;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
...@@ -31,7 +30,6 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -31,7 +30,6 @@ import java.util.concurrent.ConcurrentHashMap;
* to register / unregister listeners for state changes. * to register / unregister listeners for state changes.
*/ */
@JNINamespace("base::android") @JNINamespace("base::android")
@MainDex
public class ApplicationStatus { public class ApplicationStatus {
private static final String TOOLBAR_CALLBACK_INTERNAL_WRAPPER_CLASS = private static final String TOOLBAR_CALLBACK_INTERNAL_WRAPPER_CLASS =
"android.support.v7.internal.app.ToolbarActionBar$ToolbarCallbackWrapper"; "android.support.v7.internal.app.ToolbarActionBar$ToolbarCallbackWrapper";
......
...@@ -15,7 +15,6 @@ import java.lang.annotation.Target; ...@@ -15,7 +15,6 @@ import java.lang.annotation.Target;
* This generally means it's used by renderer processes, which can't load secondary dexes * This generally means it's used by renderer processes, which can't load secondary dexes
* on K and below. * on K and below.
*/ */
@Target(ElementType.TYPE) @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS) @Retention(RetentionPolicy.CLASS)
public @interface MainDex { public @interface MainDex {}
}
...@@ -13,12 +13,13 @@ import android.support.multidex.MultiDex; ...@@ -13,12 +13,13 @@ import android.support.multidex.MultiDex;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.MainDex;
/** /**
* Performs multidex installation for non-isolated processes. * Performs multidex installation for non-isolated processes.
*/ */
@MainDex
public class ChromiumMultiDexInstaller { public class ChromiumMultiDexInstaller {
private static final String TAG = "base_multidex"; private static final String TAG = "base_multidex";
/** /**
......
...@@ -63,15 +63,12 @@ def main(args): ...@@ -63,15 +63,12 @@ def main(args):
os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar')) os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar'))
dx_jar = os.path.abspath( dx_jar = os.path.abspath(
os.path.join(args.android_sdk_tools, 'lib', 'dx.jar')) os.path.join(args.android_sdk_tools, 'lib', 'dx.jar'))
rules_file = os.path.abspath(
os.path.join(args.android_sdk_tools, 'mainDexClasses.rules'))
proguard_cmd = [ proguard_cmd = [
'java', '-jar', args.proguard_path, 'java', '-jar', args.proguard_path,
'-forceprocessing', '-forceprocessing',
'-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify', '-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify',
'-libraryjars', shrinked_android_jar, '-libraryjars', shrinked_android_jar,
'-include', rules_file,
] ]
for m in args.main_dex_rules_paths: for m in args.main_dex_rules_paths:
proguard_cmd.extend(['-include', m]) proguard_cmd.extend(['-include', m])
...@@ -89,7 +86,6 @@ def main(args): ...@@ -89,7 +86,6 @@ def main(args):
input_paths += [ input_paths += [
shrinked_android_jar, shrinked_android_jar,
dx_jar, dx_jar,
rules_file,
] ]
input_paths += args.main_dex_rules_paths input_paths += args.main_dex_rules_paths
......
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
*; *;
} }
-keepclasseswithmembers class * {
@**.MainDex *;
}
-keepclasseswithmembers class * { -keepclasseswithmembers class * {
public static ** asInterface(android.os.IBinder); public static ** asInterface(android.os.IBinder);
} }
...@@ -30,3 +34,24 @@ ...@@ -30,3 +34,24 @@
# Need test classes to be in the main dex because test listing does not # Need test classes to be in the main dex because test listing does not
# load secondary dex on Dalvik devices. # load secondary dex on Dalvik devices.
-keep @**.RunWith class * {} -keep @**.RunWith class * {}
# The following are based on $SDK_BUILD_TOOLS/mainDexClasses.rules
# Ours differ in that it omits -keeps for application / instrumentation /
# backupagents (these are added by aapt's main dex list rules output).
# The keeps in this file are not only redundant, but the explicit -keep
# of Application.attachBaseContext() is overly broad and adds ~20k methods to
# chrome_public_apk at the time of this change.
######## START mainDexClasses.rules ########
# We need to keep all annotation classes because proguard does not trace annotation attribute
# it just filter the annotation attributes according to annotation classes it already kept.
-keep public class * extends java.lang.annotation.Annotation {
*;
}
# Keep old fashion tests in the main dex or they'll be silently ignored by InstrumentationTestRunner↵
-keep public class * extends android.test.InstrumentationTestCase {
<init>();
}
######## END mainDexClasses.rules ########
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# Proguard flags for what to keep through proguarding when multidex is # When multidex is enabled, need to keep the @MainDex annotation so that it
# enabled. Not used during main dex list determination. # can be used to create the main dex list.
-keepattributes *Annotations* -keepattributes *Annotations*
-keep @interface org.chromium.base.annotations.MainDex -keep @interface org.chromium.base.annotations.MainDex
-keep @**.MainDex class * {
*; # Keep the members only if the class is kept. Also required for the annotation
# itself to be kept, which is necessary for main dex list processing.
-keepclassmembers,allowobfuscation class * {
@**.MainDex *;
} }
...@@ -2296,13 +2296,16 @@ if (enable_java_templates) { ...@@ -2296,13 +2296,16 @@ if (enable_java_templates) {
output = _final_dex_path output = _final_dex_path
enable_multidex = _enable_multidex enable_multidex = _enable_multidex
if (_enable_multidex) {
extra_main_dex_proguard_config = _generated_proguard_main_dex_config
deps += [ ":$_process_resources_target" ]
}
# All deps are already included in _dex_sources when proguard is used. # All deps are already included in _dex_sources when proguard is used.
if (!_proguard_enabled) { if (!_proguard_enabled) {
if (_enable_multidex) { if (_enable_multidex) {
_dex_arg_key = _dex_arg_key =
"${_rebased_build_config}:deps_info:java_runtime_classpath" "${_rebased_build_config}:deps_info:java_runtime_classpath"
extra_main_dex_proguard_config = _generated_proguard_main_dex_config
deps += [ ":$_process_resources_target" ]
} else { } else {
_dex_arg_key = _dex_arg_key =
"${_rebased_build_config}:final_dex:dependency_dex_files" "${_rebased_build_config}:final_dex:dependency_dex_files"
......
...@@ -11,6 +11,7 @@ import android.os.Bundle; ...@@ -11,6 +11,7 @@ import android.os.Bundle;
import android.os.Process; import android.os.Process;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.MainDex;
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
/** /**
...@@ -24,6 +25,7 @@ import org.chromium.chrome.browser.util.IntentUtils; ...@@ -24,6 +25,7 @@ import org.chromium.chrome.browser.util.IntentUtils;
* process' Activities. It works around an Android framework issue for alarms set via the * process' Activities. It works around an Android framework issue for alarms set via the
* AlarmManager, which requires a minimum alarm duration of 5 seconds: https://crbug.com/515919. * AlarmManager, which requires a minimum alarm duration of 5 seconds: https://crbug.com/515919.
*/ */
@MainDex // Runs in a separate process.
public class BrowserRestartActivity extends Activity { public class BrowserRestartActivity extends Activity {
public static final String EXTRA_MAIN_PID = public static final String EXTRA_MAIN_PID =
"org.chromium.chrome.browser.BrowserRestartActivity.main_pid"; "org.chromium.chrome.browser.BrowserRestartActivity.main_pid";
......
...@@ -45,7 +45,6 @@ import org.chromium.chrome.browser.vr_shell.VrShellDelegate; ...@@ -45,7 +45,6 @@ import org.chromium.chrome.browser.vr_shell.VrShellDelegate;
* Basic application functionality that should be shared among all browser applications that use * Basic application functionality that should be shared among all browser applications that use
* chrome layer. * chrome layer.
*/ */
@MainDex
public class ChromeApplication extends Application { public class ChromeApplication extends Application {
private static final String COMMAND_LINE_FILE = "chrome-command-line"; private static final String COMMAND_LINE_FILE = "chrome-command-line";
private static final String TAG = "ChromiumApplication"; private static final String TAG = "ChromiumApplication";
...@@ -57,15 +56,19 @@ public class ChromeApplication extends Application { ...@@ -57,15 +56,19 @@ public class ChromeApplication extends Application {
// Quirk: context.getApplicationContext() returns null during this method. // Quirk: context.getApplicationContext() returns null during this method.
@Override @Override
protected void attachBaseContext(Context context) { protected void attachBaseContext(Context context) {
UmaUtils.recordMainEntryPointTime(); boolean browserProcess = ContextUtils.isMainProcess();
if (browserProcess) {
UmaUtils.recordMainEntryPointTime();
}
super.attachBaseContext(context); super.attachBaseContext(context);
checkAppBeingReplaced(); checkAppBeingReplaced();
if (BuildConfig.IS_MULTIDEX_ENABLED) {
ChromiumMultiDexInstaller.install(this);
}
ContextUtils.initApplicationContext(this); ContextUtils.initApplicationContext(this);
if (ContextUtils.isMainProcess()) { if (browserProcess) {
if (BuildConfig.IS_MULTIDEX_ENABLED) {
ChromiumMultiDexInstaller.install(this);
}
// Renderers and GPU process have command line passed to them via IPC // Renderers and GPU process have command line passed to them via IPC
// (see ChildProcessService.java). // (see ChildProcessService.java).
Supplier<Boolean> shouldUseDebugFlags = new Supplier<Boolean>() { Supplier<Boolean> shouldUseDebugFlags = new Supplier<Boolean>() {
...@@ -115,6 +118,7 @@ public class ChromeApplication extends Application { ...@@ -115,6 +118,7 @@ public class ChromeApplication extends Application {
} }
} }
@MainDex
@Override @Override
public void onTrimMemory(int level) { public void onTrimMemory(int level) {
super.onTrimMemory(level); super.onTrimMemory(level);
...@@ -158,6 +162,7 @@ public class ChromeApplication extends Application { ...@@ -158,6 +162,7 @@ public class ChromeApplication extends Application {
/** /**
* @return The DiscardableReferencePool for the application. * @return The DiscardableReferencePool for the application.
*/ */
@MainDex
public DiscardableReferencePool getReferencePool() { public DiscardableReferencePool getReferencePool() {
ThreadUtils.assertOnUiThread(); ThreadUtils.assertOnUiThread();
if (mReferencePool == null) { if (mReferencePool == null) {
......
...@@ -2824,8 +2824,6 @@ test("unit_tests") { ...@@ -2824,8 +2824,6 @@ test("unit_tests") {
deps += [ "//v8:v8_external_startup_data_assets" ] deps += [ "//v8:v8_external_startup_data_assets" ]
} }
android_manifest =
"//chrome/test/android/unit_tests_apk/AndroidManifest.xml"
enable_multidex = true enable_multidex = true
} else { } else {
# !is_android # !is_android
......
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.chromium.native_test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="NativeTests"
android:name="org.chromium.chrome.browser.ChromeApplication">
<activity android:name="org.chromium.native_test.NativeUnitTestActivity"
android:label="NativeTest"
android:configChanges="orientation|keyboardHidden"
android:process=":test_process">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<instrumentation android:name="org.chromium.native_test.NativeTestInstrumentationTestRunner"
android:targetPackage="org.chromium.native_test"
android:label="Instrumentation entry point for org.chromium.native_test"/>
</manifest>
...@@ -64,7 +64,6 @@ android_library("content_shell_java") { ...@@ -64,7 +64,6 @@ android_library("content_shell_java") {
":content_shell_java_resources", ":content_shell_java_resources",
":content_shell_manifest", ":content_shell_manifest",
"//base:base_java", "//base:base_java",
"//base:base_java_test_support",
"//components/content_view:content_view_java", "//components/content_view:content_view_java",
"//content/public/android:content_java", "//content/public/android:content_java",
"//device/geolocation:geolocation_java", "//device/geolocation:geolocation_java",
...@@ -200,7 +199,7 @@ android_library("content_shell_test_java") { ...@@ -200,7 +199,7 @@ android_library("content_shell_test_java") {
instrumentation_test_apk("content_shell_test_apk") { instrumentation_test_apk("content_shell_test_apk") {
deps = [ deps = [
"//base:base_javatests", "//base:base_java_test_support",
"//content/public/android:content_javatests", "//content/public/android:content_javatests",
"//net/android:net_javatests", "//net/android:net_javatests",
"//third_party/android_support_test_runner:runner_java", "//third_party/android_support_test_runner:runner_java",
......
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