Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(479)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java

Issue 22272006: Add support for multiple asynchronous browser startups. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merged BrowserStartupConfig and BrowserStartupController. Rebased. Updated ContentShellActivity to … Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser;
6
7 import android.content.Context;
8 import android.os.Handler;
9 import android.util.Log;
10
11 import com.google.common.annotations.VisibleForTesting;
12
13 import org.chromium.base.CalledByNative;
14 import org.chromium.base.JNINamespace;
15 import org.chromium.base.ThreadUtils;
16 import org.chromium.content.common.ProcessInitException;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 /**
22 * This class controls how C++ browser main loop is run and ensures it happens o nly once.
bulach 2013/08/15 15:09:12 s/is run/is started/
nyquist 2013/08/16 02:01:01 Done.
23 *
24 * It supports kicking of the startup sequence in an asynchronous way. Startup c an be called as many
25 * times as needed, but the browser process will still only be initialized once. All requests to
bulach 2013/08/15 15:09:12 times as needed (for instance, multiple activities
nyquist 2013/08/16 02:01:01 Done.
26 * start the browser will always get their callback executed; if the browser pro cess has already
27 * been started, the callback is called immediately, else it is called when init ialization is
28 * complete.
29 *
30 * All communication with this class must happen on the main thread.
31 *
32 * This is a singleton, and stores a reference to the application context.
33 */
34 @JNINamespace("content")
35 public class BrowserStartupController {
36 public interface StartupCallback {
37 void run(int startupResult);
bulach 2013/08/15 15:09:12 nit: maybe "onStartupComplete" ?
nyquist 2013/08/16 02:01:01 Done. Split into two methods: onSuccess and onFail
38 }
39
40 private static final String TAG = "BrowserStartupController";
41
42 private static final Object LOCK = new Object();
43
44 private static BrowserStartupController sInstance;
45
46 private static boolean sBrowserMayStartAsynchronously = false;
47
48 @CalledByNative
49 private static boolean browserMayStartAsynchonously() {
50 return sBrowserMayStartAsynchronously;
51 }
52
53 @CalledByNative
54 private static void browserStartupComplete(int result) {
55 BrowserStartupController instance = null;
56 synchronized (LOCK) {
57 if (sInstance != null) {
58 instance = sInstance;
59 }
60 }
61 if (instance != null) {
62 instance.executeEnqueuedCallbacks(result);
63 }
64 }
65
66 // A list of callbacks that should be called when the async startup of the b rowser process is
67 // complete.
68 private final List<StartupCallback> mAsyncStartupCallbacks;
69
70 private final Context mContext;
bulach 2013/08/15 15:09:12 nit: I heard rumors that this can cause leaks, spe
nyquist 2013/08/16 02:01:01 Done.
71
72 // Whether the async startup of the browser process has started.
73 private boolean mHasStartedInitializingBrowserProcess;
74
75 // Whether the async startup of the browser process is complete.
76 private boolean mAsyncStartupDone;
77
78 BrowserStartupController(Context context) {
79 mContext = context;
80 mAsyncStartupCallbacks = new ArrayList<StartupCallback>();
81 }
82
83 public static BrowserStartupController get(Context context) {
84 synchronized (LOCK) {
85 if (sInstance == null) {
86 sInstance = new BrowserStartupController(context.getApplicationC ontext());
87 }
88 return sInstance;
89 }
90 }
91
92 /**
93 * Start the browser process asynchronously. This will set up a queue of UI thread tasks to
94 * initialize the browser process.
95 * <p/>
96 * Note that this can only be called on the UI thread.
97 *
98 * @param callback the callback to be called when browser startup is complet e.
99 * @return Whether the queue of tasks was created successfully.
bulach 2013/08/15 15:09:12 hmm... would it make sense to have this method "vo
nyquist 2013/08/16 02:01:01 Done.
100 */
101 public boolean startBrowserProcessesAsync(final StartupCallback callback) {
102 assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread.";
103 if (mAsyncStartupDone) {
104 // Browser process is already fully started, so we can immediately p ost the callback.
105 new Handler().post(new Runnable() {
106 @Override
107 public void run() {
108 callback.run(-1);
bulach 2013/08/15 15:09:12 nit: maybe define -1 as public static final int of
nyquist 2013/08/16 02:01:01 Done.
109 }
110 });
111 return true;
112 }
113
114 // Browser process has not been fully started yet, so we defer executing the callback.
115 mAsyncStartupCallbacks.add(callback);
116
117 if (mHasStartedInitializingBrowserProcess) {
118 // We only want to try to initialize the browser process once, so we just return here.
119 return true;
120 } else {
121 // This is the first time we have been asked to start the browser pr ocess. We set the
122 // flag that indicates that we have kicked off starting the browser process.
123 mHasStartedInitializingBrowserProcess = true;
124
125 enableAsynchronousStartup();
126
127 // We can now try to initialize the Android browser process.
128 return initializeAndroidBrowserProcess();
129 }
130 }
131
132 @VisibleForTesting
133 void executeEnqueuedCallbacks(int startupResult) {
134 assert ThreadUtils.runningOnUiThread() : "Callback from browser startup from wrong thread.";
135 mAsyncStartupDone = true;
136 for (StartupCallback asyncStartupCallback : mAsyncStartupCallbacks) {
137 asyncStartupCallback.run(startupResult);
138 }
139 // We don't want to hold on to any objects after we do not need them any more.
140 mAsyncStartupCallbacks.clear();
141 }
142
143 /**
144 * Ensure that the browser process will be asynchronously started up. This a lso ensures that we
145 * get a call to {@link #browserStartupComplete} when the browser startup is complete.
146 */
147 @VisibleForTesting
148 void enableAsynchronousStartup() {
149 sBrowserMayStartAsynchronously = true;
bulach 2013/08/15 15:09:12 need to make find_bugs happy.
nyquist 2013/08/16 02:01:01 Done.
150 }
151
152 @VisibleForTesting
153 boolean initializeAndroidBrowserProcess() {
154 try {
155 AndroidBrowserProcess.init(mContext, AndroidBrowserProcess.MAX_RENDE RERS_LIMIT);
bulach 2013/08/15 15:09:12 nit: Context context = mContext; mContext = null;
nyquist 2013/08/16 02:01:01 Done.
156 } catch (ProcessInitException e) {
157 Log.e(TAG, "Unable to start browser process.", e);
158 return false;
159 }
160 return true;
161 }
162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698