| 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.os.SystemClock; | 8 import android.os.SystemClock; |
| 8 import android.util.Log; | 9 import android.util.Log; |
| 9 | 10 |
| 10 import org.chromium.base.CommandLine; | 11 import org.chromium.base.CommandLine; |
| 11 import org.chromium.base.JNINamespace; | 12 import org.chromium.base.JNINamespace; |
| 12 import org.chromium.base.SysUtils; | 13 import org.chromium.base.SysUtils; |
| 13 import org.chromium.base.TraceEvent; | 14 import org.chromium.base.TraceEvent; |
| 14 | 15 |
| 15 /** | 16 /** |
| 16 * This class provides functionality to load and register the native libraries. | 17 * This class provides functionality to load and register the native libraries. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 34 private static final Object sLock = new Object(); | 35 private static final Object sLock = new Object(); |
| 35 | 36 |
| 36 // One-way switch becomes true when the libraries are loaded. | 37 // One-way switch becomes true when the libraries are loaded. |
| 37 private static boolean sLoaded = false; | 38 private static boolean sLoaded = false; |
| 38 | 39 |
| 39 // One-way switch becomes true when the libraries are initialized ( | 40 // One-way switch becomes true when the libraries are initialized ( |
| 40 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in | 41 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in |
| 41 // library_loader_hooks.cc). | 42 // library_loader_hooks.cc). |
| 42 private static boolean sInitialized = false; | 43 private static boolean sInitialized = false; |
| 43 | 44 |
| 45 // One-way switch becomes true if the system library loading failed, |
| 46 // and the right native library was found and loaded by the hack. |
| 47 // The flag is used to report UMA stats later. |
| 48 private static boolean sNativeLibraryHackWasUsed = false; |
| 49 |
| 50 |
| 51 /** |
| 52 * TODO: http://crbug.com/354655 |
| 53 * remove this method once WebViewChromiumFactoryProvider.java |
| 54 * changes the call to ensureInitialized(null). |
| 55 */ |
| 56 public static void ensureInitialized() throws ProcessInitException { |
| 57 ensureInitialized(null); |
| 58 } |
| 59 |
| 44 /** | 60 /** |
| 45 * This method blocks until the library is fully loaded and initialized. | 61 * This method blocks until the library is fully loaded and initialized. |
| 62 * |
| 63 * @param context The context in which the method is called, the caller |
| 64 * may pass in a null context if it doesn't know in which context it |
| 65 * is running, or it doesn't need to work around the issue |
| 66 * http://b/13216167. |
| 67 * |
| 68 * When the context is not null and native library was not extracted |
| 69 * by Android package manager, the LibraryLoader class |
| 70 * will extract the native libraries from APK. This is a hack used to |
| 71 * work around some Sony devices with the following platform bug: |
| 72 * http://b/13216167. |
| 46 */ | 73 */ |
| 47 public static void ensureInitialized() throws ProcessInitException { | 74 public static void ensureInitialized(Context context) throws ProcessInitExce
ption { |
| 48 synchronized (sLock) { | 75 synchronized (sLock) { |
| 49 if (sInitialized) { | 76 if (sInitialized) { |
| 50 // Already initialized, nothing to do. | 77 // Already initialized, nothing to do. |
| 51 return; | 78 return; |
| 52 } | 79 } |
| 53 loadAlreadyLocked(); | 80 loadAlreadyLocked(context); |
| 54 initializeAlreadyLocked(CommandLine.getJavaSwitchesOrNull()); | 81 initializeAlreadyLocked(CommandLine.getJavaSwitchesOrNull()); |
| 55 } | 82 } |
| 56 } | 83 } |
| 57 | 84 |
| 58 /** | 85 /** |
| 59 * Checks if library is fully loaded and initialized. | 86 * Checks if library is fully loaded and initialized. |
| 60 */ | 87 */ |
| 61 public static boolean isInitialized() { | 88 public static boolean isInitialized() { |
| 62 synchronized (sLock) { | 89 synchronized (sLock) { |
| 63 return sInitialized; | 90 return sInitialized; |
| 64 } | 91 } |
| 65 } | 92 } |
| 66 | 93 |
| 67 /** | 94 /** |
| 68 * Loads the library and blocks until the load completes. The caller is resp
onsible | 95 * Loads the library and blocks until the load completes. The caller is resp
onsible |
| 69 * for subsequently calling ensureInitialized(). | 96 * for subsequently calling ensureInitialized(). |
| 70 * May be called on any thread, but should only be called once. Note the thr
ead | 97 * May be called on any thread, but should only be called once. Note the thr
ead |
| 71 * this is called on will be the thread that runs the native code's static i
nitializers. | 98 * this is called on will be the thread that runs the native code's static i
nitializers. |
| 72 * See the comment in doInBackground() for more considerations on this. | 99 * See the comment in doInBackground() for more considerations on this. |
| 73 * | 100 * |
| 74 * @throws ProcessInitException if the native library failed to load. | 101 * @throws ProcessInitException if the native library failed to load. |
| 75 */ | 102 */ |
| 76 public static void loadNow() throws ProcessInitException { | 103 public static void loadNow(Context context) throws ProcessInitException { |
| 77 synchronized (sLock) { | 104 synchronized (sLock) { |
| 78 loadAlreadyLocked(); | 105 loadAlreadyLocked(context); |
| 79 } | 106 } |
| 80 } | 107 } |
| 81 | 108 |
| 82 /** | 109 /** |
| 83 * initializes the library here and now: must be called on the thread that t
he | 110 * initializes the library here and now: must be called on the thread that t
he |
| 84 * native will call its "main" thread. The library must have previously been | 111 * native will call its "main" thread. The library must have previously been |
| 85 * loaded with loadNow. | 112 * loaded with loadNow. |
| 86 * @param initCommandLine The command line arguments that native command lin
e will | 113 * @param initCommandLine The command line arguments that native command lin
e will |
| 87 * be initialized with. | 114 * be initialized with. |
| 88 */ | 115 */ |
| 89 public static void initialize(String[] initCommandLine) throws ProcessInitEx
ception { | 116 public static void initialize(String[] initCommandLine) throws ProcessInitEx
ception { |
| 90 synchronized (sLock) { | 117 synchronized (sLock) { |
| 91 initializeAlreadyLocked(initCommandLine); | 118 initializeAlreadyLocked(initCommandLine); |
| 92 } | 119 } |
| 93 } | 120 } |
| 94 | 121 |
| 95 // Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code | 122 // Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code |
| 96 private static void loadAlreadyLocked() throws ProcessInitException { | 123 private static void loadAlreadyLocked(Context context) throws ProcessInitExc
eption { |
| 97 try { | 124 try { |
| 98 if (!sLoaded) { | 125 if (!sLoaded) { |
| 99 assert !sInitialized; | 126 assert !sInitialized; |
| 100 | 127 |
| 101 long startTime = SystemClock.uptimeMillis(); | 128 long startTime = SystemClock.uptimeMillis(); |
| 102 boolean useChromiumLinker = Linker.isUsed(); | 129 boolean useChromiumLinker = Linker.isUsed(); |
| 103 | 130 |
| 104 if (useChromiumLinker) Linker.prepareLibraryLoad(); | 131 if (useChromiumLinker) Linker.prepareLibraryLoad(); |
| 105 | 132 |
| 106 for (String library : NativeLibraries.LIBRARIES) { | 133 for (String library : NativeLibraries.LIBRARIES) { |
| 107 Log.i(TAG, "Loading: " + library); | 134 Log.i(TAG, "Loading: " + library); |
| 108 if (useChromiumLinker) { | 135 if (useChromiumLinker) { |
| 109 Linker.loadLibrary(library); | 136 Linker.loadLibrary(library); |
| 110 } else { | 137 } else { |
| 111 System.loadLibrary(library); | 138 try { |
| 139 System.loadLibrary(library); |
| 140 if (context != null) { |
| 141 LibraryLoaderHelper.deleteWorkaroundLibrariesAsy
nchronously( |
| 142 context); |
| 143 } |
| 144 } catch (UnsatisfiedLinkError e) { |
| 145 if (context != null |
| 146 && LibraryLoaderHelper.tryLoadLibraryUsingWorkar
ound(context, |
| 147
library)) { |
| 148 sNativeLibraryHackWasUsed = true; |
| 149 } else { |
| 150 throw e; |
| 151 } |
| 152 } |
| 112 } | 153 } |
| 113 } | 154 } |
| 114 if (useChromiumLinker) Linker.finishLibraryLoad(); | 155 if (useChromiumLinker) Linker.finishLibraryLoad(); |
| 115 long stopTime = SystemClock.uptimeMillis(); | 156 long stopTime = SystemClock.uptimeMillis(); |
| 116 Log.i(TAG, String.format("Time to load native libraries: %d ms (
timestamps %d-%d)", | 157 Log.i(TAG, String.format("Time to load native libraries: %d ms (
timestamps %d-%d)", |
| 117 stopTime - startTime, | 158 stopTime - startTime, |
| 118 startTime % 10000, | 159 startTime % 10000, |
| 119 stopTime % 10000)); | 160 stopTime % 10000)); |
| 120 sLoaded = true; | 161 sLoaded = true; |
| 121 } | 162 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 147 // shouldn't complain from now on (and in fact, it's used by the | 188 // shouldn't complain from now on (and in fact, it's used by the |
| 148 // following calls). | 189 // following calls). |
| 149 sInitialized = true; | 190 sInitialized = true; |
| 150 CommandLine.enableNativeProxy(); | 191 CommandLine.enableNativeProxy(); |
| 151 TraceEvent.setEnabledToMatchNative(); | 192 TraceEvent.setEnabledToMatchNative(); |
| 152 // Record histogram for the Chromium linker. | 193 // Record histogram for the Chromium linker. |
| 153 if (Linker.isUsed()) { | 194 if (Linker.isUsed()) { |
| 154 nativeRecordChromiumAndroidLinkerHistogram(Linker.loadAtFixedAddress
Failed(), | 195 nativeRecordChromiumAndroidLinkerHistogram(Linker.loadAtFixedAddress
Failed(), |
| 155 SysUtils.isLowEndDevice()); | 196 SysUtils.isLowEndDevice()); |
| 156 } | 197 } |
| 198 |
| 199 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); |
| 157 } | 200 } |
| 158 | 201 |
| 159 // Only methods needed before or during normal JNI registration are during S
ystem.OnLoad. | 202 // Only methods needed before or during normal JNI registration are during S
ystem.OnLoad. |
| 160 // nativeLibraryLoaded is then called to register everything else. This pro
cess is called | 203 // nativeLibraryLoaded is then called to register everything else. This pro
cess is called |
| 161 // "initialization". This method will be mapped (by generated code) to the
LibraryLoaded | 204 // "initialization". This method will be mapped (by generated code) to the
LibraryLoaded |
| 162 // definition in base/android/library_loader/library_loader_hooks.cc. | 205 // definition in base/android/library_loader/library_loader_hooks.cc. |
| 163 // | 206 // |
| 164 // Return true on success and false on failure. | 207 // Return true on success and false on failure. |
| 165 private static native boolean nativeLibraryLoaded(String[] initCommandLine); | 208 private static native boolean nativeLibraryLoaded(String[] initCommandLine); |
| 166 | 209 |
| 167 // Method called to record statistics about the Chromium linker operation, | 210 // Method called to record statistics about the Chromium linker operation, |
| 168 // i.e. whether the library failed to be loaded at a fixed address, and | 211 // i.e. whether the library failed to be loaded at a fixed address, and |
| 169 // whether the device is 'low-memory'. | 212 // whether the device is 'low-memory'. |
| 170 private static native void nativeRecordChromiumAndroidLinkerHistogram( | 213 private static native void nativeRecordChromiumAndroidLinkerHistogram( |
| 171 boolean loadedAtFixedAddressFailed, | 214 boolean loadedAtFixedAddressFailed, |
| 172 boolean isLowMemoryDevice); | 215 boolean isLowMemoryDevice); |
| 173 | 216 |
| 174 // Get the version of the native library. This is needed so that we can chec
k we | 217 // Get the version of the native library. This is needed so that we can chec
k we |
| 175 // have the right version before initializing the (rest of the) JNI. | 218 // have the right version before initializing the (rest of the) JNI. |
| 176 private static native String nativeGetVersionNumber(); | 219 private static native String nativeGetVersionNumber(); |
| 220 |
| 221 private static native void nativeRecordNativeLibraryHack(boolean usedHack); |
| 177 } | 222 } |
| OLD | NEW |