BrowserStartupController.java revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)package org.chromium.content.browser; 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import android.content.Context; 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import android.os.Handler; 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import android.util.Log; 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import com.google.common.annotations.VisibleForTesting; 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import org.chromium.base.CalledByNative; 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import org.chromium.base.JNINamespace; 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import org.chromium.base.ThreadUtils; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import org.chromium.base.library_loader.LibraryLoader; 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import org.chromium.base.library_loader.LoaderErrors; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import org.chromium.base.library_loader.ProcessInitException; 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)import org.chromium.content.app.ContentMain; 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import java.util.ArrayList; 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import java.util.List; 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/** 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * This class controls how C++ browser main loop is started and ensures it happens only once. 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * It supports kicking off the startup sequence in an asynchronous way. Startup can be called as 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * many times as needed (for instance, multiple activities for the same application), but the 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * browser process will still only be initialized once. All requests to start the browser will 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * always get their callback executed; if the browser process has already been started, the callback 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * is called immediately, else it is called when initialization is complete. 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * All communication with this class must happen on the main thread. 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * This is a singleton, and stores a reference to the application context. 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)@JNINamespace("content") 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)public class BrowserStartupController { 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * This provides the interface to the callbacks for successful or failed startup 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public interface StartupCallback { 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void onSuccess(boolean alreadyStarted); 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void onFailure(); 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private static final String TAG = "BrowserStartupController"; 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Helper constants for {@link StartupCallback#onSuccess}. 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private static final boolean ALREADY_STARTED = true; 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private static final boolean NOT_ALREADY_STARTED = false; 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Helper constants for {@link #executeEnqueuedCallbacks(int, boolean)}. 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static final int STARTUP_SUCCESS = -1; 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static final int STARTUP_FAILURE = 1; 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private static BrowserStartupController sInstance; 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private static boolean sBrowserMayStartAsynchronously = false; 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private static void setAsynchronousStartup(boolean enable) { 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) sBrowserMayStartAsynchronously = enable; 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) @VisibleForTesting 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @CalledByNative 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) static boolean browserMayStartAsynchonously() { 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return sBrowserMayStartAsynchronously; 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @CalledByNative 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static void browserStartupComplete(int result) { 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sInstance != null) { 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sInstance.executeEnqueuedCallbacks(result, NOT_ALREADY_STARTED); 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // A list of callbacks that should be called when the async startup of the browser process is 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // complete. 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private final List<StartupCallback> mAsyncStartupCallbacks; 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The context is set on creation, but the reference is cleared after the browser process 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // initialization has been started, since it is not needed anymore. This is to ensure the 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // context is not leaked. 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private final Context mContext; 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Whether the async startup of the browser process has started. 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private boolean mHasStartedInitializingBrowserProcess; 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Whether the async startup of the browser process is complete. 95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private boolean mStartupDone; 96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Use single-process mode that runs the renderer on a separate thread in 98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the main application. 99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public static final int MAX_RENDERERS_SINGLE_PROCESS = 0; 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Cap on the maximum number of renderer processes that can be requested. 102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This is currently set to account for: 103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // 13: The maximum number of sandboxed processes we have available 104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // - 1: The regular New Tab Page 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // - 1: The incognito New Tab Page 106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // - 1: A regular incognito tab 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // - 1: Safety buffer (http://crbug.com/251279) 108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public static final int MAX_RENDERERS_LIMIT = 109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ChildProcessLauncher.MAX_REGISTERED_SANDBOXED_SERVICES - 4; 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This field is set after startup has been completed based on whether the startup was a success 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // or not. It is used when later requests to startup come in that happen after the initial set 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // of enqueued callbacks have been executed. 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private boolean mStartupSuccess; 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BrowserStartupController(Context context) { 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mContext = context; 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks = new ArrayList<StartupCallback>(); 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public static BrowserStartupController get(Context context) { 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread."; 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ThreadUtils.assertOnUiThread(); 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sInstance == null) { 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sInstance = new BrowserStartupController(context.getApplicationContext()); 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return sInstance; 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static BrowserStartupController overrideInstanceForTest(BrowserStartupController controller) { 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sInstance == null) { 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sInstance = controller; 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return sInstance; 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /** 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * Start the browser process asynchronously. This will set up a queue of UI thread tasks to 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * initialize the browser process. 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * <p/> 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * Note that this can only be called on the UI thread. 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * @param callback the callback to be called when browser startup is complete. 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public void startBrowserProcessesAsync(final StartupCallback callback) 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) throws ProcessInitException { 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread."; 149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupDone) { 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Browser process initialization has already been completed, so we can immediately post 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the callback. 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) postStartupCompleted(callback); 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Browser process has not been fully started yet, so we defer executing the callback. 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks.add(callback); 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!mHasStartedInitializingBrowserProcess) { 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This is the first time we have been asked to start the browser process. We set the 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // flag that indicates that we have kicked off starting the browser process. 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mHasStartedInitializingBrowserProcess = true; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) prepareToStartBrowserProcess(MAX_RENDERERS_LIMIT); 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) setAsynchronousStartup(true); 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (contentStart() > 0) { 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Failed. The callbacks may not have run, so run them. 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /** 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Start the browser process synchronously. If the browser is already being started 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * asynchronously then complete startup synchronously 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * <p/> 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Note that this can only be called on the UI thread. 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param maxRenderers The maximum number of renderer processes the browser may 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * create. Zero for single process mode. 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * @throws ProcessInitException 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public void startBrowserProcessesSync(int maxRenderers) throws ProcessInitException { 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If already started skip to checking the result 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mStartupDone) { 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mHasStartedInitializingBrowserProcess) { 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) prepareToStartBrowserProcess(maxRenderers); 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) setAsynchronousStartup(false); 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (contentStart() > 0) { 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Failed. The callbacks may not have run, so run them. 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Startup should now be complete 200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) assert mStartupDone; 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mStartupSuccess) { 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_STARTUP_FAILED); 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /** 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Wrap ContentMain.start() for testing. 208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) @VisibleForTesting 210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int contentStart() { 211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ContentMain.start(); 212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void addStartupCompletedObserver(StartupCallback callback) { 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ThreadUtils.assertOnUiThread(); 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupDone) { 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) postStartupCompleted(callback); 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks.add(callback); 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private void executeEnqueuedCallbacks(int startupResult, boolean alreadyStarted) { 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert ThreadUtils.runningOnUiThread() : "Callback from browser startup from wrong thread."; 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) mStartupDone = true; 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) mStartupSuccess = (startupResult <= 0); 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (StartupCallback asyncStartupCallback : mAsyncStartupCallbacks) { 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupSuccess) { 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) asyncStartupCallback.onSuccess(alreadyStarted); 230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) asyncStartupCallback.onFailure(); 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We don't want to hold on to any objects after we do not need them anymore. 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks.clear(); 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Queue the callbacks to run. Since running the callbacks clears the list it is safe to call 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // this more than once. 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private void enqueueCallbackExecution(final int startupFailure, final boolean alreadyStarted) { 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new Handler().post(new Runnable() { 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @Override 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void run() { 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) executeEnqueuedCallbacks(startupFailure, alreadyStarted); 2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }); 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private void postStartupCompleted(final StartupCallback callback) { 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new Handler().post(new Runnable() { 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @Override 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void run() { 253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupSuccess) { 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback.onSuccess(ALREADY_STARTED); 255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback.onFailure(); 257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }); 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void prepareToStartBrowserProcess(int maxRendererProcesses) throws ProcessInitException { 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Log.i(TAG, "Initializing chromium process, renderers=" + maxRendererProcesses); 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Normally Main.java will have kicked this off asynchronously for Chrome. But other 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // ContentView apps like tests also need them so we make sure we've extracted resources 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // here. We can still make it a little async (wait until the library is loaded). 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext); 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.startExtractingResources(); 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Normally Main.java will have already loaded the library asynchronously, we only need 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // to load it here if we arrived via another flow, e.g. bookmark access & sync setup. 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LibraryLoader.ensureInitialized(); 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(yfriedman): Remove dependency on a command line flag for this. 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DeviceUtils.addDeviceSpecificUserAgentSwitch(mContext); 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Context appContext = mContext.getApplicationContext(); 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Now we really need to have the resources ready. 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.waitForCompletion(); 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) nativeSetCommandLineFlags(maxRendererProcesses, 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) nativeIsPluginEnabled() ? getPlugins() : null); 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ContentMain.initApplicationContext(appContext); 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /** 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Initialization needed for tests. Mainly used by content browsertests. 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public void initChromiumBrowserProcessForTests() { 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext); 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.startExtractingResources(); 294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.waitForCompletion(); 295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Having a single renderer should be sufficient for tests. We can't have more than 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // MAX_RENDERERS_LIMIT. 298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) nativeSetCommandLineFlags(1 /* maxRenderers */, null); 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private String getPlugins() { 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PepperPluginManager.getPlugins(mContext); 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private static native void nativeSetCommandLineFlags(int maxRenderProcesses, 306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) String pluginDescriptor); 307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Is this an official build of Chrome? Only native code knows for sure. Official build 309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // knowledge is needed very early in process startup. 310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private static native boolean nativeIsOfficialBuild(); 311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private static native boolean nativeIsPluginEnabled(); 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 314