Commit 9df6d778 authored by Eric Stevenson's avatar Eric Stevenson Committed by Commit Bot

Reland "Android: Remove BuildHooksAndroidImpl from the main dex."

This is a reland of eb3da872

Original change's description:
> Android: Remove BuildHooksAndroidImpl from the main dex.
> 
> Removing the reference to BuildHooksAndroidImpl from BuildHooksAndroid
> shrinks the main dex by ~2000 methods for downstream targets.
> 
> Bug: 820570
> Change-Id: If4051f7a85e387129c65a7a5b927183b5b36bf65
> Reviewed-on: https://chromium-review.googlesource.com/1089625
> Commit-Queue: Eric Stevenson <estevenson@chromium.org>
> Reviewed-by: agrieve <agrieve@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#565305}

Bug: 820570
Change-Id: I8fbaf650ac1ed444ccc6d2cbd3d6d45ab045451f
Reviewed-on: https://chromium-review.googlesource.com/1093111Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avataragrieve <agrieve@chromium.org>
Commit-Queue: Eric Stevenson <estevenson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567370}
parent 0441bbd3
...@@ -43,6 +43,7 @@ android_library("build_hooks_android_java") { ...@@ -43,6 +43,7 @@ android_library("build_hooks_android_java") {
jar_excluded_patterns = [ "*/BuildHooksAndroidImpl.class" ] jar_excluded_patterns = [ "*/BuildHooksAndroidImpl.class" ]
no_build_hooks = true no_build_hooks = true
proguard_configs = [ "proguard/build_hooks_android_impl.flags" ]
} }
# This default implementation is used if an android_apk target doesn't # This default implementation is used if an android_apk target doesn't
......
...@@ -19,54 +19,79 @@ import android.content.res.Resources; ...@@ -19,54 +19,79 @@ import android.content.res.Resources;
* implementation is supplied to an android_apk target (via build_hooks_android_impl_deps). * implementation is supplied to an android_apk target (via build_hooks_android_impl_deps).
*/ */
public abstract class BuildHooksAndroid { public abstract class BuildHooksAndroid {
private static final BuildHooksAndroidImpl sInstance = new BuildHooksAndroidImpl(); private static BuildHooksAndroid sInstance;
private static BuildHooksAndroid get() {
if (sInstance == null) {
sInstance = constructBuildHooksAndroidImpl();
}
return sInstance;
}
// Creates an instance of BuildHooksAndroidImpl using reflection. Why is this necessary?
// The downstream version of BuildHooksAndroidImpl pulls a bunch of methods into the main dex
// that don't actually need to be there. This happens because there are @MainDex classes that
// have Context methods added (via. bytecode rewriting) that call into BuildHooksAndroid.
// Creating the instance via. reflection tricks proguard into thinking BuildHooksAndroidImpl
// doesn't need to be in the main dex file.
private static BuildHooksAndroid constructBuildHooksAndroidImpl() {
try {
// Not final to avoid inlining. Without this proguard is able to figure out that
// BuildHooksAndroidImpl is actually used.
String implClazzName = "org.chromium.build.BuildHooksAndroidImpl";
Class<?> implClazz = Class.forName(implClazzName);
return (BuildHooksAndroid) implClazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Resources getResources(Context context) { public static Resources getResources(Context context) {
return sInstance.getResourcesImpl(context); return get().getResourcesImpl(context);
} }
protected abstract Resources getResourcesImpl(Context context); protected abstract Resources getResourcesImpl(Context context);
public static AssetManager getAssets(Context context) { public static AssetManager getAssets(Context context) {
return sInstance.getAssetsImpl(context); return get().getAssetsImpl(context);
} }
protected abstract AssetManager getAssetsImpl(Context context); protected abstract AssetManager getAssetsImpl(Context context);
public static Resources.Theme getTheme(Context context) { public static Resources.Theme getTheme(Context context) {
return sInstance.getThemeImpl(context); return get().getThemeImpl(context);
} }
protected abstract Resources.Theme getThemeImpl(Context context); protected abstract Resources.Theme getThemeImpl(Context context);
public static void setTheme(Context context, int theme) { public static void setTheme(Context context, int theme) {
sInstance.setThemeImpl(context, theme); get().setThemeImpl(context, theme);
} }
protected abstract void setThemeImpl(Context context, int theme); protected abstract void setThemeImpl(Context context, int theme);
public static Context createConfigurationContext(Context context) { public static Context createConfigurationContext(Context context) {
return sInstance.createConfigurationContextImpl(context); return get().createConfigurationContextImpl(context);
} }
protected abstract Context createConfigurationContextImpl(Context context); protected abstract Context createConfigurationContextImpl(Context context);
public static int getIdentifier( public static int getIdentifier(
Resources resources, String name, String defType, String defPackage) { Resources resources, String name, String defType, String defPackage) {
return sInstance.getIdentifierImpl(resources, name, defType, defPackage); return get().getIdentifierImpl(resources, name, defType, defPackage);
} }
protected abstract int getIdentifierImpl( protected abstract int getIdentifierImpl(
Resources resources, String name, String defType, String defPackage); Resources resources, String name, String defType, String defPackage);
public static boolean isEnabled() { public static boolean isEnabled() {
return sInstance.isEnabledImpl(); return get().isEnabledImpl();
} }
protected abstract boolean isEnabledImpl(); protected abstract boolean isEnabledImpl();
public static void initCustomResources(Context context) { public static void initCustomResources(Context context) {
sInstance.initCustomResourcesImpl(context); get().initCustomResourcesImpl(context);
} }
protected abstract void initCustomResourcesImpl(Context context); protected abstract void initCustomResourcesImpl(Context context);
...@@ -75,7 +100,7 @@ public abstract class BuildHooksAndroid { ...@@ -75,7 +100,7 @@ public abstract class BuildHooksAndroid {
* Record custom resources related UMA. Requires native library to be loaded. * Record custom resources related UMA. Requires native library to be loaded.
*/ */
public static void maybeRecordResourceMetrics() { public static void maybeRecordResourceMetrics() {
sInstance.maybeRecordResourceMetricsImpl(); get().maybeRecordResourceMetricsImpl();
} }
protected abstract void maybeRecordResourceMetricsImpl(); protected abstract void maybeRecordResourceMetricsImpl();
......
# Copyright 2018 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.
-keep class org.chromium.build.BuildHooksAndroidImpl
...@@ -79,6 +79,11 @@ template("chrome_public_apk_tmpl") { ...@@ -79,6 +79,11 @@ template("chrome_public_apk_tmpl") {
"*R\$*", # Should not use resources from non-browser process. "*R\$*", # Should not use resources from non-browser process.
] ]
} }
# Allow targets to append to the default list.
if (defined(extra_negative_main_dex_globs)) {
negative_main_dex_globs += extra_negative_main_dex_globs
}
} }
if (!is_java_debug) { if (!is_java_debug) {
proguard_enabled = true proguard_enabled = true
......
...@@ -63,13 +63,13 @@ public class ChromeApplication extends Application { ...@@ -63,13 +63,13 @@ public class ChromeApplication extends Application {
UmaUtils.recordMainEntryPointTime(); UmaUtils.recordMainEntryPointTime();
} }
super.attachBaseContext(context); super.attachBaseContext(context);
checkAppBeingReplaced();
ContextUtils.initApplicationContext(this); ContextUtils.initApplicationContext(this);
if (browserProcess) { if (browserProcess) {
if (BuildConfig.IS_MULTIDEX_ENABLED) { if (BuildConfig.IS_MULTIDEX_ENABLED) {
ChromiumMultiDexInstaller.install(this); ChromiumMultiDexInstaller.install(this);
} }
checkAppBeingReplaced();
// 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).
...@@ -125,7 +125,7 @@ public class ChromeApplication extends Application { ...@@ -125,7 +125,7 @@ public class ChromeApplication extends Application {
// During app update the old apk can still be triggered by broadcasts and spin up an // During app update the old apk can still be triggered by broadcasts and spin up an
// out-of-date application. Kill old applications in this bad state. See // out-of-date application. Kill old applications in this bad state. See
// http://crbug.com/658130 for more context and http://b.android.com/56296 for the bug. // http://crbug.com/658130 for more context and http://b.android.com/56296 for the bug.
if (getResources() == null) { if (ContextUtils.getApplicationAssets() == null) {
Log.e(TAG, "getResources() null, closing app."); Log.e(TAG, "getResources() null, closing app.");
System.exit(0); System.exit(0);
} }
......
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