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.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.pm.ApplicationInfo; | 9 import android.content.pm.ApplicationInfo; |
10 import android.content.pm.PackageInfo; | 10 import android.content.pm.PackageInfo; |
11 import android.os.AsyncTask; | 11 import android.os.AsyncTask; |
12 import android.os.Build; | 12 import android.os.Build; |
13 import android.os.SystemClock; | 13 import android.os.SystemClock; |
14 import android.util.Log; | |
15 | 14 |
16 import org.chromium.base.CalledByNative; | 15 import org.chromium.base.CalledByNative; |
17 import org.chromium.base.CommandLine; | 16 import org.chromium.base.CommandLine; |
18 import org.chromium.base.JNINamespace; | 17 import org.chromium.base.JNINamespace; |
| 18 import org.chromium.base.Log; |
19 import org.chromium.base.PackageUtils; | 19 import org.chromium.base.PackageUtils; |
20 import org.chromium.base.TraceEvent; | 20 import org.chromium.base.TraceEvent; |
21 import org.chromium.base.VisibleForTesting; | |
22 import org.chromium.base.metrics.RecordHistogram; | 21 import org.chromium.base.metrics.RecordHistogram; |
23 | 22 |
| 23 import java.util.concurrent.atomic.AtomicBoolean; |
| 24 |
24 import javax.annotation.Nullable; | 25 import javax.annotation.Nullable; |
25 | 26 |
26 /** | 27 /** |
27 * This class provides functionality to load and register the native libraries. | 28 * This class provides functionality to load and register the native libraries. |
28 * Callers are allowed to separate loading the libraries from initializing them. | 29 * Callers are allowed to separate loading the libraries from initializing them. |
29 * This may be an advantage for Android Webview, where the libraries can be load
ed | 30 * This may be an advantage for Android Webview, where the libraries can be load
ed |
30 * by the zygote process, but then needs per process initialization after the | 31 * by the zygote process, but then needs per process initialization after the |
31 * application processes are forked from the zygote process. | 32 * application processes are forked from the zygote process. |
32 * | 33 * |
33 * The libraries may be loaded and initialized from any thread. Synchronization | 34 * The libraries may be loaded and initialized from any thread. Synchronization |
34 * primitives are used to ensure that overlapping requests from different | 35 * primitives are used to ensure that overlapping requests from different |
35 * threads are handled sequentially. | 36 * threads are handled sequentially. |
36 * | 37 * |
37 * See also base/android/library_loader/library_loader_hooks.cc, which contains | 38 * See also base/android/library_loader/library_loader_hooks.cc, which contains |
38 * the native counterpart to this class. | 39 * the native counterpart to this class. |
39 */ | 40 */ |
40 @JNINamespace("base::android") | 41 @JNINamespace("base::android") |
41 public class LibraryLoader { | 42 public class LibraryLoader { |
42 private static final String TAG = "LibraryLoader"; | 43 private static final String TAG = "cr.library_loader"; |
43 | 44 |
44 // Set to true to enable debug logs. | 45 // Set to true to enable debug logs. |
45 private static final boolean DEBUG = false; | 46 private static final boolean DEBUG = false; |
46 | 47 |
47 // Guards all access to the libraries | 48 // Guards all access to the libraries |
48 private static final Object sLock = new Object(); | 49 private static final Object sLock = new Object(); |
49 | 50 |
50 // The singleton instance of LibraryLoader. | 51 // The singleton instance of LibraryLoader. |
51 private static volatile LibraryLoader sInstance; | 52 private static volatile LibraryLoader sInstance; |
52 | 53 |
(...skipping 13 matching lines...) Expand all Loading... |
66 | 67 |
67 // One-way switches recording attempts to use Relro sharing in the browser. | 68 // One-way switches recording attempts to use Relro sharing in the browser. |
68 // The flags are used to report UMA stats later. | 69 // The flags are used to report UMA stats later. |
69 private boolean mIsUsingBrowserSharedRelros; | 70 private boolean mIsUsingBrowserSharedRelros; |
70 private boolean mLoadAtFixedAddressFailed; | 71 private boolean mLoadAtFixedAddressFailed; |
71 | 72 |
72 // One-way switch becomes true if the Chromium library was loaded from the | 73 // One-way switch becomes true if the Chromium library was loaded from the |
73 // APK file directly. | 74 // APK file directly. |
74 private boolean mLibraryWasLoadedFromApk; | 75 private boolean mLibraryWasLoadedFromApk; |
75 | 76 |
76 // One-way switch becomes false if the Chromium library should be loaded | |
77 // directly from the APK file but it was compressed or not aligned. | |
78 private boolean mLibraryIsMappableInApk = true; | |
79 | |
80 // The type of process the shared library is loaded in. | 77 // The type of process the shared library is loaded in. |
81 // This member can be accessed from multiple threads simultaneously, so it h
ave to be | 78 // This member can be accessed from multiple threads simultaneously, so it h
ave to be |
82 // final (like now) or be protected in some way (volatile of synchronized). | 79 // final (like now) or be protected in some way (volatile of synchronized). |
83 private final int mLibraryProcessType; | 80 private final int mLibraryProcessType; |
84 | 81 |
| 82 // One-way switch that becomes true once |
| 83 // {@link asyncPrefetchLibrariesToMemory} has been called. |
| 84 private final AtomicBoolean mPrefetchLibraryHasBeenCalled; |
| 85 |
| 86 // The number of milliseconds it took to load all the native libraries, whic
h |
| 87 // will be reported via UMA. Set once when the libraries are done loading. |
| 88 private long mLibraryLoadTimeMs; |
| 89 |
85 /** | 90 /** |
86 * @param libraryProcessType the process the shared library is loaded in. re
fer to | 91 * @param libraryProcessType the process the shared library is loaded in. re
fer to |
87 * LibraryProcessType for possible values. | 92 * LibraryProcessType for possible values. |
88 * @return LibraryLoader if existing, otherwise create a new one. | 93 * @return LibraryLoader if existing, otherwise create a new one. |
89 */ | 94 */ |
90 public static LibraryLoader get(int libraryProcessType) throws ProcessInitEx
ception { | 95 public static LibraryLoader get(int libraryProcessType) throws ProcessInitEx
ception { |
91 synchronized (sLock) { | 96 synchronized (sLock) { |
92 if (sInstance != null) { | 97 if (sInstance != null) { |
93 if (sInstance.mLibraryProcessType == libraryProcessType) return
sInstance; | 98 if (sInstance.mLibraryProcessType == libraryProcessType) return
sInstance; |
94 throw new ProcessInitException( | 99 throw new ProcessInitException( |
95 LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_LOAD_FAILED); | 100 LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_LOAD_FAILED); |
96 } | 101 } |
97 sInstance = new LibraryLoader(libraryProcessType); | 102 sInstance = new LibraryLoader(libraryProcessType); |
98 return sInstance; | 103 return sInstance; |
99 } | 104 } |
100 } | 105 } |
101 | 106 |
102 private LibraryLoader(int libraryProcessType) { | 107 private LibraryLoader(int libraryProcessType) { |
103 mLibraryProcessType = libraryProcessType; | 108 mLibraryProcessType = libraryProcessType; |
104 } | 109 mPrefetchLibraryHasBeenCalled = new AtomicBoolean(); |
105 | |
106 /** | |
107 * The same as ensureInitialized(null, false), should only be called | |
108 * by non-browser processes. | |
109 * | |
110 * @throws ProcessInitException | |
111 */ | |
112 @VisibleForTesting | |
113 public void ensureInitialized() throws ProcessInitException { | |
114 ensureInitialized(null, false); | |
115 } | 110 } |
116 | 111 |
117 /** | 112 /** |
118 * This method blocks until the library is fully loaded and initialized. | 113 * This method blocks until the library is fully loaded and initialized. |
119 * | 114 * |
120 * @param context The context in which the method is called, the caller | 115 * @param context The context in which the method is called. |
121 * may pass in a null context if it doesn't know in which context it | |
122 * is running. | |
123 * | |
124 * @param shouldDeleteFallbackLibraries The flag tells whether the method | |
125 * should delete the fallback libraries or not. | |
126 */ | 116 */ |
127 public void ensureInitialized( | 117 public void ensureInitialized(Context context) throws ProcessInitException { |
128 Context context, boolean shouldDeleteFallbackLibraries) | |
129 throws ProcessInitException { | |
130 synchronized (sLock) { | 118 synchronized (sLock) { |
131 if (mInitialized) { | 119 if (mInitialized) { |
132 // Already initialized, nothing to do. | 120 // Already initialized, nothing to do. |
133 return; | 121 return; |
134 } | 122 } |
135 loadAlreadyLocked(context, shouldDeleteFallbackLibraries); | 123 loadAlreadyLocked(context); |
136 initializeAlreadyLocked(); | 124 initializeAlreadyLocked(); |
137 } | 125 } |
138 } | 126 } |
139 | 127 |
140 /** | 128 /** |
141 * Checks if library is fully loaded and initialized. | 129 * Checks if library is fully loaded and initialized. |
142 */ | 130 */ |
143 public static boolean isInitialized() { | 131 public static boolean isInitialized() { |
144 return sInstance != null && sInstance.mInitialized; | 132 return sInstance != null && sInstance.mInitialized; |
145 } | 133 } |
146 | 134 |
147 /** | 135 /** |
148 * The same as loadNow(null, false), should only be called by | |
149 * non-browser process. | |
150 * | |
151 * @throws ProcessInitException | |
152 */ | |
153 public void loadNow() throws ProcessInitException { | |
154 loadNow(null, false); | |
155 } | |
156 | |
157 /** | |
158 * Loads the library and blocks until the load completes. The caller is resp
onsible | 136 * Loads the library and blocks until the load completes. The caller is resp
onsible |
159 * for subsequently calling ensureInitialized(). | 137 * for subsequently calling ensureInitialized(). |
160 * May be called on any thread, but should only be called once. Note the thr
ead | 138 * May be called on any thread, but should only be called once. Note the thr
ead |
161 * this is called on will be the thread that runs the native code's static i
nitializers. | 139 * this is called on will be the thread that runs the native code's static i
nitializers. |
162 * See the comment in doInBackground() for more considerations on this. | 140 * See the comment in doInBackground() for more considerations on this. |
163 * | 141 * |
164 * @param context The context the code is running, or null if it doesn't hav
e one. | 142 * @param context The context the code is running. |
165 * @param shouldDeleteFallbackLibraries The flag tells whether the method | |
166 * should delete the old fallback libraries or not. | |
167 * | 143 * |
168 * @throws ProcessInitException if the native library failed to load. | 144 * @throws ProcessInitException if the native library failed to load. |
169 */ | 145 */ |
170 public void loadNow(Context context, boolean shouldDeleteFallbackLibraries) | 146 public void loadNow(Context context) throws ProcessInitException { |
171 throws ProcessInitException { | |
172 synchronized (sLock) { | 147 synchronized (sLock) { |
173 loadAlreadyLocked(context, shouldDeleteFallbackLibraries); | 148 loadAlreadyLocked(context); |
174 } | 149 } |
175 } | 150 } |
176 | 151 |
177 /** | 152 /** |
178 * initializes the library here and now: must be called on the thread that t
he | 153 * initializes the library here and now: must be called on the thread that t
he |
179 * native will call its "main" thread. The library must have previously been | 154 * native will call its "main" thread. The library must have previously been |
180 * loaded with loadNow. | 155 * loaded with loadNow. |
181 */ | 156 */ |
182 public void initialize() throws ProcessInitException { | 157 public void initialize() throws ProcessInitException { |
183 synchronized (sLock) { | 158 synchronized (sLock) { |
184 initializeAlreadyLocked(); | 159 initializeAlreadyLocked(); |
185 } | 160 } |
186 } | 161 } |
187 | 162 |
188 /** Prefetches the native libraries in a background thread. | 163 /** Prefetches the native libraries in a background thread. |
189 * | 164 * |
190 * Launches an AsyncTask that, through a short-lived forked process, reads a | 165 * Launches an AsyncTask that, through a short-lived forked process, reads a |
191 * part of each page of the native library. This is done to warm up the | 166 * part of each page of the native library. This is done to warm up the |
192 * page cache, turning hard page faults into soft ones. | 167 * page cache, turning hard page faults into soft ones. |
193 * | 168 * |
194 * This is done this way, as testing shows that fadvise(FADV_WILLNEED) is | 169 * This is done this way, as testing shows that fadvise(FADV_WILLNEED) is |
195 * detrimental to the startup time. | 170 * detrimental to the startup time. |
196 * | |
197 * @param context the application context. | |
198 */ | 171 */ |
199 public void asyncPrefetchLibrariesToMemory(final Context context) { | 172 public void asyncPrefetchLibrariesToMemory() { |
| 173 if (!mPrefetchLibraryHasBeenCalled.compareAndSet(false, true)) return; |
200 new AsyncTask<Void, Void, Void>() { | 174 new AsyncTask<Void, Void, Void>() { |
201 @Override | 175 @Override |
202 protected Void doInBackground(Void... params) { | 176 protected Void doInBackground(Void... params) { |
203 TraceEvent.begin("LibraryLoader.asyncPrefetchLibrariesToMemory")
; | 177 TraceEvent.begin("LibraryLoader.asyncPrefetchLibrariesToMemory")
; |
204 boolean success = nativeForkAndPrefetchNativeLibrary(); | 178 boolean success = nativeForkAndPrefetchNativeLibrary(); |
205 if (!success) { | 179 if (!success) { |
206 Log.w(TAG, "Forking a process to prefetch the native library
failed."); | 180 Log.w(TAG, "Forking a process to prefetch the native library
failed."); |
207 } | 181 } |
208 RecordHistogram.recordBooleanHistogram("LibraryLoader.PrefetchSt
atus", success); | 182 RecordHistogram.recordBooleanHistogram("LibraryLoader.PrefetchSt
atus", success); |
209 TraceEvent.end("LibraryLoader.asyncPrefetchLibrariesToMemory"); | 183 TraceEvent.end("LibraryLoader.asyncPrefetchLibrariesToMemory"); |
210 return null; | 184 return null; |
211 } | 185 } |
212 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | 186 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
213 } | 187 } |
214 | 188 |
215 // Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code | 189 // Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code |
216 private void loadAlreadyLocked( | 190 private void loadAlreadyLocked(Context context) throws ProcessInitException
{ |
217 Context context, boolean shouldDeleteFallbackLibraries) | |
218 throws ProcessInitException { | |
219 try { | 191 try { |
220 if (!mLoaded) { | 192 if (!mLoaded) { |
221 assert !mInitialized; | 193 assert !mInitialized; |
222 | 194 |
223 long startTime = SystemClock.uptimeMillis(); | 195 long startTime = SystemClock.uptimeMillis(); |
224 boolean useChromiumLinker = Linker.isUsed(); | 196 Linker linker = Linker.getInstance(); |
225 boolean fallbackWasUsed = false; | 197 boolean useChromiumLinker = linker.isUsed(); |
226 | 198 |
227 if (useChromiumLinker) { | 199 if (useChromiumLinker) { |
228 // Determine the APK file path. | 200 // Determine the APK file path. |
229 String apkFilePath = null; | 201 String apkFilePath = getLibraryApkPath(context); |
230 if (context != null) { | |
231 apkFilePath = getLibraryApkPath(context); | |
232 } else { | |
233 Log.w(TAG, "could not check load from APK support due to
null context"); | |
234 } | |
235 | |
236 // Load libraries using the Chromium linker. | 202 // Load libraries using the Chromium linker. |
237 Linker.prepareLibraryLoad(); | 203 linker.prepareLibraryLoad(); |
238 | 204 |
239 for (String library : NativeLibraries.LIBRARIES) { | 205 for (String library : NativeLibraries.LIBRARIES) { |
240 // Don't self-load the linker. This is because the build
system is | 206 // Don't self-load the linker. This is because the build
system is |
241 // not clever enough to understand that all the librarie
s packaged | 207 // not clever enough to understand that all the librarie
s packaged |
242 // in the final .apk don't need to be explicitly loaded. | 208 // in the final .apk don't need to be explicitly loaded. |
243 if (Linker.isChromiumLinkerLibrary(library)) { | 209 if (linker.isChromiumLinkerLibrary(library)) { |
244 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); | 210 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); |
245 continue; | 211 continue; |
246 } | 212 } |
247 | 213 |
248 // Determine where the library should be loaded from. | 214 // Determine where the library should be loaded from. |
249 String zipFilePath = null; | 215 String zipFilePath = null; |
250 String libFilePath = System.mapLibraryName(library); | 216 String libFilePath = System.mapLibraryName(library); |
251 if (apkFilePath != null && Linker.isInZipFile()) { | 217 if (linker.isInZipFile()) { |
252 // The library is in the APK file. | 218 // Load directly from the APK. |
253 if (!Linker.checkLibraryIsMappableInApk(apkFilePath,
libFilePath)) { | 219 zipFilePath = apkFilePath; |
254 mLibraryIsMappableInApk = false; | 220 Log.i(TAG, |
255 } | 221 "Loading " + library + " directly from withi
n " + apkFilePath); |
256 if (mLibraryIsMappableInApk) { | |
257 // Load directly from the APK. | |
258 zipFilePath = apkFilePath; | |
259 Log.i(TAG, "Loading " + library + " directly fro
m within " | |
260 + apkFilePath); | |
261 } else { | |
262 // Unpack library fallback. | |
263 Log.i(TAG, "Loading " + library | |
264 + " using unpack library fallback from w
ithin " | |
265 + apkFilePath); | |
266 libFilePath = LibraryLoaderHelper.buildFallbackL
ibrary( | |
267 context, library); | |
268 fallbackWasUsed = true; | |
269 Log.i(TAG, "Built fallback library " + libFilePa
th); | |
270 } | |
271 } else { | 222 } else { |
272 // The library is in its own file. | 223 // The library is in its own file. |
273 Log.i(TAG, "Loading " + library); | 224 Log.i(TAG, "Loading " + library); |
274 } | 225 } |
275 | 226 |
276 // Load the library. | 227 // Load the library. |
277 boolean isLoaded = false; | 228 boolean isLoaded = false; |
278 if (Linker.isUsingBrowserSharedRelros()) { | 229 if (linker.isUsingBrowserSharedRelros()) { |
279 mIsUsingBrowserSharedRelros = true; | 230 mIsUsingBrowserSharedRelros = true; |
280 try { | 231 try { |
281 loadLibrary(zipFilePath, libFilePath); | 232 loadLibrary(zipFilePath, libFilePath); |
282 isLoaded = true; | 233 isLoaded = true; |
283 } catch (UnsatisfiedLinkError e) { | 234 } catch (UnsatisfiedLinkError e) { |
284 Log.w(TAG, "Failed to load native library with s
hared RELRO, " | 235 Log.w(TAG, "Failed to load native library with s
hared RELRO, " |
285 + "retrying without"); | 236 + "retrying without"); |
286 Linker.disableSharedRelros(); | 237 linker.disableSharedRelros(); |
287 mLoadAtFixedAddressFailed = true; | 238 mLoadAtFixedAddressFailed = true; |
288 } | 239 } |
289 } | 240 } |
290 if (!isLoaded) { | 241 if (!isLoaded) { |
291 loadLibrary(zipFilePath, libFilePath); | 242 loadLibrary(zipFilePath, libFilePath); |
292 } | 243 } |
293 } | 244 } |
294 | 245 |
295 Linker.finishLibraryLoad(); | 246 linker.finishLibraryLoad(); |
296 } else { | 247 } else { |
297 // Load libraries using the system linker. | 248 // Load libraries using the system linker. |
298 for (String library : NativeLibraries.LIBRARIES) { | 249 for (String library : NativeLibraries.LIBRARIES) { |
299 System.loadLibrary(library); | 250 System.loadLibrary(library); |
300 } | 251 } |
301 } | 252 } |
302 | 253 |
303 if (!fallbackWasUsed && context != null | |
304 && shouldDeleteFallbackLibraries) { | |
305 LibraryLoaderHelper.deleteLibrariesAsynchronously( | |
306 context, LibraryLoaderHelper.LOAD_FROM_APK_FALLBACK_
DIR); | |
307 } | |
308 | |
309 long stopTime = SystemClock.uptimeMillis(); | 254 long stopTime = SystemClock.uptimeMillis(); |
| 255 mLibraryLoadTimeMs = stopTime - startTime; |
310 Log.i(TAG, String.format("Time to load native libraries: %d ms (
timestamps %d-%d)", | 256 Log.i(TAG, String.format("Time to load native libraries: %d ms (
timestamps %d-%d)", |
311 stopTime - startTime, | 257 mLibraryLoadTimeMs, startTime % 10000, stopTi
me % 10000)); |
312 startTime % 10000, | |
313 stopTime % 10000)); | |
314 | 258 |
315 mLoaded = true; | 259 mLoaded = true; |
316 } | 260 } |
317 } catch (UnsatisfiedLinkError e) { | 261 } catch (UnsatisfiedLinkError e) { |
318 throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBR
ARY_LOAD_FAILED, e); | 262 throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBR
ARY_LOAD_FAILED, e); |
319 } | 263 } |
320 // Check that the version of the library we have loaded matches the vers
ion we expect | 264 // Check that the version of the library we have loaded matches the vers
ion we expect |
321 Log.i(TAG, String.format( | 265 Log.i(TAG, String.format("Expected native library version number \"%s\",
" |
322 "Expected native library version number \"%s\"," | 266 + "actual native library version number \"%s\
"", |
323 + "actual native library version number \"%s\"", | 267 NativeLibraries.sVersionNumber, nativeGetVersionNumbe
r())); |
324 NativeLibraries.sVersionNumber, | |
325 nativeGetVersionNumber())); | |
326 if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) { | 268 if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) { |
327 throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBR
ARY_WRONG_VERSION); | 269 throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBR
ARY_WRONG_VERSION); |
328 } | 270 } |
329 } | 271 } |
330 | 272 |
331 // Returns whether the given split name is that of the ABI split. | 273 // Returns whether the given split name is that of the ABI split. |
332 private static boolean isAbiSplit(String splitName) { | 274 private static boolean isAbiSplit(String splitName) { |
333 // The split name for the ABI split is manually set in the build rules. | 275 // The split name for the ABI split is manually set in the build rules. |
334 return splitName.startsWith("abi_"); | 276 return splitName.startsWith("abi_"); |
335 } | 277 } |
(...skipping 13 matching lines...) Expand all Loading... |
349 return appInfo.splitSourceDirs[i]; | 291 return appInfo.splitSourceDirs[i]; |
350 } | 292 } |
351 } | 293 } |
352 } | 294 } |
353 return appInfo.sourceDir; | 295 return appInfo.sourceDir; |
354 } | 296 } |
355 | 297 |
356 // Load a native shared library with the Chromium linker. If the zip file | 298 // Load a native shared library with the Chromium linker. If the zip file |
357 // path is not null, the library is loaded directly from the zip file. | 299 // path is not null, the library is loaded directly from the zip file. |
358 private void loadLibrary(@Nullable String zipFilePath, String libFilePath) { | 300 private void loadLibrary(@Nullable String zipFilePath, String libFilePath) { |
359 Linker.loadLibrary(zipFilePath, libFilePath); | 301 Linker.getInstance().loadLibrary(zipFilePath, libFilePath); |
360 if (zipFilePath != null) { | 302 if (zipFilePath != null) { |
361 mLibraryWasLoadedFromApk = true; | 303 mLibraryWasLoadedFromApk = true; |
362 } | 304 } |
363 } | 305 } |
364 | 306 |
365 // The WebView requires the Command Line to be switched over before | 307 // The WebView requires the Command Line to be switched over before |
366 // initialization is done. This is okay in the WebView's case since the | 308 // initialization is done. This is okay in the WebView's case since the |
367 // JNI is already loaded by this point. | 309 // JNI is already loaded by this point. |
368 public void switchCommandLineForWebView() { | 310 public void switchCommandLineForWebView() { |
369 synchronized (sLock) { | 311 synchronized (sLock) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 } | 361 } |
420 | 362 |
421 // Called after all native initializations are complete. | 363 // Called after all native initializations are complete. |
422 public void onNativeInitializationComplete(Context context) { | 364 public void onNativeInitializationComplete(Context context) { |
423 recordBrowserProcessHistogram(context); | 365 recordBrowserProcessHistogram(context); |
424 } | 366 } |
425 | 367 |
426 // Record Chromium linker histogram state for the main browser process. Call
ed from | 368 // Record Chromium linker histogram state for the main browser process. Call
ed from |
427 // onNativeInitializationComplete(). | 369 // onNativeInitializationComplete(). |
428 private void recordBrowserProcessHistogram(Context context) { | 370 private void recordBrowserProcessHistogram(Context context) { |
429 if (Linker.isUsed()) { | 371 if (Linker.getInstance().isUsed()) { |
430 nativeRecordChromiumAndroidLinkerBrowserHistogram(mIsUsingBrowserSha
redRelros, | 372 nativeRecordChromiumAndroidLinkerBrowserHistogram(mIsUsingBrowserSha
redRelros, |
431 mLoadAtFixedAddres
sFailed, | 373 mLoadAtFixedAddressFailed, getLibraryLoadFromApkStatus(conte
xt), |
432 getLibraryLoadFrom
ApkStatus(context)); | 374 mLibraryLoadTimeMs); |
433 } | 375 } |
434 } | 376 } |
435 | 377 |
436 // Returns the device's status for loading a library directly from the APK f
ile. | 378 // Returns the device's status for loading a library directly from the APK f
ile. |
437 // This method can only be called when the Chromium linker is used. | 379 // This method can only be called when the Chromium linker is used. |
438 private int getLibraryLoadFromApkStatus(Context context) { | 380 private int getLibraryLoadFromApkStatus(Context context) { |
439 assert Linker.isUsed(); | 381 assert Linker.getInstance().isUsed(); |
440 | 382 |
441 if (mLibraryWasLoadedFromApk) { | 383 if (mLibraryWasLoadedFromApk) { |
442 return LibraryLoadFromApkStatusCodes.SUCCESSFUL; | 384 return LibraryLoadFromApkStatusCodes.SUCCESSFUL; |
443 } | 385 } |
444 | 386 |
445 if (!mLibraryIsMappableInApk) { | |
446 return LibraryLoadFromApkStatusCodes.USED_UNPACK_LIBRARY_FALLBACK; | |
447 } | |
448 | |
449 // There were no libraries to be loaded directly from the APK file. | 387 // There were no libraries to be loaded directly from the APK file. |
450 return LibraryLoadFromApkStatusCodes.UNKNOWN; | 388 return LibraryLoadFromApkStatusCodes.UNKNOWN; |
451 } | 389 } |
452 | 390 |
453 // Register pending Chromium linker histogram state for renderer processes.
This cannot be | 391 // Register pending Chromium linker histogram state for renderer processes.
This cannot be |
454 // recorded as a histogram immediately because histograms and IPC are not re
ady at the | 392 // recorded as a histogram immediately because histograms and IPC are not re
ady at the |
455 // time it are captured. This function stores a pending value, so that a lat
er call to | 393 // time it are captured. This function stores a pending value, so that a lat
er call to |
456 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. | 394 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. |
457 public void registerRendererProcessHistogram(boolean requestedSharedRelro, | 395 public void registerRendererProcessHistogram(boolean requestedSharedRelro, |
458 boolean loadAtFixedAddressFaile
d) { | 396 boolean loadAtFixedAddressFaile
d) { |
459 if (Linker.isUsed()) { | 397 if (Linker.getInstance().isUsed()) { |
460 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared
Relro, | 398 nativeRegisterChromiumAndroidLinkerRendererHistogram( |
461 loadAtFixedAddr
essFailed); | 399 requestedSharedRelro, loadAtFixedAddressFailed, mLibraryLoad
TimeMs); |
462 } | 400 } |
463 } | 401 } |
464 | 402 |
465 /** | 403 /** |
466 * @return the process the shared library is loaded in, see the LibraryProce
ssType | 404 * @return the process the shared library is loaded in, see the LibraryProce
ssType |
467 * for possible values. | 405 * for possible values. |
468 */ | 406 */ |
469 @CalledByNative | 407 @CalledByNative |
470 public static int getLibraryProcessType() { | 408 public static int getLibraryProcessType() { |
471 if (sInstance == null) return LibraryProcessType.PROCESS_UNINITIALIZED; | 409 if (sInstance == null) return LibraryProcessType.PROCESS_UNINITIALIZED; |
472 return sInstance.mLibraryProcessType; | 410 return sInstance.mLibraryProcessType; |
473 } | 411 } |
474 | 412 |
475 private native void nativeInitCommandLine(String[] initCommandLine); | 413 private native void nativeInitCommandLine(String[] initCommandLine); |
476 | 414 |
477 // Only methods needed before or during normal JNI registration are during S
ystem.OnLoad. | 415 // Only methods needed before or during normal JNI registration are during S
ystem.OnLoad. |
478 // nativeLibraryLoaded is then called to register everything else. This pro
cess is called | 416 // nativeLibraryLoaded is then called to register everything else. This pro
cess is called |
479 // "initialization". This method will be mapped (by generated code) to the
LibraryLoaded | 417 // "initialization". This method will be mapped (by generated code) to the
LibraryLoaded |
480 // definition in base/android/library_loader/library_loader_hooks.cc. | 418 // definition in base/android/library_loader/library_loader_hooks.cc. |
481 // | 419 // |
482 // Return true on success and false on failure. | 420 // Return true on success and false on failure. |
483 private native boolean nativeLibraryLoaded(); | 421 private native boolean nativeLibraryLoaded(); |
484 | 422 |
485 // Method called to record statistics about the Chromium linker operation fo
r the main | 423 // Method called to record statistics about the Chromium linker operation fo
r the main |
486 // browser process. Indicates whether the linker attempted relro sharing for
the browser, | 424 // browser process. Indicates whether the linker attempted relro sharing for
the browser, |
487 // and if it did, whether the library failed to load at a fixed address. Als
o records | 425 // and if it did, whether the library failed to load at a fixed address. Als
o records |
488 // support for loading a library directly from the APK file. | 426 // support for loading a library directly from the APK file, and the number
of milliseconds |
| 427 // it took to load the libraries. |
489 private native void nativeRecordChromiumAndroidLinkerBrowserHistogram( | 428 private native void nativeRecordChromiumAndroidLinkerBrowserHistogram( |
490 boolean isUsingBrowserSharedRelros, | 429 boolean isUsingBrowserSharedRelros, boolean loadAtFixedAddressFailed
, |
491 boolean loadAtFixedAddressFailed, | 430 int libraryLoadFromApkStatus, long libraryLoadTime); |
492 int libraryLoadFromApkStatus); | |
493 | 431 |
494 // Method called to register (for later recording) statistics about the Chro
mium linker | 432 // Method called to register (for later recording) statistics about the Chro
mium linker |
495 // operation for a renderer process. Indicates whether the linker attempted
relro sharing, | 433 // operation for a renderer process. Indicates whether the linker attempted
relro sharing, |
496 // and if it did, whether the library failed to load at a fixed address. | 434 // and if it did, whether the library failed to load at a fixed address. Als
o records the |
| 435 // number of milliseconds it took to load the libraries. |
497 private native void nativeRegisterChromiumAndroidLinkerRendererHistogram( | 436 private native void nativeRegisterChromiumAndroidLinkerRendererHistogram( |
498 boolean requestedSharedRelro, | 437 boolean requestedSharedRelro, boolean loadAtFixedAddressFailed, long
libraryLoadTime); |
499 boolean loadAtFixedAddressFailed); | |
500 | 438 |
501 // Get the version of the native library. This is needed so that we can chec
k we | 439 // Get the version of the native library. This is needed so that we can chec
k we |
502 // have the right version before initializing the (rest of the) JNI. | 440 // have the right version before initializing the (rest of the) JNI. |
503 private native String nativeGetVersionNumber(); | 441 private native String nativeGetVersionNumber(); |
504 | 442 |
505 // Finds the ranges corresponding to the native library pages, forks a new | 443 // Finds the ranges corresponding to the native library pages, forks a new |
506 // process to prefetch these pages and waits for it. The new process then | 444 // process to prefetch these pages and waits for it. The new process then |
507 // terminates. This is blocking. | 445 // terminates. This is blocking. |
508 private static native boolean nativeForkAndPrefetchNativeLibrary(); | 446 private static native boolean nativeForkAndPrefetchNativeLibrary(); |
509 } | 447 } |
OLD | NEW |