Commit d2a9782d authored by Clark DuVall's avatar Clark DuVall Committed by Chromium LUCI CQ

Make sure chrome split preload has finished before creating activities

I saw some of the class loader mismatch crashes came back after adding
preloading. This will hopefully fix those crashes.

Bug: 1146745
Change-Id: I9e9364ba6d0a69bb38267905461961c018e73133
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2606193Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839632}
parent 0a2ceee2
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.base; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.base;
import static org.chromium.chrome.browser.base.SplitCompatUtils.CHROME_SPLIT_NAME; import static org.chromium.chrome.browser.base.SplitCompatUtils.CHROME_SPLIT_NAME;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper; import android.content.ContextWrapper;
...@@ -42,8 +43,11 @@ import java.lang.reflect.Field; ...@@ -42,8 +43,11 @@ import java.lang.reflect.Field;
*/ */
public class SplitChromeApplication extends SplitCompatApplication { public class SplitChromeApplication extends SplitCompatApplication {
private static final String TAG = "SplitChromeApp"; private static final String TAG = "SplitChromeApp";
@SuppressLint("StaticFieldLeak")
private static SplitPreloader sSplitPreloader;
private String mChromeApplicationClassName; private String mChromeApplicationClassName;
private SplitPreloader mSplitPreloader;
public SplitChromeApplication() { public SplitChromeApplication() {
this(SplitCompatUtils.getIdentifierName( this(SplitCompatUtils.getIdentifierName(
...@@ -56,9 +60,7 @@ public class SplitChromeApplication extends SplitCompatApplication { ...@@ -56,9 +60,7 @@ public class SplitChromeApplication extends SplitCompatApplication {
@Override @Override
public void onCreate() { public void onCreate() {
if (mSplitPreloader != null) { finishPreload(CHROME_SPLIT_NAME);
mSplitPreloader.wait(CHROME_SPLIT_NAME);
}
super.onCreate(); super.onCreate();
} }
...@@ -81,11 +83,9 @@ public class SplitChromeApplication extends SplitCompatApplication { ...@@ -81,11 +83,9 @@ public class SplitChromeApplication extends SplitCompatApplication {
@Override @Override
public Context createContextForSplit(String name) throws PackageManager.NameNotFoundException { public Context createContextForSplit(String name) throws PackageManager.NameNotFoundException {
try (TraceEvent te = TraceEvent.scoped("SplitChromeApplication.createContextForSplit")) { try (TraceEvent te = TraceEvent.scoped("SplitChromeApplication.createContextForSplit")) {
if (mSplitPreloader != null) { // Wait for any splits that are preloading so we don't have a race to update the
// Wait for any splits that are preloading so we don't have a race to update the // class loader cache (b/172602571).
// class loader cache (b/172602571). finishPreload(name);
mSplitPreloader.wait(name);
}
long startTime = SystemClock.uptimeMillis(); long startTime = SystemClock.uptimeMillis();
Context context = super.createContextForSplit(name); Context context = super.createContextForSplit(name);
RecordHistogram.recordTimesHistogram("Android.IsolatedSplits.ContextCreateTime." + name, RecordHistogram.recordTimesHistogram("Android.IsolatedSplits.ContextCreateTime." + name,
...@@ -99,13 +99,13 @@ public class SplitChromeApplication extends SplitCompatApplication { ...@@ -99,13 +99,13 @@ public class SplitChromeApplication extends SplitCompatApplication {
// The chrome split has a large amount of code, which can slow down startup. Loading // The chrome split has a large amount of code, which can slow down startup. Loading
// this in the background allows us to do this in parallel with startup tasks which do // this in the background allows us to do this in parallel with startup tasks which do
// not depend on code in the chrome split. // not depend on code in the chrome split.
mSplitPreloader = new SplitPreloader(context); sSplitPreloader = new SplitPreloader(context);
// If the chrome module is not enabled or isolated splits are not supported (e.g. in Android // If the chrome module is not enabled or isolated splits are not supported (e.g. in Android
// N), the onComplete function will run immediately so it must handle the case where the // N), the onComplete function will run immediately so it must handle the case where the
// base context of the application has not been set yet. // base context of the application has not been set yet.
mSplitPreloader.preload(CHROME_SPLIT_NAME, (chromeContext) -> { sSplitPreloader.preload(CHROME_SPLIT_NAME, (chromeContext) -> {
// When installed, the vr module is always loaded on startup, so preload here. // When installed, the vr module is always loaded on startup, so preload here.
mSplitPreloader.preload("vr", null); sSplitPreloader.preload("vr", null);
// If the chrome module is not enabled or isolated splits are not supported, // If the chrome module is not enabled or isolated splits are not supported,
// chromeContext will have the same ClassLoader as the base context, so no need to // chromeContext will have the same ClassLoader as the base context, so no need to
// replace the ClassLoaders here. // replace the ClassLoaders here.
...@@ -120,6 +120,12 @@ public class SplitChromeApplication extends SplitCompatApplication { ...@@ -120,6 +120,12 @@ public class SplitChromeApplication extends SplitCompatApplication {
return new Impl(); return new Impl();
} }
/* package */ static void finishPreload(String name) {
if (sSplitPreloader != null) {
sSplitPreloader.wait(name);
}
}
/** /**
* Fixes Activity ClassLoader if necessary. Isolated splits can cause a ClassLoader mismatch * Fixes Activity ClassLoader if necessary. Isolated splits can cause a ClassLoader mismatch
* between the Application and Activity ClassLoaders. We have a workaround in * between the Application and Activity ClassLoaders. We have a workaround in
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.base; package org.chromium.chrome.browser.base;
import static org.chromium.chrome.browser.base.SplitCompatUtils.CHROME_SPLIT_NAME;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.AppComponentFactory; import android.app.AppComponentFactory;
...@@ -32,6 +34,9 @@ public class SplitCompatAppComponentFactory extends AppComponentFactory { ...@@ -32,6 +34,9 @@ public class SplitCompatAppComponentFactory extends AppComponentFactory {
@Override @Override
public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) public Activity instantiateActivity(ClassLoader cl, String className, Intent intent)
throws ClassNotFoundException, IllegalAccessException, InstantiationException { throws ClassNotFoundException, IllegalAccessException, InstantiationException {
// Activities will not call createContextForSplit() which will normally ensure the preload
// is finished, so we have to manually ensure that here.
SplitChromeApplication.finishPreload(CHROME_SPLIT_NAME);
return super.instantiateActivity(getComponentClassLoader(cl, className), className, intent); return super.instantiateActivity(getComponentClassLoader(cl, className), className, intent);
} }
......
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