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.SystemClock; | 8 import android.os.SystemClock; |
9 import android.util.Log; | 9 import android.util.Log; |
10 | 10 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // One-way switch becomes true when the libraries are initialized ( | 43 // One-way switch becomes true when the libraries are initialized ( |
44 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in | 44 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in |
45 // library_loader_hooks.cc). | 45 // library_loader_hooks.cc). |
46 private static boolean sInitialized = false; | 46 private static boolean sInitialized = false; |
47 | 47 |
48 // One-way switches recording attempts to use Relro sharing in the browser. | 48 // One-way switches recording attempts to use Relro sharing in the browser. |
49 // The flags are used to report UMA stats later. | 49 // The flags are used to report UMA stats later. |
50 private static boolean sIsUsingBrowserSharedRelros = false; | 50 private static boolean sIsUsingBrowserSharedRelros = false; |
51 private static boolean sLoadAtFixedAddressFailed = false; | 51 private static boolean sLoadAtFixedAddressFailed = false; |
52 | 52 |
53 // One-way switch recording whether the device supports memory mapping | 53 // One-way switch becomes true if the library was loaded from the APK file |
54 // APK files with executable permissions. Only used in the browser. | 54 // directly. |
55 private static boolean sLibraryLoadFromApkSupported = false; | 55 private static boolean sLibraryWasLoadedFromApk = false; |
56 | 56 |
57 // One-way switch becomes true if the system library loading failed, | 57 // One-way switch becomes true if the system library loading failed, |
58 // and the right native library was found and loaded by the hack. | 58 // and the right native library was found and loaded by the hack. |
59 // The flag is used to report UMA stats later. | 59 // The flag is used to report UMA stats later. |
60 private static boolean sNativeLibraryHackWasUsed = false; | 60 private static boolean sNativeLibraryHackWasUsed = false; |
61 | 61 |
62 /** | 62 /** |
63 * The same as ensureInitialized(null, false), should only be called | 63 * The same as ensureInitialized(null, false), should only be called |
64 * by non-browser processes. | 64 * by non-browser processes. |
65 * | 65 * |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 if (!sLoaded) { | 157 if (!sLoaded) { |
158 assert !sInitialized; | 158 assert !sInitialized; |
159 | 159 |
160 long startTime = SystemClock.uptimeMillis(); | 160 long startTime = SystemClock.uptimeMillis(); |
161 boolean useChromiumLinker = Linker.isUsed(); | 161 boolean useChromiumLinker = Linker.isUsed(); |
162 | 162 |
163 if (useChromiumLinker) { | 163 if (useChromiumLinker) { |
164 // Load libraries using the Chromium linker. | 164 // Load libraries using the Chromium linker. |
165 Linker.prepareLibraryLoad(); | 165 Linker.prepareLibraryLoad(); |
166 | 166 |
167 // Check if the device supports loading a library directly f
rom the APK file. | |
168 String apkfile = context.getApplicationInfo().sourceDir; | |
169 if (Linker.isInBrowserProcess()) { | |
170 sLibraryLoadFromApkSupported = Linker.checkLibraryLoadFr
omApkSupport( | |
171 apkfile); | |
172 } | |
173 | |
174 for (String library : NativeLibraries.LIBRARIES) { | 167 for (String library : NativeLibraries.LIBRARIES) { |
175 String zipfile = null; | 168 String zipfile = null; |
176 if (Linker.isInZipFile()) { | 169 if (Linker.isInZipFile()) { |
177 zipfile = apkfile; | 170 zipfile = context.getApplicationInfo().sourceDir; |
178 Log.i(TAG, "Loading " + library + " from within " +
zipfile); | 171 Log.i(TAG, "Loading " + library + " from within " +
zipfile); |
179 } else { | 172 } else { |
180 Log.i(TAG, "Loading: " + library); | 173 Log.i(TAG, "Loading: " + library); |
181 } | 174 } |
182 | 175 |
183 boolean isLoaded = false; | 176 boolean isLoaded = false; |
184 if (Linker.isUsingBrowserSharedRelros()) { | 177 if (Linker.isUsingBrowserSharedRelros()) { |
185 sIsUsingBrowserSharedRelros = true; | 178 sIsUsingBrowserSharedRelros = true; |
186 try { | 179 try { |
187 if (zipfile != null) { | 180 if (zipfile != null) { |
188 Linker.loadLibraryInZipFile(zipfile, library
); | 181 Linker.loadLibraryInZipFile(zipfile, library
); |
| 182 sLibraryWasLoadedFromApk = true; |
189 } else { | 183 } else { |
190 Linker.loadLibrary(library); | 184 Linker.loadLibrary(library); |
191 } | 185 } |
192 isLoaded = true; | 186 isLoaded = true; |
193 } catch (UnsatisfiedLinkError e) { | 187 } catch (UnsatisfiedLinkError e) { |
194 Log.w(TAG, "Failed to load native library with s
hared RELRO, " + | 188 Log.w(TAG, "Failed to load native library with s
hared RELRO, " + |
195 "retrying without"); | 189 "retrying without"); |
196 Linker.disableSharedRelros(); | 190 Linker.disableSharedRelros(); |
197 sLoadAtFixedAddressFailed = true; | 191 sLoadAtFixedAddressFailed = true; |
198 } | 192 } |
199 } | 193 } |
200 if (!isLoaded) { | 194 if (!isLoaded) { |
201 if (zipfile != null) { | 195 if (zipfile != null) { |
202 Linker.loadLibraryInZipFile(zipfile, library); | 196 Linker.loadLibraryInZipFile(zipfile, library); |
| 197 sLibraryWasLoadedFromApk = true; |
203 } else { | 198 } else { |
204 Linker.loadLibrary(library); | 199 Linker.loadLibrary(library); |
205 } | 200 } |
206 } | 201 } |
207 } | 202 } |
208 | 203 |
209 Linker.finishLibraryLoad(); | 204 Linker.finishLibraryLoad(); |
210 } else { | 205 } else { |
211 // Load libraries using the system linker. | 206 // Load libraries using the system linker. |
212 for (String library : NativeLibraries.LIBRARIES) { | 207 for (String library : NativeLibraries.LIBRARIES) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 CommandLine.enableNativeProxy(); | 296 CommandLine.enableNativeProxy(); |
302 sCommandLineSwitched = true; | 297 sCommandLineSwitched = true; |
303 } | 298 } |
304 | 299 |
305 // From now on, keep tracing in sync with native. | 300 // From now on, keep tracing in sync with native. |
306 TraceEvent.registerNativeEnabledObserver(); | 301 TraceEvent.registerNativeEnabledObserver(); |
307 } | 302 } |
308 | 303 |
309 // Called after all native initializations are complete. | 304 // Called after all native initializations are complete. |
310 public static void onNativeInitializationComplete(Context context) { | 305 public static void onNativeInitializationComplete(Context context) { |
311 onNativeInitializationComplete(); | 306 recordBrowserProcessHistogram(context); |
312 } | |
313 | |
314 // Called after all native initializations are complete. | |
315 @Deprecated | |
316 public static void onNativeInitializationComplete() { | |
317 recordBrowserProcessHistogram(); | |
318 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); | 307 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); |
319 } | 308 } |
320 | 309 |
321 // Record Chromium linker histogram state for the main browser process. Call
ed from | 310 // Record Chromium linker histogram state for the main browser process. Call
ed from |
322 // onNativeInitializationComplete(). | 311 // onNativeInitializationComplete(). |
323 private static void recordBrowserProcessHistogram() { | 312 private static void recordBrowserProcessHistogram(Context context) { |
324 if (Linker.isUsed()) { | 313 if (Linker.isUsed()) { |
325 assert Linker.isInBrowserProcess(); | |
326 nativeRecordChromiumAndroidLinkerBrowserHistogram(sIsUsingBrowserSha
redRelros, | 314 nativeRecordChromiumAndroidLinkerBrowserHistogram(sIsUsingBrowserSha
redRelros, |
327 sLoadAtFixedAddres
sFailed, | 315 sLoadAtFixedAddres
sFailed, |
328 sLibraryLoadFromAp
kSupported); | 316 getLibraryLoadFrom
ApkStatus(context)); |
329 } | 317 } |
330 } | 318 } |
331 | 319 |
| 320 // Returns the device's status for loading a library directly from the APK f
ile. |
| 321 // This method can only be called when the Chromium linker is used. |
| 322 private static int getLibraryLoadFromApkStatus(Context context) { |
| 323 assert Linker.isUsed(); |
| 324 |
| 325 if (sLibraryWasLoadedFromApk) { |
| 326 return LibraryLoadFromApkStatusCodes.SUCCESSFUL; |
| 327 } |
| 328 |
| 329 if (context == null) { |
| 330 Log.w(TAG, "Unknown APK filename due to null context"); |
| 331 return LibraryLoadFromApkStatusCodes.UNKNOWN; |
| 332 } |
| 333 |
| 334 return Linker.checkLibraryLoadFromApkSupport(context.getApplicationInfo(
).sourceDir) ? |
| 335 LibraryLoadFromApkStatusCodes.SUPPORTED : |
| 336 LibraryLoadFromApkStatusCodes.NOT_SUPPORTED; |
| 337 } |
| 338 |
332 // Register pending Chromium linker histogram state for renderer processes.
This cannot be | 339 // Register pending Chromium linker histogram state for renderer processes.
This cannot be |
333 // recorded as a histogram immediately because histograms and IPC are not re
ady at the | 340 // recorded as a histogram immediately because histograms and IPC are not re
ady at the |
334 // time it are captured. This function stores a pending value, so that a lat
er call to | 341 // time it are captured. This function stores a pending value, so that a lat
er call to |
335 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. | 342 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. |
336 public static void registerRendererProcessHistogram(boolean requestedSharedR
elro, | 343 public static void registerRendererProcessHistogram(boolean requestedSharedR
elro, |
337 boolean loadAtFixedAddre
ssFailed) { | 344 boolean loadAtFixedAddre
ssFailed) { |
338 if (Linker.isUsed()) { | 345 if (Linker.isUsed()) { |
339 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared
Relro, | 346 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared
Relro, |
340 loadAtFixedAddr
essFailed); | 347 loadAtFixedAddr
essFailed); |
341 } | 348 } |
342 } | 349 } |
343 | 350 |
344 private static native void nativeInitCommandLine(String[] initCommandLine); | 351 private static native void nativeInitCommandLine(String[] initCommandLine); |
345 | 352 |
346 // Only methods needed before or during normal JNI registration are during S
ystem.OnLoad. | 353 // Only methods needed before or during normal JNI registration are during S
ystem.OnLoad. |
347 // nativeLibraryLoaded is then called to register everything else. This pro
cess is called | 354 // nativeLibraryLoaded is then called to register everything else. This pro
cess is called |
348 // "initialization". This method will be mapped (by generated code) to the
LibraryLoaded | 355 // "initialization". This method will be mapped (by generated code) to the
LibraryLoaded |
349 // definition in base/android/library_loader/library_loader_hooks.cc. | 356 // definition in base/android/library_loader/library_loader_hooks.cc. |
350 // | 357 // |
351 // Return true on success and false on failure. | 358 // Return true on success and false on failure. |
352 private static native boolean nativeLibraryLoaded(); | 359 private static native boolean nativeLibraryLoaded(); |
353 | 360 |
354 // Method called to record statistics about the Chromium linker operation fo
r the main | 361 // Method called to record statistics about the Chromium linker operation fo
r the main |
355 // browser process. Indicates whether the linker attempted relro sharing for
the browser, | 362 // browser process. Indicates whether the linker attempted relro sharing for
the browser, |
356 // and if it did, whether the library failed to load at a fixed address. Als
o records | 363 // and if it did, whether the library failed to load at a fixed address. Als
o records |
357 // support for memory mapping APK files with executable permissions. | 364 // support for loading a library directly from the APK file. |
358 private static native void nativeRecordChromiumAndroidLinkerBrowserHistogram
( | 365 private static native void nativeRecordChromiumAndroidLinkerBrowserHistogram
( |
359 boolean isUsingBrowserSharedRelros, | 366 boolean isUsingBrowserSharedRelros, |
360 boolean loadAtFixedAddressFailed, | 367 boolean loadAtFixedAddressFailed, |
361 boolean apkMemoryMappingSupported); | 368 int libraryLoadFromApkStatus); |
362 | 369 |
363 // Method called to register (for later recording) statistics about the Chro
mium linker | 370 // Method called to register (for later recording) statistics about the Chro
mium linker |
364 // operation for a renderer process. Indicates whether the linker attempted
relro sharing, | 371 // operation for a renderer process. Indicates whether the linker attempted
relro sharing, |
365 // and if it did, whether the library failed to load at a fixed address. | 372 // and if it did, whether the library failed to load at a fixed address. |
366 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog
ram( | 373 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog
ram( |
367 boolean requestedSharedRelro, | 374 boolean requestedSharedRelro, |
368 boolean loadAtFixedAddressFailed); | 375 boolean loadAtFixedAddressFailed); |
369 | 376 |
370 // Get the version of the native library. This is needed so that we can chec
k we | 377 // Get the version of the native library. This is needed so that we can chec
k we |
371 // have the right version before initializing the (rest of the) JNI. | 378 // have the right version before initializing the (rest of the) JNI. |
372 private static native String nativeGetVersionNumber(); | 379 private static native String nativeGetVersionNumber(); |
373 | 380 |
374 private static native void nativeRecordNativeLibraryHack(boolean usedHack); | 381 private static native void nativeRecordNativeLibraryHack(boolean usedHack); |
375 } | 382 } |
OLD | NEW |