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.base.library_loader; | 5 package org.chromium.base.library_loader; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.os.AsyncTask; | 8 import android.os.AsyncTask; |
9 import android.os.SystemClock; | 9 import android.os.SystemClock; |
10 | 10 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 private LibraryLoader(int libraryProcessType) { | 125 private LibraryLoader(int libraryProcessType) { |
126 mLibraryProcessType = libraryProcessType; | 126 mLibraryProcessType = libraryProcessType; |
127 mPrefetchLibraryHasBeenCalled = new AtomicBoolean(); | 127 mPrefetchLibraryHasBeenCalled = new AtomicBoolean(); |
128 } | 128 } |
129 | 129 |
130 /** | 130 /** |
131 * This method blocks until the library is fully loaded and initialized. | 131 * This method blocks until the library is fully loaded and initialized. |
132 * | |
133 * @param context The context in which the method is called. | |
134 */ | 132 */ |
135 public void ensureInitialized(Context context) throws ProcessInitException { | 133 public void ensureInitialized() throws ProcessInitException { |
136 // TODO(wnwen): Move this call appropriately down to the tests that need it. | |
137 ContextUtils.initApplicationContext(context.getApplicationContext()); | |
138 synchronized (sLock) { | 134 synchronized (sLock) { |
139 if (mInitialized) { | 135 if (mInitialized) { |
140 // Already initialized, nothing to do. | 136 // Already initialized, nothing to do. |
141 return; | 137 return; |
142 } | 138 } |
143 loadAlreadyLocked(context); | 139 loadAlreadyLocked(ContextUtils.getApplicationContext()); |
144 initializeAlreadyLocked(); | 140 initializeAlreadyLocked(); |
145 } | 141 } |
146 } | 142 } |
147 | 143 |
148 /** | 144 /** |
149 * Checks if library is fully loaded and initialized. | 145 * Checks if library is fully loaded and initialized. |
150 */ | 146 */ |
151 public static boolean isInitialized() { | 147 public static boolean isInitialized() { |
152 return sInstance != null && sInstance.mInitialized; | 148 return sInstance != null && sInstance.mInitialized; |
153 } | 149 } |
154 | 150 |
155 /** | 151 /** |
156 * Loads the library and blocks until the load completes. The caller is resp onsible | 152 * Loads the library and blocks until the load completes. The caller is resp onsible |
157 * for subsequently calling ensureInitialized(). | 153 * for subsequently calling ensureInitialized(). |
158 * May be called on any thread, but should only be called once. Note the thr ead | 154 * May be called on any thread, but should only be called once. Note the thr ead |
159 * this is called on will be the thread that runs the native code's static i nitializers. | 155 * this is called on will be the thread that runs the native code's static i nitializers. |
160 * See the comment in doInBackground() for more considerations on this. | 156 * See the comment in doInBackground() for more considerations on this. |
161 * | 157 * |
162 * @param context The context the code is running. | |
163 * | |
164 * @throws ProcessInitException if the native library failed to load. | 158 * @throws ProcessInitException if the native library failed to load. |
165 */ | 159 */ |
166 public void loadNow(Context context) throws ProcessInitException { | 160 public void loadNow() throws ProcessInitException { |
161 loadNowOverrideApplicationContext(ContextUtils.getApplicationContext()); | |
162 } | |
163 | |
164 /** | |
165 * Override kept for callers that need to load from a different app context. Do not use unless | |
166 * specifically required to load from another context that is not the curren t process's app | |
167 * context. | |
168 * | |
169 * @param appContext The overriding app context to be used to load libraries . | |
170 * @throws ProcessInitException if the native library failed to load with th is context. | |
171 */ | |
172 public void loadNowOverrideApplicationContext(Context appContext) throws Pro cessInitException { | |
173 if (mLoaded && appContext != ContextUtils.getApplicationContext()) { | |
Ted C
2016/09/28 17:27:46
should this be in the synchronized block since tha
Peter Wen
2016/09/29 18:41:38
Done. Thanks!
| |
174 throw new IllegalStateException("Duplicate attempt to load from alte rnate context."); | |
175 } | |
167 synchronized (sLock) { | 176 synchronized (sLock) { |
168 loadAlreadyLocked(context); | 177 loadAlreadyLocked(appContext); |
169 } | 178 } |
170 } | 179 } |
171 | 180 |
172 /** | 181 /** |
173 * initializes the library here and now: must be called on the thread that t he | 182 * initializes the library here and now: must be called on the thread that t he |
174 * native will call its "main" thread. The library must have previously been | 183 * native will call its "main" thread. The library must have previously been |
175 * loaded with loadNow. | 184 * loaded with loadNow. |
176 */ | 185 */ |
177 public void initialize() throws ProcessInitException { | 186 public void initialize() throws ProcessInitException { |
178 synchronized (sLock) { | 187 synchronized (sLock) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 } | 252 } |
244 | 253 |
245 // Loaded successfully, so record if we loaded directly from an APK. | 254 // Loaded successfully, so record if we loaded directly from an APK. |
246 if (zipFilePath != null) { | 255 if (zipFilePath != null) { |
247 mLibraryWasLoadedFromApk = true; | 256 mLibraryWasLoadedFromApk = true; |
248 } | 257 } |
249 } | 258 } |
250 | 259 |
251 // Invoke either Linker.loadLibrary(...) or System.loadLibrary(...), trigger ing | 260 // Invoke either Linker.loadLibrary(...) or System.loadLibrary(...), trigger ing |
252 // JNI_OnLoad in native code | 261 // JNI_OnLoad in native code |
253 private void loadAlreadyLocked(Context context) throws ProcessInitException { | 262 private void loadAlreadyLocked(Context appContext) throws ProcessInitExcepti on { |
254 try { | 263 try { |
255 if (!mLoaded) { | 264 if (!mLoaded) { |
256 assert !mInitialized; | 265 assert !mInitialized; |
257 | 266 |
258 long startTime = SystemClock.uptimeMillis(); | 267 long startTime = SystemClock.uptimeMillis(); |
259 | 268 |
260 if (Linker.isUsed()) { | 269 if (Linker.isUsed()) { |
261 // Load libraries using the Chromium linker. | 270 // Load libraries using the Chromium linker. |
262 Linker linker = Linker.getInstance(); | 271 Linker linker = Linker.getInstance(); |
263 linker.prepareLibraryLoad(); | 272 linker.prepareLibraryLoad(); |
264 | 273 |
265 for (String library : NativeLibraries.LIBRARIES) { | 274 for (String library : NativeLibraries.LIBRARIES) { |
266 // Don't self-load the linker. This is because the build system is | 275 // Don't self-load the linker. This is because the build system is |
267 // not clever enough to understand that all the librarie s packaged | 276 // not clever enough to understand that all the librarie s packaged |
268 // in the final .apk don't need to be explicitly loaded. | 277 // in the final .apk don't need to be explicitly loaded. |
269 if (linker.isChromiumLinkerLibrary(library)) { | 278 if (linker.isChromiumLinkerLibrary(library)) { |
270 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); | 279 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); |
271 continue; | 280 continue; |
272 } | 281 } |
273 | 282 |
274 // Determine where the library should be loaded from. | 283 // Determine where the library should be loaded from. |
275 String zipFilePath = null; | 284 String zipFilePath = null; |
276 String libFilePath = System.mapLibraryName(library); | 285 String libFilePath = System.mapLibraryName(library); |
277 if (Linker.isInZipFile()) { | 286 if (Linker.isInZipFile()) { |
278 // Load directly from the APK. | 287 // Load directly from the APK. |
279 zipFilePath = context.getApplicationInfo().sourceDir ; | 288 zipFilePath = appContext.getApplicationInfo().source Dir; |
280 Log.i(TAG, "Loading " + library + " from within " + zipFilePath); | 289 Log.i(TAG, "Loading " + library + " from within " + zipFilePath); |
281 } else { | 290 } else { |
282 // The library is in its own file. | 291 // The library is in its own file. |
283 Log.i(TAG, "Loading " + library); | 292 Log.i(TAG, "Loading " + library); |
284 } | 293 } |
285 | 294 |
286 // Load the library using this Linker. May throw Unsatis fiedLinkError. | 295 // Load the library using this Linker. May throw Unsatis fiedLinkError. |
287 loadLibrary(linker, zipFilePath, libFilePath); | 296 loadLibrary(linker, zipFilePath, libFilePath); |
288 } | 297 } |
289 | 298 |
290 linker.finishLibraryLoad(); | 299 linker.finishLibraryLoad(); |
291 } else { | 300 } else { |
292 if (sLibraryPreloader != null) { | 301 if (sLibraryPreloader != null) { |
293 mLibraryPreloaderStatus = sLibraryPreloader.loadLibrary( context); | 302 mLibraryPreloaderStatus = sLibraryPreloader.loadLibrary( appContext); |
294 } | 303 } |
295 // Load libraries using the system linker. | 304 // Load libraries using the system linker. |
296 for (String library : NativeLibraries.LIBRARIES) { | 305 for (String library : NativeLibraries.LIBRARIES) { |
297 System.loadLibrary(library); | 306 System.loadLibrary(library); |
298 } | 307 } |
299 } | 308 } |
300 | 309 |
301 long stopTime = SystemClock.uptimeMillis(); | 310 long stopTime = SystemClock.uptimeMillis(); |
302 mLibraryLoadTimeMs = stopTime - startTime; | 311 mLibraryLoadTimeMs = stopTime - startTime; |
303 Log.i(TAG, String.format("Time to load native libraries: %d ms ( timestamps %d-%d)", | 312 Log.i(TAG, String.format("Time to load native libraries: %d ms ( timestamps %d-%d)", |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 | 380 |
372 // From this point on, native code is ready to use and checkIsReady() | 381 // From this point on, native code is ready to use and checkIsReady() |
373 // shouldn't complain from now on (and in fact, it's used by the | 382 // shouldn't complain from now on (and in fact, it's used by the |
374 // following calls). | 383 // following calls). |
375 // Note that this flag can be accessed asynchronously, so any initializa tion | 384 // Note that this flag can be accessed asynchronously, so any initializa tion |
376 // must be performed before. | 385 // must be performed before. |
377 mInitialized = true; | 386 mInitialized = true; |
378 } | 387 } |
379 | 388 |
380 // Called after all native initializations are complete. | 389 // Called after all native initializations are complete. |
381 public void onNativeInitializationComplete(Context context) { | 390 public void onNativeInitializationComplete() { |
382 recordBrowserProcessHistogram(context); | 391 recordBrowserProcessHistogram(); |
383 } | 392 } |
384 | 393 |
385 // Record Chromium linker histogram state for the main browser process. Call ed from | 394 // Record Chromium linker histogram state for the main browser process. Call ed from |
386 // onNativeInitializationComplete(). | 395 // onNativeInitializationComplete(). |
387 private void recordBrowserProcessHistogram(Context context) { | 396 private void recordBrowserProcessHistogram() { |
388 if (Linker.getInstance().isUsed()) { | 397 if (Linker.getInstance().isUsed()) { |
389 nativeRecordChromiumAndroidLinkerBrowserHistogram(mIsUsingBrowserSha redRelros, | 398 nativeRecordChromiumAndroidLinkerBrowserHistogram( |
390 mLoadAtFixedAddres sFailed, | 399 mIsUsingBrowserSharedRelros, |
391 getLibraryLoadFrom ApkStatus(context), | 400 mLoadAtFixedAddressFailed, |
392 mLibraryLoadTimeMs ); | 401 getLibraryLoadFromApkStatus(), |
402 mLibraryLoadTimeMs); | |
393 } | 403 } |
394 if (sLibraryPreloader != null) { | 404 if (sLibraryPreloader != null) { |
395 nativeRecordLibraryPreloaderBrowserHistogram(mLibraryPreloaderStatus ); | 405 nativeRecordLibraryPreloaderBrowserHistogram(mLibraryPreloaderStatus ); |
396 } | 406 } |
397 } | 407 } |
398 | 408 |
399 // Returns the device's status for loading a library directly from the APK f ile. | 409 // Returns the device's status for loading a library directly from the APK f ile. |
400 // This method can only be called when the Chromium linker is used. | 410 // This method can only be called when the Chromium linker is used. |
401 private int getLibraryLoadFromApkStatus(Context context) { | 411 private int getLibraryLoadFromApkStatus() { |
402 assert Linker.getInstance().isUsed(); | 412 assert Linker.getInstance().isUsed(); |
403 | 413 |
404 if (mLibraryWasLoadedFromApk) { | 414 if (mLibraryWasLoadedFromApk) { |
405 return LibraryLoadFromApkStatusCodes.SUCCESSFUL; | 415 return LibraryLoadFromApkStatusCodes.SUCCESSFUL; |
406 } | 416 } |
407 | 417 |
408 // There were no libraries to be loaded directly from the APK file. | 418 // There were no libraries to be loaded directly from the APK file. |
409 return LibraryLoadFromApkStatusCodes.UNKNOWN; | 419 return LibraryLoadFromApkStatusCodes.UNKNOWN; |
410 } | 420 } |
411 | 421 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 | 489 |
480 // Finds the ranges corresponding to the native library pages, forks a new | 490 // Finds the ranges corresponding to the native library pages, forks a new |
481 // process to prefetch these pages and waits for it. The new process then | 491 // process to prefetch these pages and waits for it. The new process then |
482 // terminates. This is blocking. | 492 // terminates. This is blocking. |
483 private static native boolean nativeForkAndPrefetchNativeLibrary(); | 493 private static native boolean nativeForkAndPrefetchNativeLibrary(); |
484 | 494 |
485 // Returns the percentage of the native library code page that are currently reseident in | 495 // Returns the percentage of the native library code page that are currently reseident in |
486 // memory. | 496 // memory. |
487 private static native int nativePercentageOfResidentNativeLibraryCode(); | 497 private static native int nativePercentageOfResidentNativeLibraryCode(); |
488 } | 498 } |
OLD | NEW |