| Index: content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
|
| deleted file mode 100644
|
| index 403c9065588a62fbb315440b07cb903991f77c36..0000000000000000000000000000000000000000
|
| --- a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
|
| +++ /dev/null
|
| @@ -1,310 +0,0 @@
|
| -// Copyright 2013 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.
|
| -
|
| -package org.chromium.content.browser;
|
| -
|
| -import android.content.Context;
|
| -import android.os.Handler;
|
| -import android.util.Log;
|
| -
|
| -import com.google.common.annotations.VisibleForTesting;
|
| -
|
| -import org.chromium.base.CalledByNative;
|
| -import org.chromium.base.JNINamespace;
|
| -import org.chromium.base.ThreadUtils;
|
| -import org.chromium.content.app.ContentMain;
|
| -import org.chromium.content.app.LibraryLoader;
|
| -import org.chromium.content.common.ProcessInitException;
|
| -import org.chromium.content.common.ResultCodes;
|
| -
|
| -import java.util.ArrayList;
|
| -import java.util.List;
|
| -
|
| -/**
|
| - * This class controls how C++ browser main loop is started and ensures it happens only once.
|
| - *
|
| - * It supports kicking off the startup sequence in an asynchronous way. Startup can be called as
|
| - * many times as needed (for instance, multiple activities for the same application), but the
|
| - * browser process will still only be initialized once. All requests to start the browser will
|
| - * always get their callback executed; if the browser process has already been started, the callback
|
| - * is called immediately, else it is called when initialization is complete.
|
| - *
|
| - * All communication with this class must happen on the main thread.
|
| - *
|
| - * This is a singleton, and stores a reference to the application context.
|
| - */
|
| -@JNINamespace("content")
|
| -public class BrowserStartupController {
|
| -
|
| - public interface StartupCallback {
|
| - void onSuccess(boolean alreadyStarted);
|
| - void onFailure();
|
| - }
|
| -
|
| - private static final String TAG = "BrowserStartupController";
|
| -
|
| - // Helper constants for {@link StartupCallback#onSuccess}.
|
| - private static final boolean ALREADY_STARTED = true;
|
| - private static final boolean NOT_ALREADY_STARTED = false;
|
| -
|
| - // Helper constants for {@link #executeEnqueuedCallbacks(int, boolean)}.
|
| - @VisibleForTesting
|
| - static final int STARTUP_SUCCESS = -1;
|
| - @VisibleForTesting
|
| - static final int STARTUP_FAILURE = 1;
|
| -
|
| - private static BrowserStartupController sInstance;
|
| -
|
| - private static boolean sBrowserMayStartAsynchronously = false;
|
| -
|
| - private static void setAsynchronousStartup(boolean enable) {
|
| - sBrowserMayStartAsynchronously = enable;
|
| - }
|
| -
|
| - @VisibleForTesting
|
| - @CalledByNative
|
| - static boolean browserMayStartAsynchonously() {
|
| - return sBrowserMayStartAsynchronously;
|
| - }
|
| -
|
| - @VisibleForTesting
|
| - @CalledByNative
|
| - static void browserStartupComplete(int result) {
|
| - if (sInstance != null) {
|
| - sInstance.executeEnqueuedCallbacks(result, NOT_ALREADY_STARTED);
|
| - }
|
| - }
|
| -
|
| - // A list of callbacks that should be called when the async startup of the browser process is
|
| - // complete.
|
| - private final List<StartupCallback> mAsyncStartupCallbacks;
|
| -
|
| - // The context is set on creation, but the reference is cleared after the browser process
|
| - // initialization has been started, since it is not needed anymore. This is to ensure the
|
| - // context is not leaked.
|
| - private final Context mContext;
|
| -
|
| - // Whether the async startup of the browser process has started.
|
| - private boolean mHasStartedInitializingBrowserProcess;
|
| -
|
| - // Whether the async startup of the browser process is complete.
|
| - private boolean mStartupDone;
|
| -
|
| - // Use single-process mode that runs the renderer on a separate thread in
|
| - // the main application.
|
| - public static final int MAX_RENDERERS_SINGLE_PROCESS = 0;
|
| -
|
| - // Cap on the maximum number of renderer processes that can be requested.
|
| - // This is currently set to account for:
|
| - // 13: The maximum number of sandboxed processes we have available
|
| - // - 1: The regular New Tab Page
|
| - // - 1: The incognito New Tab Page
|
| - // - 1: A regular incognito tab
|
| - // - 1: Safety buffer (http://crbug.com/251279)
|
| - public static final int MAX_RENDERERS_LIMIT =
|
| - ChildProcessLauncher.MAX_REGISTERED_SANDBOXED_SERVICES - 4;
|
| -
|
| - // This field is set after startup has been completed based on whether the startup was a success
|
| - // or not. It is used when later requests to startup come in that happen after the initial set
|
| - // of enqueued callbacks have been executed.
|
| - private boolean mStartupSuccess;
|
| -
|
| - BrowserStartupController(Context context) {
|
| - mContext = context;
|
| - mAsyncStartupCallbacks = new ArrayList<StartupCallback>();
|
| - }
|
| -
|
| - public static BrowserStartupController get(Context context) {
|
| - assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread.";
|
| - ThreadUtils.assertOnUiThread();
|
| - if (sInstance == null) {
|
| - sInstance = new BrowserStartupController(context.getApplicationContext());
|
| - }
|
| - return sInstance;
|
| - }
|
| -
|
| - @VisibleForTesting
|
| - static BrowserStartupController overrideInstanceForTest(BrowserStartupController controller) {
|
| - if (sInstance == null) {
|
| - sInstance = controller;
|
| - }
|
| - return sInstance;
|
| - }
|
| -
|
| - /**
|
| - * Start the browser process asynchronously. This will set up a queue of UI thread tasks to
|
| - * initialize the browser process.
|
| - * <p/>
|
| - * Note that this can only be called on the UI thread.
|
| - *
|
| - * @param callback the callback to be called when browser startup is complete.
|
| - */
|
| - public void startBrowserProcessesAsync(final StartupCallback callback)
|
| - throws ProcessInitException {
|
| - assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread.";
|
| - if (mStartupDone) {
|
| - // Browser process initialization has already been completed, so we can immediately post
|
| - // the callback.
|
| - postStartupCompleted(callback);
|
| - return;
|
| - }
|
| -
|
| - // Browser process has not been fully started yet, so we defer executing the callback.
|
| - mAsyncStartupCallbacks.add(callback);
|
| -
|
| - if (!mHasStartedInitializingBrowserProcess) {
|
| - // This is the first time we have been asked to start the browser process. We set the
|
| - // flag that indicates that we have kicked off starting the browser process.
|
| - mHasStartedInitializingBrowserProcess = true;
|
| -
|
| - prepareToStartBrowserProcess(MAX_RENDERERS_LIMIT);
|
| -
|
| - setAsynchronousStartup(true);
|
| - if (contentStart() > 0) {
|
| - // Failed. The callbacks may not have run, so run them.
|
| - enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Start the browser process synchronously. If the browser is already being started
|
| - * asynchronously then complete startup synchronously
|
| - *
|
| - * <p/>
|
| - * Note that this can only be called on the UI thread.
|
| - *
|
| - * @param maxRenderers The maximum number of renderer processes the browser may
|
| - * create. Zero for single process mode.
|
| - * @throws ProcessInitException
|
| - */
|
| - public void startBrowserProcessesSync(int maxRenderers) throws ProcessInitException {
|
| - // If already started skip to checking the result
|
| - if (!mStartupDone) {
|
| - if (!mHasStartedInitializingBrowserProcess) {
|
| - prepareToStartBrowserProcess(maxRenderers);
|
| - }
|
| -
|
| - setAsynchronousStartup(false);
|
| - if (contentStart() > 0) {
|
| - // Failed. The callbacks may not have run, so run them.
|
| - enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED);
|
| - }
|
| - }
|
| -
|
| - // Startup should now be complete
|
| - assert mStartupDone;
|
| - if (!mStartupSuccess) {
|
| - throw new ProcessInitException(ResultCodes.RESULT_CODE_NATIVE_STARTUP_FAILED);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Wrap ContentMain.start() for testing.
|
| - */
|
| - @VisibleForTesting
|
| - int contentStart() {
|
| - return ContentMain.start();
|
| - }
|
| -
|
| - public void addStartupCompletedObserver(StartupCallback callback) {
|
| - ThreadUtils.assertOnUiThread();
|
| - if (mStartupDone) {
|
| - postStartupCompleted(callback);
|
| - } else {
|
| - mAsyncStartupCallbacks.add(callback);
|
| - }
|
| - }
|
| -
|
| - private void executeEnqueuedCallbacks(int startupResult, boolean alreadyStarted) {
|
| - assert ThreadUtils.runningOnUiThread() : "Callback from browser startup from wrong thread.";
|
| - mStartupDone = true;
|
| - mStartupSuccess = (startupResult <= 0);
|
| - for (StartupCallback asyncStartupCallback : mAsyncStartupCallbacks) {
|
| - if (mStartupSuccess) {
|
| - asyncStartupCallback.onSuccess(alreadyStarted);
|
| - } else {
|
| - asyncStartupCallback.onFailure();
|
| - }
|
| - }
|
| - // We don't want to hold on to any objects after we do not need them anymore.
|
| - mAsyncStartupCallbacks.clear();
|
| - }
|
| -
|
| - // Queue the callbacks to run. Since running the callbacks clears the list it is safe to call
|
| - // this more than once.
|
| - private void enqueueCallbackExecution(final int startupFailure, final boolean alreadyStarted) {
|
| - new Handler().post(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - executeEnqueuedCallbacks(startupFailure, alreadyStarted);
|
| - }
|
| - });
|
| - }
|
| -
|
| - private void postStartupCompleted(final StartupCallback callback) {
|
| - new Handler().post(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - if (mStartupSuccess) {
|
| - callback.onSuccess(ALREADY_STARTED);
|
| - } else {
|
| - callback.onFailure();
|
| - }
|
| - }
|
| - });
|
| - }
|
| -
|
| - @VisibleForTesting
|
| - void prepareToStartBrowserProcess(int maxRendererProcesses) throws ProcessInitException {
|
| - Log.i(TAG, "Initializing chromium process, renderers=" + maxRendererProcesses);
|
| -
|
| - // Normally Main.java will have kicked this off asynchronously for Chrome. But other
|
| - // ContentView apps like tests also need them so we make sure we've extracted resources
|
| - // here. We can still make it a little async (wait until the library is loaded).
|
| - ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext);
|
| - resourceExtractor.startExtractingResources();
|
| -
|
| - // Normally Main.java will have already loaded the library asynchronously, we only need
|
| - // to load it here if we arrived via another flow, e.g. bookmark access & sync setup.
|
| - LibraryLoader.ensureInitialized();
|
| -
|
| - // TODO(yfriedman): Remove dependency on a command line flag for this.
|
| - DeviceUtils.addDeviceSpecificUserAgentSwitch(mContext);
|
| -
|
| - Context appContext = mContext.getApplicationContext();
|
| - // Now we really need to have the resources ready.
|
| - resourceExtractor.waitForCompletion();
|
| -
|
| - nativeSetCommandLineFlags(maxRendererProcesses,
|
| - nativeIsPluginEnabled() ? getPlugins() : null);
|
| - ContentMain.initApplicationContext(appContext);
|
| - }
|
| -
|
| - /**
|
| - * Initialization needed for tests. Mainly used by content browsertests.
|
| - */
|
| - public void initChromiumBrowserProcessForTests() {
|
| - ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext);
|
| - resourceExtractor.startExtractingResources();
|
| - resourceExtractor.waitForCompletion();
|
| -
|
| - // Having a single renderer should be sufficient for tests. We can't have more than
|
| - // MAX_RENDERERS_LIMIT.
|
| - nativeSetCommandLineFlags(1 /* maxRenderers */, null);
|
| - }
|
| -
|
| - private String getPlugins() {
|
| - return PepperPluginManager.getPlugins(mContext);
|
| - }
|
| -
|
| - private static native void nativeSetCommandLineFlags(int maxRenderProcesses,
|
| - String pluginDescriptor);
|
| -
|
| - // Is this an official build of Chrome? Only native code knows for sure. Official build
|
| - // knowledge is needed very early in process startup.
|
| - private static native boolean nativeIsOfficialBuild();
|
| -
|
| - private static native boolean nativeIsPluginEnabled();
|
| -}
|
|
|