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 |