OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.init; | 5 package org.chromium.chrome.browser.init; |
6 | 6 |
7 import android.content.Context; | |
8 import android.content.Intent; | 7 import android.content.Intent; |
9 import android.os.Handler; | 8 import android.os.Handler; |
10 import android.os.Looper; | 9 import android.os.Looper; |
11 import android.util.Log; | 10 import android.util.Log; |
12 | 11 |
| 12 import org.chromium.base.ContextUtils; |
13 import org.chromium.base.ThreadUtils; | 13 import org.chromium.base.ThreadUtils; |
14 import org.chromium.base.library_loader.LibraryLoader; | 14 import org.chromium.base.library_loader.LibraryLoader; |
15 import org.chromium.base.library_loader.LibraryProcessType; | 15 import org.chromium.base.library_loader.LibraryProcessType; |
16 import org.chromium.base.library_loader.ProcessInitException; | 16 import org.chromium.base.library_loader.ProcessInitException; |
17 import org.chromium.content.browser.ChildProcessLauncher; | 17 import org.chromium.content.browser.ChildProcessLauncher; |
18 | 18 |
19 import java.util.ArrayList; | 19 import java.util.ArrayList; |
20 import java.util.List; | 20 import java.util.List; |
21 | 21 |
22 /** | 22 /** |
23 * This class controls the different asynchronous states during our initializati
on: | 23 * This class controls the different asynchronous states during our initializati
on: |
24 * 1. During startBackgroundTasks(), we'll kick off loading the library and yiel
d the call stack. | 24 * 1. During startBackgroundTasks(), we'll kick off loading the library and yiel
d the call stack. |
25 * 2. We may receive a onStart() / onStop() call any point after that, whether o
r not | 25 * 2. We may receive a onStart() / onStop() call any point after that, whether o
r not |
26 * the library has been loaded. | 26 * the library has been loaded. |
27 */ | 27 */ |
28 class NativeInitializationController { | 28 class NativeInitializationController { |
29 private static final String TAG = "NativeInitializationController"; | 29 private static final String TAG = "NativeInitializationController"; |
30 | 30 |
31 private final Context mContext; | |
32 private final ChromeActivityNativeDelegate mActivityDelegate; | 31 private final ChromeActivityNativeDelegate mActivityDelegate; |
33 private final Handler mHandler; | 32 private final Handler mHandler; |
34 | 33 |
35 private boolean mOnStartPending; | 34 private boolean mOnStartPending; |
36 private boolean mOnResumePending; | 35 private boolean mOnResumePending; |
37 private List<Intent> mPendingNewIntents; | 36 private List<Intent> mPendingNewIntents; |
38 private List<ActivityResult> mPendingActivityResults; | 37 private List<ActivityResult> mPendingActivityResults; |
39 private boolean mWaitingForFirstDraw; | 38 private boolean mWaitingForFirstDraw; |
40 private boolean mHasDoneFirstDraw; | 39 private boolean mHasDoneFirstDraw; |
41 private boolean mInitializationComplete; | 40 private boolean mInitializationComplete; |
(...skipping 10 matching lines...) Expand all Loading... |
52 public ActivityResult(int requestCode, int resultCode, Intent data) { | 51 public ActivityResult(int requestCode, int resultCode, Intent data) { |
53 this.requestCode = requestCode; | 52 this.requestCode = requestCode; |
54 this.resultCode = resultCode; | 53 this.resultCode = resultCode; |
55 this.data = data; | 54 this.data = data; |
56 } | 55 } |
57 } | 56 } |
58 | 57 |
59 /** | 58 /** |
60 * Create the NativeInitializationController using the main loop and the app
lication context. | 59 * Create the NativeInitializationController using the main loop and the app
lication context. |
61 * It will be linked back to the activity via the given delegate. | 60 * It will be linked back to the activity via the given delegate. |
62 * @param context The context to pull the application context from. | |
63 * @param activityDelegate The activity delegate for the owning activity. | 61 * @param activityDelegate The activity delegate for the owning activity. |
64 */ | 62 */ |
65 public NativeInitializationController(Context context, | 63 public NativeInitializationController(ChromeActivityNativeDelegate activityD
elegate) { |
66 ChromeActivityNativeDelegate activityDelegate) { | |
67 mContext = context.getApplicationContext(); | |
68 mHandler = new Handler(Looper.getMainLooper()); | 64 mHandler = new Handler(Looper.getMainLooper()); |
69 mActivityDelegate = activityDelegate; | 65 mActivityDelegate = activityDelegate; |
70 } | 66 } |
71 | 67 |
72 /** | 68 /** |
73 * Start loading the native library in the background. This kicks off the na
tive initialization | 69 * Start loading the native library in the background. This kicks off the na
tive initialization |
74 * process. | 70 * process. |
75 * | 71 * |
76 * @param allocateChildConnection Whether a spare child connection should be
allocated. Set to | 72 * @param allocateChildConnection Whether a spare child connection should be
allocated. Set to |
77 * false if you know that no new renderer is
needed. | 73 * false if you know that no new renderer is
needed. |
78 */ | 74 */ |
79 public void startBackgroundTasks(final boolean allocateChildConnection) { | 75 public void startBackgroundTasks(final boolean allocateChildConnection) { |
80 // TODO(yusufo) : Investigate using an AsyncTask for this. | 76 // TODO(yusufo) : Investigate using an AsyncTask for this. |
81 new Thread() { | 77 new Thread() { |
82 @Override | 78 @Override |
83 public void run() { | 79 public void run() { |
84 try { | 80 try { |
85 LibraryLoader libraryLoader = | 81 LibraryLoader libraryLoader = |
86 LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER
); | 82 LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER
); |
87 libraryLoader.ensureInitialized(mContext.getApplicationConte
xt()); | 83 libraryLoader.ensureInitialized(); |
88 // The prefetch is done after the library load for two reaso
ns: | 84 // The prefetch is done after the library load for two reaso
ns: |
89 // - It is easier to know the library location after it has | 85 // - It is easier to know the library location after it has |
90 // been loaded. | 86 // been loaded. |
91 // - Testing has shown that this gives the best compromise, | 87 // - Testing has shown that this gives the best compromise, |
92 // by avoiding performance regression on any tested | 88 // by avoiding performance regression on any tested |
93 // device, and providing performance improvement on | 89 // device, and providing performance improvement on |
94 // some. Doing it earlier delays UI inflation and more | 90 // some. Doing it earlier delays UI inflation and more |
95 // generally startup on some devices, most likely by | 91 // generally startup on some devices, most likely by |
96 // competing for IO. | 92 // competing for IO. |
97 // For experimental results, see http://crbug.com/460438. | 93 // For experimental results, see http://crbug.com/460438. |
98 libraryLoader.asyncPrefetchLibrariesToMemory(); | 94 libraryLoader.asyncPrefetchLibrariesToMemory(); |
99 } catch (ProcessInitException e) { | 95 } catch (ProcessInitException e) { |
100 Log.e(TAG, "Unable to load native library.", e); | 96 Log.e(TAG, "Unable to load native library.", e); |
101 mActivityDelegate.onStartupFailure(); | 97 mActivityDelegate.onStartupFailure(); |
102 return; | 98 return; |
103 } | 99 } |
104 if (allocateChildConnection) ChildProcessLauncher.warmUp(mContex
t); | 100 if (allocateChildConnection) { |
| 101 ChildProcessLauncher.warmUp(ContextUtils.getApplicationConte
xt()); |
| 102 } |
105 ThreadUtils.runOnUiThread(new Runnable() { | 103 ThreadUtils.runOnUiThread(new Runnable() { |
106 @Override | 104 @Override |
107 public void run() { | 105 public void run() { |
108 onLibraryLoaded(); | 106 onLibraryLoaded(); |
109 } | 107 } |
110 }); | 108 }); |
111 } | 109 } |
112 }.start(); | 110 }.start(); |
113 } | 111 } |
114 | 112 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 startNowAndProcessPendingItems(); | 156 startNowAndProcessPendingItems(); |
159 } | 157 } |
160 | 158 |
161 if (mOnResumePending) { | 159 if (mOnResumePending) { |
162 mOnResumePending = false; | 160 mOnResumePending = false; |
163 onResume(); | 161 onResume(); |
164 } | 162 } |
165 | 163 |
166 try { | 164 try { |
167 LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER) | 165 LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER) |
168 .onNativeInitializationComplete(mContext.getApplicationConte
xt()); | 166 .onNativeInitializationComplete(); |
169 } catch (ProcessInitException e) { | 167 } catch (ProcessInitException e) { |
170 Log.e(TAG, "Unable to load native library.", e); | 168 Log.e(TAG, "Unable to load native library.", e); |
171 mActivityDelegate.onStartupFailure(); | 169 mActivityDelegate.onStartupFailure(); |
172 return; | 170 return; |
173 } | 171 } |
174 } | 172 } |
175 | 173 |
176 /** | 174 /** |
177 * Called when an activity gets an onStart call and is done with java only t
asks. | 175 * Called when an activity gets an onStart call and is done with java only t
asks. |
178 */ | 176 */ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 } | 211 } |
214 | 212 |
215 /** | 213 /** |
216 * Called when an activity gets an onNewIntent call and is done with java on
ly tasks. | 214 * Called when an activity gets an onNewIntent call and is done with java on
ly tasks. |
217 * @param intent The intent that has arrived to the activity linked to the g
iven delegate. | 215 * @param intent The intent that has arrived to the activity linked to the g
iven delegate. |
218 */ | 216 */ |
219 public void onNewIntent(Intent intent) { | 217 public void onNewIntent(Intent intent) { |
220 if (mInitializationComplete) { | 218 if (mInitializationComplete) { |
221 mActivityDelegate.onNewIntentWithNative(intent); | 219 mActivityDelegate.onNewIntentWithNative(intent); |
222 } else { | 220 } else { |
223 if (mPendingNewIntents == null) mPendingNewIntents = new ArrayList<I
ntent>(1); | 221 if (mPendingNewIntents == null) mPendingNewIntents = new ArrayList<>
(1); |
224 mPendingNewIntents.add(intent); | 222 mPendingNewIntents.add(intent); |
225 } | 223 } |
226 } | 224 } |
227 | 225 |
228 /** | 226 /** |
229 * This is the Android onActivityResult callback deferred, if necessary, | 227 * This is the Android onActivityResult callback deferred, if necessary, |
230 * to when the native library has loaded. | 228 * to when the native library has loaded. |
231 * @param requestCode The request code for the ActivityResult. | 229 * @param requestCode The request code for the ActivityResult. |
232 * @param resultCode The result code for the ActivityResult. | 230 * @param resultCode The result code for the ActivityResult. |
233 * @param data The intent that has been sent with the ActivityResult. | 231 * @param data The intent that has been sent with the ActivityResult. |
234 */ | 232 */ |
235 public void onActivityResult(int requestCode, int resultCode, Intent data) { | 233 public void onActivityResult(int requestCode, int resultCode, Intent data) { |
236 if (mInitializationComplete) { | 234 if (mInitializationComplete) { |
237 mActivityDelegate.onActivityResultWithNative(requestCode, resultCode
, data); | 235 mActivityDelegate.onActivityResultWithNative(requestCode, resultCode
, data); |
238 } else { | 236 } else { |
239 if (mPendingActivityResults == null) { | 237 if (mPendingActivityResults == null) { |
240 mPendingActivityResults = new ArrayList<ActivityResult>(1); | 238 mPendingActivityResults = new ArrayList<>(1); |
241 } | 239 } |
242 mPendingActivityResults.add(new ActivityResult(requestCode, resultCo
de, data)); | 240 mPendingActivityResults.add(new ActivityResult(requestCode, resultCo
de, data)); |
243 } | 241 } |
244 } | 242 } |
245 | 243 |
246 private void startNowAndProcessPendingItems() { | 244 private void startNowAndProcessPendingItems() { |
247 // onNewIntent and onActivityResult are called only when the activity is
paused. | 245 // onNewIntent and onActivityResult are called only when the activity is
paused. |
248 // To match the non-deferred behavior, onStart should be called before a
ny processing | 246 // To match the non-deferred behavior, onStart should be called before a
ny processing |
249 // of pending intents and activity results. | 247 // of pending intents and activity results. |
250 // Note that if we needed ChromeActivityNativeDelegate.onResumeWithNativ
e(), the pending | 248 // Note that if we needed ChromeActivityNativeDelegate.onResumeWithNativ
e(), the pending |
(...skipping 13 matching lines...) Expand all Loading... |
264 ActivityResult activityResult; | 262 ActivityResult activityResult; |
265 for (int i = 0; i < mPendingActivityResults.size(); i++) { | 263 for (int i = 0; i < mPendingActivityResults.size(); i++) { |
266 activityResult = mPendingActivityResults.get(i); | 264 activityResult = mPendingActivityResults.get(i); |
267 mActivityDelegate.onActivityResultWithNative(activityResult.requ
estCode, | 265 mActivityDelegate.onActivityResultWithNative(activityResult.requ
estCode, |
268 activityResult.resultCode, activityResult.data); | 266 activityResult.resultCode, activityResult.data); |
269 } | 267 } |
270 mPendingActivityResults = null; | 268 mPendingActivityResults = null; |
271 } | 269 } |
272 } | 270 } |
273 } | 271 } |
OLD | NEW |