Commit 6516122e authored by hjd's avatar hjd Committed by Commit bot

Fix CommandLine initialization for Chrome & WebView

Chrome may access the CommandLine from Java in-between 'load' and
'initialize' which currently causes an crash since JNI is not ready
until after initialize but the CommandLine is switched over to native
after load (we moved the CommandLine switch to after load to fix a
problem in the Webview).

This fixes the problem for Chrome by moving the CommandLine switch
back to after initialize but provides a method to cause the switch to
happen early so the WebView problem can be fixed to.

BUG=417053,331424

Review URL: https://codereview.chromium.org/598363003

Cr-Commit-Position: refs/heads/master@{#296924}
parent 7f1cd3a3
......@@ -8,6 +8,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.android_webview.AwBrowserProcess;
import org.chromium.base.CommandLine;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.test.util.Feature;
/**
......@@ -34,6 +35,7 @@ public class CommandLineTest extends AwTestBase {
// Setup Chrome.
AwBrowserProcess.loadLibrary();
LibraryLoader.switchCommandLineForWebView();
// Now we should have switched to a native backed command line:
cl = CommandLine.getInstance();
......
......@@ -37,6 +37,10 @@ public class LibraryLoader {
// One-way switch becomes true when the libraries are loaded.
private static boolean sLoaded = false;
// One-way switch becomes true when the Java command line is switched to
// native.
private static boolean sCommandLineSwitched = false;
// One-way switch becomes true when the libraries are initialized (
// by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in
// library_loader_hooks.cc).
......@@ -216,9 +220,6 @@ public class LibraryLoader {
startTime % 10000,
stopTime % 10000));
nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull());
CommandLine.enableNativeProxy();
sLoaded = true;
}
} catch (UnsatisfiedLinkError e) {
......@@ -235,12 +236,39 @@ public class LibraryLoader {
}
}
// The WebView requires the Command Line to be switched over before
// initialization is done. This is okay in the WebView's case since the
// JNI is already loaded by this point.
public static void switchCommandLineForWebView() {
synchronized (sLock) {
ensureCommandLineSwitchedAlreadyLocked();
}
}
// Switch the CommandLine over from Java to native if it hasn't already been done.
// This must happen after the code is loaded and after JNI is ready (since after the
// switch the Java CommandLine will delegate all calls the native CommandLine).
private static void ensureCommandLineSwitchedAlreadyLocked() {
assert sLoaded;
if (sCommandLineSwitched) {
return;
}
nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull());
CommandLine.enableNativeProxy();
sCommandLineSwitched = true;
}
// Invoke base::android::LibraryLoaded in library_loader_hooks.cc
private static void initializeAlreadyLocked() throws ProcessInitException {
if (sInitialized) {
return;
}
// Setup the native command line if necessary.
if (!sCommandLineSwitched) {
nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull());
}
if (!nativeLibraryLoaded()) {
Log.e(TAG, "error calling nativeLibraryLoaded");
throw new ProcessInitException(LoaderErrors.LOADER_ERROR_FAILED_TO_REGISTER_JNI);
......@@ -250,6 +278,13 @@ public class LibraryLoader {
// following calls).
sInitialized = true;
// The Chrome JNI is registered by now so we can switch the Java
// command line over to delegating to native if it's necessary.
if (!sCommandLineSwitched) {
CommandLine.enableNativeProxy();
sCommandLineSwitched = true;
}
// From now on, keep tracing in sync with native.
TraceEvent.registerNativeEnabledObserver();
}
......
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