Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java

Issue 684163002: Library loading fallback. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 import org.chromium.base.CommandLine; 11 import org.chromium.base.CommandLine;
12 import org.chromium.base.JNINamespace; 12 import org.chromium.base.JNINamespace;
13 import org.chromium.base.TraceEvent; 13 import org.chromium.base.TraceEvent;
14 14
15 import javax.annotation.Nullable;
16
15 /** 17 /**
16 * This class provides functionality to load and register the native libraries. 18 * This class provides functionality to load and register the native libraries.
17 * Callers are allowed to separate loading the libraries from initializing them. 19 * Callers are allowed to separate loading the libraries from initializing them.
18 * This may be an advantage for Android Webview, where the libraries can be load ed 20 * This may be an advantage for Android Webview, where the libraries can be load ed
19 * by the zygote process, but then needs per process initialization after the 21 * by the zygote process, but then needs per process initialization after the
20 * application processes are forked from the zygote process. 22 * application processes are forked from the zygote process.
21 * 23 *
22 * The libraries may be loaded and initialized from any thread. Synchronization 24 * The libraries may be loaded and initialized from any thread. Synchronization
23 * primitives are used to ensure that overlapping requests from different 25 * primitives are used to ensure that overlapping requests from different
24 * threads are handled sequentially. 26 * threads are handled sequentially.
(...skipping 21 matching lines...) Expand all
46 // One-way switch becomes true when the libraries are initialized ( 48 // One-way switch becomes true when the libraries are initialized (
47 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in 49 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in
48 // library_loader_hooks.cc). 50 // library_loader_hooks.cc).
49 private static boolean sInitialized = false; 51 private static boolean sInitialized = false;
50 52
51 // One-way switches recording attempts to use Relro sharing in the browser. 53 // One-way switches recording attempts to use Relro sharing in the browser.
52 // The flags are used to report UMA stats later. 54 // The flags are used to report UMA stats later.
53 private static boolean sIsUsingBrowserSharedRelros = false; 55 private static boolean sIsUsingBrowserSharedRelros = false;
54 private static boolean sLoadAtFixedAddressFailed = false; 56 private static boolean sLoadAtFixedAddressFailed = false;
55 57
56 // One-way switch becomes true if the library was loaded from the APK file 58 // One-way switch becomes true if the device supports loading the Chromium
57 // directly. 59 // library directly from the APK.
60 private static boolean sLibraryLoadFromApkSupported = false;
61
62 // One-way switch becomes true if the Chromium library was loaded from the
63 // APK file directly.
58 private static boolean sLibraryWasLoadedFromApk = false; 64 private static boolean sLibraryWasLoadedFromApk = false;
59 65
60 // One-way switch becomes false if the Chromium library should be loaded 66 // One-way switch becomes false if the Chromium library should be loaded
61 // directly from the APK file but it was not aligned. 67 // directly from the APK file but it was not aligned.
62 private static boolean sLibraryWasAlignedInApk = true; 68 private static boolean sLibraryWasAlignedInApk = true;
63 69
64 // One-way switch becomes true if the system library loading failed, 70 // One-way switch becomes true if the system library loading failed,
65 // and the right native library was found and loaded by the hack. 71 // and the right native library was found and loaded by the hack.
66 // The flag is used to report UMA stats later. 72 // The flag is used to report UMA stats later.
67 private static boolean sNativeLibraryHackWasUsed = false; 73 private static boolean sNativeLibraryHackWasUsed = false;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 Context context, boolean shouldDeleteOldWorkaroundLibraries) 167 Context context, boolean shouldDeleteOldWorkaroundLibraries)
162 throws ProcessInitException { 168 throws ProcessInitException {
163 try { 169 try {
164 if (!sLoaded) { 170 if (!sLoaded) {
165 assert !sInitialized; 171 assert !sInitialized;
166 172
167 long startTime = SystemClock.uptimeMillis(); 173 long startTime = SystemClock.uptimeMillis();
168 boolean useChromiumLinker = Linker.isUsed(); 174 boolean useChromiumLinker = Linker.isUsed();
169 175
170 if (useChromiumLinker) { 176 if (useChromiumLinker) {
177 String apkFilename = null;
178
179 // Check if the device supports loading a library directly f rom the APK file.
180 if (context != null) {
181 apkFilename = context.getApplicationInfo().sourceDir;
182 sLibraryLoadFromApkSupported = Linker.checkLibraryLoadFr omApkSupport(
183 apkFilename);
184 } else {
185 Log.w(TAG, "loadAlreadyLocked(): null context");
186 }
187
171 // Load libraries using the Chromium linker. 188 // Load libraries using the Chromium linker.
172 Linker.prepareLibraryLoad(); 189 Linker.prepareLibraryLoad();
173 190
174 for (String library : NativeLibraries.LIBRARIES) { 191 for (String library : NativeLibraries.LIBRARIES) {
175 // Don't self-load the linker. This is because the build system is 192 // Don't self-load the linker. This is because the build system is
176 // not clever enough to understand that all the librarie s packaged 193 // not clever enough to understand that all the librarie s packaged
177 // in the final .apk don't need to be explicitly loaded. 194 // in the final .apk don't need to be explicitly loaded.
178 if (Linker.isChromiumLinkerLibrary(library)) { 195 if (Linker.isChromiumLinkerLibrary(library)) {
179 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); 196 if (DEBUG) Log.i(TAG, "ignoring self-linker load");
180 continue; 197 continue;
181 } 198 }
182 199
183 String zipfile = null; 200 // Determine where the library should be loaded from.
184 if (Linker.isInZipFile()) { 201 String zipFilename = null;
185 zipfile = context.getApplicationInfo().sourceDir; 202 String libFilename = System.mapLibraryName(library);
186 sLibraryWasAlignedInApk = Linker.checkLibraryAligned InApk( 203 if (apkFilename != null && Linker.isInZipFile()) {
187 zipfile, System.mapLibraryName(library)); 204 // The library is in the APK file.
188 Log.i(TAG, "Loading " + library + " from within " + zipfile); 205 if (!Linker.checkLibraryAlignedInApk(
206 apkFilename, System.mapLibraryName(library)) ) {
Anton 2014/10/29 13:35:35 Replace System.mapLibraryName(library) with libFil
petrcermak 2014/10/29 14:01:01 Done.
207 sLibraryWasAlignedInApk = false;
208 }
209 if (sLibraryLoadFromApkSupported && sLibraryWasAlign edInApk) {
210 // Load directly from the APK.
211 Log.i(TAG, "Loading " + library + " directly fro m within " +
212 apkFilename);
213 zipFilename = apkFilename;
214 } else {
215 // Fallback.
216 Log.i(TAG, "Loading " + library + " using fallba ck from within " +
217 apkFilename);
218 libFilename = LibraryLoaderHelper.buildFallbackL ibrary(
219 context, apkFilename, libFilename);
220 Log.i(TAG, "Built fallback library " + libFilena me);
221 }
189 } else { 222 } else {
190 Log.i(TAG, "Loading: " + library); 223 // The library is in its own file.
224 Log.i(TAG, "Loading " + library);
191 } 225 }
192 226
227 // Load the library.
193 boolean isLoaded = false; 228 boolean isLoaded = false;
194 if (Linker.isUsingBrowserSharedRelros()) { 229 if (Linker.isUsingBrowserSharedRelros()) {
195 sIsUsingBrowserSharedRelros = true; 230 sIsUsingBrowserSharedRelros = true;
196 try { 231 try {
197 if (zipfile != null) { 232 loadLibrary(zipFilename, libFilename);
198 Linker.loadLibraryInZipFile(zipfile, library );
199 sLibraryWasLoadedFromApk = true;
200 } else {
201 Linker.loadLibrary(library);
202 }
203 isLoaded = true; 233 isLoaded = true;
204 } catch (UnsatisfiedLinkError e) { 234 } catch (UnsatisfiedLinkError e) {
205 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, " +
206 "retrying without"); 236 "retrying without");
207 Linker.disableSharedRelros(); 237 Linker.disableSharedRelros();
208 sLoadAtFixedAddressFailed = true; 238 sLoadAtFixedAddressFailed = true;
209 } 239 }
210 } 240 }
211 if (!isLoaded) { 241 if (!isLoaded) {
212 if (zipfile != null) { 242 loadLibrary(zipFilename, libFilename);
213 Linker.loadLibraryInZipFile(zipfile, library);
214 sLibraryWasLoadedFromApk = true;
215 } else {
216 Linker.loadLibrary(library);
217 }
218 } 243 }
219 } 244 }
220 245
221 Linker.finishLibraryLoad(); 246 Linker.finishLibraryLoad();
222 } else { 247 } else {
223 // Load libraries using the system linker. 248 // Load libraries using the system linker.
224 for (String library : NativeLibraries.LIBRARIES) { 249 for (String library : NativeLibraries.LIBRARIES) {
225 try { 250 try {
226 System.loadLibrary(library); 251 System.loadLibrary(library);
227 } catch (UnsatisfiedLinkError e) { 252 } catch (UnsatisfiedLinkError e) {
(...skipping 30 matching lines...) Expand all
258 Log.i(TAG, String.format( 283 Log.i(TAG, String.format(
259 "Expected native library version number \"%s\"," + 284 "Expected native library version number \"%s\"," +
260 "actual native library version number \"%s\"", 285 "actual native library version number \"%s\"",
261 NativeLibraries.sVersionNumber, 286 NativeLibraries.sVersionNumber,
262 nativeGetVersionNumber())); 287 nativeGetVersionNumber()));
263 if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) { 288 if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) {
264 throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBR ARY_WRONG_VERSION); 289 throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBR ARY_WRONG_VERSION);
265 } 290 }
266 } 291 }
267 292
293 // Load a native shared library with the Chromium linker. If the zip file
294 // filename is not null, the library is loaded directly from the zip file.
295 private static void loadLibrary(@Nullable String zipFilename, String libFile name) {
296 if (zipFilename != null) {
297 sLibraryWasLoadedFromApk = true;
298 }
299 Linker.loadLibrary(zipFilename, libFilename);
300 }
301
268 // The WebView requires the Command Line to be switched over before 302 // The WebView requires the Command Line to be switched over before
269 // initialization is done. This is okay in the WebView's case since the 303 // initialization is done. This is okay in the WebView's case since the
270 // JNI is already loaded by this point. 304 // JNI is already loaded by this point.
271 public static void switchCommandLineForWebView() { 305 public static void switchCommandLineForWebView() {
272 synchronized (sLock) { 306 synchronized (sLock) {
273 ensureCommandLineSwitchedAlreadyLocked(); 307 ensureCommandLineSwitchedAlreadyLocked();
274 } 308 }
275 } 309 }
276 310
277 // Switch the CommandLine over from Java to native if it hasn't already been done. 311 // Switch the CommandLine over from Java to native if it hasn't already been done.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog ram( 428 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog ram(
395 boolean requestedSharedRelro, 429 boolean requestedSharedRelro,
396 boolean loadAtFixedAddressFailed); 430 boolean loadAtFixedAddressFailed);
397 431
398 // Get the version of the native library. This is needed so that we can chec k we 432 // Get the version of the native library. This is needed so that we can chec k we
399 // have the right version before initializing the (rest of the) JNI. 433 // have the right version before initializing the (rest of the) JNI.
400 private static native String nativeGetVersionNumber(); 434 private static native String nativeGetVersionNumber();
401 435
402 private static native void nativeRecordNativeLibraryHack(boolean usedHack); 436 private static native void nativeRecordNativeLibraryHack(boolean usedHack);
403 } 437 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698