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 org.chromium.base.CalledByNative; 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import org.chromium.base.JNINamespace; 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.base.ResourceExtractor; 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import org.chromium.base.ThreadUtils; 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.base.VisibleForTesting; 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) 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This field is set after startup has been completed based on whether the startup was a success 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // or not. It is used when later requests to startup come in that happen after the initial set 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // of enqueued callbacks have been executed. 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private boolean mStartupSuccess; 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BrowserStartupController(Context context) { 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mContext = context; 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks = new ArrayList<StartupCallback>(); 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public static BrowserStartupController get(Context context) { 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread."; 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ThreadUtils.assertOnUiThread(); 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sInstance == null) { 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sInstance = new BrowserStartupController(context.getApplicationContext()); 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return sInstance; 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static BrowserStartupController overrideInstanceForTest(BrowserStartupController controller) { 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sInstance == null) { 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sInstance = controller; 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return sInstance; 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /** 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * Start the browser process asynchronously. This will set up a queue of UI thread tasks to 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * initialize the browser process. 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * <p/> 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * Note that this can only be called on the UI thread. 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * @param callback the callback to be called when browser startup is complete. 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public void startBrowserProcessesAsync(final StartupCallback callback) 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) throws ProcessInitException { 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread."; 135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupDone) { 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Browser process initialization has already been completed, so we can immediately post 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the callback. 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) postStartupCompleted(callback); 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Browser process has not been fully started yet, so we defer executing the callback. 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks.add(callback); 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!mHasStartedInitializingBrowserProcess) { 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This is the first time we have been asked to start the browser process. We set the 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // flag that indicates that we have kicked off starting the browser process. 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mHasStartedInitializingBrowserProcess = true; 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prepareToStartBrowserProcess(false); 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) setAsynchronousStartup(true); 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (contentStart() > 0) { 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Failed. The callbacks may not have run, so run them. 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); 156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /** 161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Start the browser process synchronously. If the browser is already being started 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * asynchronously then complete startup synchronously 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * <p/> 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Note that this can only be called on the UI thread. 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param singleProcess true iff the browser should run single-process, ie. keep renderers in 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * the browser process 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * @throws ProcessInitException 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public void startBrowserProcessesSync(boolean singleProcess) throws ProcessInitException { 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If already started skip to checking the result 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mStartupDone) { 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mHasStartedInitializingBrowserProcess) { 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prepareToStartBrowserProcess(singleProcess); 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) setAsynchronousStartup(false); 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (contentStart() > 0) { 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Failed. The callbacks may not have run, so run them. 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enqueueCallbackExecution(STARTUP_FAILURE, NOT_ALREADY_STARTED); 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Startup should now be complete 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) assert mStartupDone; 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!mStartupSuccess) { 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_STARTUP_FAILED); 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /** 193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Wrap ContentMain.start() for testing. 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) @VisibleForTesting 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int contentStart() { 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ContentMain.start(); 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void addStartupCompletedObserver(StartupCallback callback) { 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ThreadUtils.assertOnUiThread(); 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupDone) { 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) postStartupCompleted(callback); 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks.add(callback); 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private void executeEnqueuedCallbacks(int startupResult, boolean alreadyStarted) { 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert ThreadUtils.runningOnUiThread() : "Callback from browser startup from wrong thread."; 211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) mStartupDone = true; 212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) mStartupSuccess = (startupResult <= 0); 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (StartupCallback asyncStartupCallback : mAsyncStartupCallbacks) { 214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupSuccess) { 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) asyncStartupCallback.onSuccess(alreadyStarted); 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) asyncStartupCallback.onFailure(); 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We don't want to hold on to any objects after we do not need them anymore. 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mAsyncStartupCallbacks.clear(); 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Queue the callbacks to run. Since running the callbacks clears the list it is safe to call 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // this more than once. 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private void enqueueCallbackExecution(final int startupFailure, final boolean alreadyStarted) { 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new Handler().post(new Runnable() { 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @Override 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void run() { 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) executeEnqueuedCallbacks(startupFailure, alreadyStarted); 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }); 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private void postStartupCompleted(final StartupCallback callback) { 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new Handler().post(new Runnable() { 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @Override 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void run() { 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (mStartupSuccess) { 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback.onSuccess(ALREADY_STARTED); 241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback.onFailure(); 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }); 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @VisibleForTesting 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void prepareToStartBrowserProcess(boolean singleProcess) throws ProcessInitException { 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Log.i(TAG, "Initializing chromium process, singleProcess=" + singleProcess); 251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Normally Main.java will have kicked this off asynchronously for Chrome. But other 253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // ContentView apps like tests also need them so we make sure we've extracted resources 254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // here. We can still make it a little async (wait until the library is loaded). 255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext); 256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.startExtractingResources(); 257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Normally Main.java will have already loaded the library asynchronously, we only need 259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // to load it here if we arrived via another flow, e.g. bookmark access & sync setup. 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LibraryLoader.ensureInitialized(mContext, true); 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(yfriedman): Remove dependency on a command line flag for this. 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DeviceUtils.addDeviceSpecificUserAgentSwitch(mContext); 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Context appContext = mContext.getApplicationContext(); 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Now we really need to have the resources ready. 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.waitForCompletion(); 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nativeSetCommandLineFlags(singleProcess, nativeIsPluginEnabled() ? getPlugins() : null); 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ContentMain.initApplicationContext(appContext); 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /** 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Initialization needed for tests. Mainly used by content browsertests. 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public void initChromiumBrowserProcessForTests() { 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext); 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.startExtractingResources(); 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resourceExtractor.waitForCompletion(); 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nativeSetCommandLineFlags(false, null); 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private String getPlugins() { 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PepperPluginManager.getPlugins(mContext); 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private static native void nativeSetCommandLineFlags( 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) boolean singleProcess, String pluginDescriptor); 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Is this an official build of Chrome? Only native code knows for sure. Official build 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // knowledge is needed very early in process startup. 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private static native boolean nativeIsOfficialBuild(); 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private static native boolean nativeIsPluginEnabled(); 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 296