Chromium Code Reviews| 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 // The name of the APK file. |
| 54 // APK files with executable permissions. Only used in the browser. | 54 private static String sApkFileName = null; |
| 55 private static boolean sLibraryLoadFromApkSupported = false; | 55 |
| 56 // One-way switch becomes true when the library is successfully loaded from | |
|
rmcilroy
2014/10/20 10:42:39
nit - One-way switch becomes true if the library w
petrcermak
2014/10/20 15:33:22
Done.
| |
| 57 // the APK file. | |
| 58 private static boolean sLibraryLoadedFromApk = false; | |
|
rmcilroy
2014/10/20 10:42:39
nit - sLibraryWasLoadedFromApk
petrcermak
2014/10/20 15:33:22
Done.
| |
| 56 | 59 |
| 57 // One-way switch becomes true if the system library loading failed, | 60 // One-way switch becomes true if the system library loading failed, |
| 58 // and the right native library was found and loaded by the hack. | 61 // and the right native library was found and loaded by the hack. |
| 59 // The flag is used to report UMA stats later. | 62 // The flag is used to report UMA stats later. |
| 60 private static boolean sNativeLibraryHackWasUsed = false; | 63 private static boolean sNativeLibraryHackWasUsed = false; |
| 61 | 64 |
| 62 /** | 65 /** |
| 63 * The same as ensureInitialized(null, false), should only be called | 66 * The same as ensureInitialized(null, false), should only be called |
| 64 * by non-browser processes. | 67 * by non-browser processes. |
| 65 * | 68 * |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 private static void loadAlreadyLocked( | 156 private static void loadAlreadyLocked( |
| 154 Context context, boolean shouldDeleteOldWorkaroundLibraries) | 157 Context context, boolean shouldDeleteOldWorkaroundLibraries) |
| 155 throws ProcessInitException { | 158 throws ProcessInitException { |
| 156 try { | 159 try { |
| 157 if (!sLoaded) { | 160 if (!sLoaded) { |
| 158 assert !sInitialized; | 161 assert !sInitialized; |
| 159 | 162 |
| 160 long startTime = SystemClock.uptimeMillis(); | 163 long startTime = SystemClock.uptimeMillis(); |
| 161 boolean useChromiumLinker = Linker.isUsed(); | 164 boolean useChromiumLinker = Linker.isUsed(); |
| 162 | 165 |
| 166 if (context != null) { | |
| 167 sApkFileName = context.getApplicationInfo().sourceDir; | |
| 168 } | |
| 169 | |
| 163 if (useChromiumLinker) { | 170 if (useChromiumLinker) { |
| 164 // Load libraries using the Chromium linker. | 171 // Load libraries using the Chromium linker. |
| 165 Linker.prepareLibraryLoad(); | 172 Linker.prepareLibraryLoad(); |
| 166 | 173 |
| 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) { | 174 for (String library : NativeLibraries.LIBRARIES) { |
| 175 String zipfile = null; | 175 String zipfile = null; |
| 176 if (Linker.isInZipFile()) { | 176 if (Linker.isInZipFile()) { |
| 177 zipfile = apkfile; | 177 zipfile = sApkFileName; |
| 178 Log.i(TAG, "Loading " + library + " from within " + zipfile); | 178 Log.i(TAG, "Loading " + library + " from within " + zipfile); |
| 179 } else { | 179 } else { |
| 180 Log.i(TAG, "Loading: " + library); | 180 Log.i(TAG, "Loading: " + library); |
| 181 } | 181 } |
| 182 | 182 |
| 183 boolean isLoaded = false; | 183 boolean isLoaded = false; |
| 184 if (Linker.isUsingBrowserSharedRelros()) { | 184 if (Linker.isUsingBrowserSharedRelros()) { |
| 185 sIsUsingBrowserSharedRelros = true; | 185 sIsUsingBrowserSharedRelros = true; |
| 186 try { | 186 try { |
| 187 if (zipfile != null) { | 187 if (zipfile != null) { |
| 188 Linker.loadLibraryInZipFile(zipfile, library ); | 188 Linker.loadLibraryInZipFile(zipfile, library ); |
| 189 sLibraryLoadedFromApk = true; | |
| 189 } else { | 190 } else { |
| 190 Linker.loadLibrary(library); | 191 Linker.loadLibrary(library); |
| 191 } | 192 } |
| 192 isLoaded = true; | 193 isLoaded = true; |
| 193 } catch (UnsatisfiedLinkError e) { | 194 } catch (UnsatisfiedLinkError e) { |
| 194 Log.w(TAG, "Failed to load native library with s hared RELRO, " + | 195 Log.w(TAG, "Failed to load native library with s hared RELRO, " + |
| 195 "retrying without"); | 196 "retrying without"); |
| 196 Linker.disableSharedRelros(); | 197 Linker.disableSharedRelros(); |
| 197 sLoadAtFixedAddressFailed = true; | 198 sLoadAtFixedAddressFailed = true; |
| 198 } | 199 } |
| 199 } | 200 } |
| 200 if (!isLoaded) { | 201 if (!isLoaded) { |
| 201 if (zipfile != null) { | 202 if (zipfile != null) { |
| 202 Linker.loadLibraryInZipFile(zipfile, library); | 203 Linker.loadLibraryInZipFile(zipfile, library); |
| 204 sLibraryLoadedFromApk = true; | |
| 203 } else { | 205 } else { |
| 204 Linker.loadLibrary(library); | 206 Linker.loadLibrary(library); |
| 205 } | 207 } |
| 206 } | 208 } |
| 207 } | 209 } |
| 208 | 210 |
| 209 Linker.finishLibraryLoad(); | 211 Linker.finishLibraryLoad(); |
| 210 } else { | 212 } else { |
| 211 // Load libraries using the system linker. | 213 // Load libraries using the system linker. |
| 212 for (String library : NativeLibraries.LIBRARIES) { | 214 for (String library : NativeLibraries.LIBRARIES) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 } | 309 } |
| 308 | 310 |
| 309 // Called after all native initializations are complete. | 311 // Called after all native initializations are complete. |
| 310 public static void onNativeInitializationComplete() { | 312 public static void onNativeInitializationComplete() { |
| 311 recordBrowserProcessHistogram(); | 313 recordBrowserProcessHistogram(); |
| 312 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); | 314 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); |
| 313 } | 315 } |
| 314 | 316 |
| 315 // Record Chromium linker histogram state for the main browser process. Call ed from | 317 // Record Chromium linker histogram state for the main browser process. Call ed from |
| 316 // onNativeInitializationComplete(). | 318 // onNativeInitializationComplete(). |
| 317 private static void recordBrowserProcessHistogram() { | 319 private static void recordBrowserProcessHistogram() { |
|
rmcilroy
2014/10/20 10:42:39
It looks like this is only called from onNativeIni
petrcermak
2014/10/20 15:33:22
Done.
| |
| 318 if (Linker.isUsed()) { | 320 if (Linker.isUsed()) { |
| 319 assert Linker.isInBrowserProcess(); | 321 int libraryLoadFromApkSupport; |
|
rmcilroy
2014/10/20 10:42:39
nit - libraryLoadFromApkStatus
petrcermak
2014/10/20 15:33:22
The variable is not needed now that the code is in
| |
| 322 if (sLibraryLoadedFromApk) { | |
| 323 libraryLoadFromApkSupport = LibraryLoadFromApkSupportCode.SUCCES SFUL; | |
| 324 } else if (sApkFileName != null) { | |
| 325 libraryLoadFromApkSupport = Linker.checkLibraryLoadFromApkSuppor t(sApkFileName) ? | |
| 326 LibraryLoadFromApkSupportCode.SUPPORTED : | |
| 327 LibraryLoadFromApkSupportCode.NOT_SUPPORTED; | |
| 328 } else { | |
| 329 libraryLoadFromApkSupport = LibraryLoadFromApkSupportCode.UNKNOW N; | |
| 330 Log.w(TAG, "Unknown APK filename due to null context"); | |
| 331 } | |
|
rmcilroy
2014/10/20 10:42:39
Please pull this out into a separate function whic
petrcermak
2014/10/20 15:33:22
Done.
| |
| 320 nativeRecordChromiumAndroidLinkerBrowserHistogram(sIsUsingBrowserSha redRelros, | 332 nativeRecordChromiumAndroidLinkerBrowserHistogram(sIsUsingBrowserSha redRelros, |
| 321 sLoadAtFixedAddres sFailed, | 333 sLoadAtFixedAddres sFailed, |
| 322 sLibraryLoadFromAp kSupported); | 334 libraryLoadFromApk Support); |
| 323 } | 335 } |
| 324 } | 336 } |
| 325 | 337 |
| 326 // Register pending Chromium linker histogram state for renderer processes. This cannot be | 338 // Register pending Chromium linker histogram state for renderer processes. This cannot be |
| 327 // recorded as a histogram immediately because histograms and IPC are not re ady at the | 339 // recorded as a histogram immediately because histograms and IPC are not re ady at the |
| 328 // time it are captured. This function stores a pending value, so that a lat er call to | 340 // time it are captured. This function stores a pending value, so that a lat er call to |
| 329 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. | 341 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. |
| 330 public static void registerRendererProcessHistogram(boolean requestedSharedR elro, | 342 public static void registerRendererProcessHistogram(boolean requestedSharedR elro, |
| 331 boolean loadAtFixedAddre ssFailed) { | 343 boolean loadAtFixedAddre ssFailed) { |
| 332 if (Linker.isUsed()) { | 344 if (Linker.isUsed()) { |
| 333 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared Relro, | 345 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared Relro, |
| 334 loadAtFixedAddr essFailed); | 346 loadAtFixedAddr essFailed); |
| 335 } | 347 } |
| 336 } | 348 } |
| 337 | 349 |
| 338 private static native void nativeInitCommandLine(String[] initCommandLine); | 350 private static native void nativeInitCommandLine(String[] initCommandLine); |
| 339 | 351 |
| 340 // Only methods needed before or during normal JNI registration are during S ystem.OnLoad. | 352 // Only methods needed before or during normal JNI registration are during S ystem.OnLoad. |
| 341 // nativeLibraryLoaded is then called to register everything else. This pro cess is called | 353 // nativeLibraryLoaded is then called to register everything else. This pro cess is called |
| 342 // "initialization". This method will be mapped (by generated code) to the LibraryLoaded | 354 // "initialization". This method will be mapped (by generated code) to the LibraryLoaded |
| 343 // definition in base/android/library_loader/library_loader_hooks.cc. | 355 // definition in base/android/library_loader/library_loader_hooks.cc. |
| 344 // | 356 // |
| 345 // Return true on success and false on failure. | 357 // Return true on success and false on failure. |
| 346 private static native boolean nativeLibraryLoaded(); | 358 private static native boolean nativeLibraryLoaded(); |
| 347 | 359 |
| 348 // Method called to record statistics about the Chromium linker operation fo r the main | 360 // Method called to record statistics about the Chromium linker operation fo r the main |
| 349 // browser process. Indicates whether the linker attempted relro sharing for the browser, | 361 // browser process. Indicates whether the linker attempted relro sharing for the browser, |
| 350 // and if it did, whether the library failed to load at a fixed address. Als o records | 362 // and if it did, whether the library failed to load at a fixed address. Als o records |
| 351 // support for memory mapping APK files with executable permissions. | 363 // support for loading a library directly from the APK file. |
| 352 private static native void nativeRecordChromiumAndroidLinkerBrowserHistogram ( | 364 private static native void nativeRecordChromiumAndroidLinkerBrowserHistogram ( |
| 353 boolean isUsingBrowserSharedRelros, | 365 boolean isUsingBrowserSharedRelros, |
| 354 boolean loadAtFixedAddressFailed, | 366 boolean loadAtFixedAddressFailed, |
| 355 boolean apkMemoryMappingSupported); | 367 int libraryLoadFromApkSupport); |
| 356 | 368 |
| 357 // Method called to register (for later recording) statistics about the Chro mium linker | 369 // Method called to register (for later recording) statistics about the Chro mium linker |
| 358 // operation for a renderer process. Indicates whether the linker attempted relro sharing, | 370 // operation for a renderer process. Indicates whether the linker attempted relro sharing, |
| 359 // and if it did, whether the library failed to load at a fixed address. | 371 // and if it did, whether the library failed to load at a fixed address. |
| 360 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog ram( | 372 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog ram( |
| 361 boolean requestedSharedRelro, | 373 boolean requestedSharedRelro, |
| 362 boolean loadAtFixedAddressFailed); | 374 boolean loadAtFixedAddressFailed); |
| 363 | 375 |
| 364 // Get the version of the native library. This is needed so that we can chec k we | 376 // Get the version of the native library. This is needed so that we can chec k we |
| 365 // have the right version before initializing the (rest of the) JNI. | 377 // have the right version before initializing the (rest of the) JNI. |
| 366 private static native String nativeGetVersionNumber(); | 378 private static native String nativeGetVersionNumber(); |
| 367 | 379 |
| 368 private static native void nativeRecordNativeLibraryHack(boolean usedHack); | 380 private static native void nativeRecordNativeLibraryHack(boolean usedHack); |
| 369 } | 381 } |
| OLD | NEW |