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

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

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 11 months 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 side-by-side diff with in-line comments
Download patch
Index: base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
index a789eff611f68fb972e03c32d871f0534733d622..5dfc2ba2edc3004ccc449a40ade168838648e428 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -11,16 +11,17 @@ import android.content.pm.PackageInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.os.SystemClock;
-import android.util.Log;
import org.chromium.base.CalledByNative;
import org.chromium.base.CommandLine;
import org.chromium.base.JNINamespace;
+import org.chromium.base.Log;
import org.chromium.base.PackageUtils;
import org.chromium.base.TraceEvent;
-import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import javax.annotation.Nullable;
/**
@@ -39,7 +40,7 @@ import javax.annotation.Nullable;
*/
@JNINamespace("base::android")
public class LibraryLoader {
- private static final String TAG = "LibraryLoader";
+ private static final String TAG = "cr.library_loader";
// Set to true to enable debug logs.
private static final boolean DEBUG = false;
@@ -73,15 +74,19 @@ public class LibraryLoader {
// APK file directly.
private boolean mLibraryWasLoadedFromApk;
- // One-way switch becomes false if the Chromium library should be loaded
- // directly from the APK file but it was compressed or not aligned.
- private boolean mLibraryIsMappableInApk = true;
-
// The type of process the shared library is loaded in.
// This member can be accessed from multiple threads simultaneously, so it have to be
// final (like now) or be protected in some way (volatile of synchronized).
private final int mLibraryProcessType;
+ // One-way switch that becomes true once
+ // {@link asyncPrefetchLibrariesToMemory} has been called.
+ private final AtomicBoolean mPrefetchLibraryHasBeenCalled;
+
+ // The number of milliseconds it took to load all the native libraries, which
+ // will be reported via UMA. Set once when the libraries are done loading.
+ private long mLibraryLoadTimeMs;
+
/**
* @param libraryProcessType the process the shared library is loaded in. refer to
* LibraryProcessType for possible values.
@@ -101,38 +106,21 @@ public class LibraryLoader {
private LibraryLoader(int libraryProcessType) {
mLibraryProcessType = libraryProcessType;
- }
-
- /**
- * The same as ensureInitialized(null, false), should only be called
- * by non-browser processes.
- *
- * @throws ProcessInitException
- */
- @VisibleForTesting
- public void ensureInitialized() throws ProcessInitException {
- ensureInitialized(null, false);
+ mPrefetchLibraryHasBeenCalled = new AtomicBoolean();
}
/**
* This method blocks until the library is fully loaded and initialized.
*
- * @param context The context in which the method is called, the caller
- * may pass in a null context if it doesn't know in which context it
- * is running.
- *
- * @param shouldDeleteFallbackLibraries The flag tells whether the method
- * should delete the fallback libraries or not.
+ * @param context The context in which the method is called.
*/
- public void ensureInitialized(
- Context context, boolean shouldDeleteFallbackLibraries)
- throws ProcessInitException {
+ public void ensureInitialized(Context context) throws ProcessInitException {
synchronized (sLock) {
if (mInitialized) {
// Already initialized, nothing to do.
return;
}
- loadAlreadyLocked(context, shouldDeleteFallbackLibraries);
+ loadAlreadyLocked(context);
initializeAlreadyLocked();
}
}
@@ -145,32 +133,19 @@ public class LibraryLoader {
}
/**
- * The same as loadNow(null, false), should only be called by
- * non-browser process.
- *
- * @throws ProcessInitException
- */
- public void loadNow() throws ProcessInitException {
- loadNow(null, false);
- }
-
- /**
* Loads the library and blocks until the load completes. The caller is responsible
* for subsequently calling ensureInitialized().
* May be called on any thread, but should only be called once. Note the thread
* this is called on will be the thread that runs the native code's static initializers.
* See the comment in doInBackground() for more considerations on this.
*
- * @param context The context the code is running, or null if it doesn't have one.
- * @param shouldDeleteFallbackLibraries The flag tells whether the method
- * should delete the old fallback libraries or not.
+ * @param context The context the code is running.
*
* @throws ProcessInitException if the native library failed to load.
*/
- public void loadNow(Context context, boolean shouldDeleteFallbackLibraries)
- throws ProcessInitException {
+ public void loadNow(Context context) throws ProcessInitException {
synchronized (sLock) {
- loadAlreadyLocked(context, shouldDeleteFallbackLibraries);
+ loadAlreadyLocked(context);
}
}
@@ -193,10 +168,9 @@ public class LibraryLoader {
*
* This is done this way, as testing shows that fadvise(FADV_WILLNEED) is
* detrimental to the startup time.
- *
- * @param context the application context.
*/
- public void asyncPrefetchLibrariesToMemory(final Context context) {
+ public void asyncPrefetchLibrariesToMemory() {
+ if (!mPrefetchLibraryHasBeenCalled.compareAndSet(false, true)) return;
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
@@ -213,34 +187,26 @@ public class LibraryLoader {
}
// Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code
- private void loadAlreadyLocked(
- Context context, boolean shouldDeleteFallbackLibraries)
- throws ProcessInitException {
+ private void loadAlreadyLocked(Context context) throws ProcessInitException {
try {
if (!mLoaded) {
assert !mInitialized;
long startTime = SystemClock.uptimeMillis();
- boolean useChromiumLinker = Linker.isUsed();
- boolean fallbackWasUsed = false;
+ Linker linker = Linker.getInstance();
+ boolean useChromiumLinker = linker.isUsed();
if (useChromiumLinker) {
// Determine the APK file path.
- String apkFilePath = null;
- if (context != null) {
- apkFilePath = getLibraryApkPath(context);
- } else {
- Log.w(TAG, "could not check load from APK support due to null context");
- }
-
+ String apkFilePath = getLibraryApkPath(context);
// Load libraries using the Chromium linker.
- Linker.prepareLibraryLoad();
+ linker.prepareLibraryLoad();
for (String library : NativeLibraries.LIBRARIES) {
// Don't self-load the linker. This is because the build system is
// not clever enough to understand that all the libraries packaged
// in the final .apk don't need to be explicitly loaded.
- if (Linker.isChromiumLinkerLibrary(library)) {
+ if (linker.isChromiumLinkerLibrary(library)) {
if (DEBUG) Log.i(TAG, "ignoring self-linker load");
continue;
}
@@ -248,26 +214,11 @@ public class LibraryLoader {
// Determine where the library should be loaded from.
String zipFilePath = null;
String libFilePath = System.mapLibraryName(library);
- if (apkFilePath != null && Linker.isInZipFile()) {
- // The library is in the APK file.
- if (!Linker.checkLibraryIsMappableInApk(apkFilePath, libFilePath)) {
- mLibraryIsMappableInApk = false;
- }
- if (mLibraryIsMappableInApk) {
- // Load directly from the APK.
- zipFilePath = apkFilePath;
- Log.i(TAG, "Loading " + library + " directly from within "
- + apkFilePath);
- } else {
- // Unpack library fallback.
- Log.i(TAG, "Loading " + library
- + " using unpack library fallback from within "
- + apkFilePath);
- libFilePath = LibraryLoaderHelper.buildFallbackLibrary(
- context, library);
- fallbackWasUsed = true;
- Log.i(TAG, "Built fallback library " + libFilePath);
- }
+ if (linker.isInZipFile()) {
+ // Load directly from the APK.
+ zipFilePath = apkFilePath;
+ Log.i(TAG,
+ "Loading " + library + " directly from within " + apkFilePath);
} else {
// The library is in its own file.
Log.i(TAG, "Loading " + library);
@@ -275,7 +226,7 @@ public class LibraryLoader {
// Load the library.
boolean isLoaded = false;
- if (Linker.isUsingBrowserSharedRelros()) {
+ if (linker.isUsingBrowserSharedRelros()) {
mIsUsingBrowserSharedRelros = true;
try {
loadLibrary(zipFilePath, libFilePath);
@@ -283,7 +234,7 @@ public class LibraryLoader {
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Failed to load native library with shared RELRO, "
+ "retrying without");
- Linker.disableSharedRelros();
+ linker.disableSharedRelros();
mLoadAtFixedAddressFailed = true;
}
}
@@ -292,7 +243,7 @@ public class LibraryLoader {
}
}
- Linker.finishLibraryLoad();
+ linker.finishLibraryLoad();
} else {
// Load libraries using the system linker.
for (String library : NativeLibraries.LIBRARIES) {
@@ -300,17 +251,10 @@ public class LibraryLoader {
}
}
- if (!fallbackWasUsed && context != null
- && shouldDeleteFallbackLibraries) {
- LibraryLoaderHelper.deleteLibrariesAsynchronously(
- context, LibraryLoaderHelper.LOAD_FROM_APK_FALLBACK_DIR);
- }
-
long stopTime = SystemClock.uptimeMillis();
+ mLibraryLoadTimeMs = stopTime - startTime;
Log.i(TAG, String.format("Time to load native libraries: %d ms (timestamps %d-%d)",
- stopTime - startTime,
- startTime % 10000,
- stopTime % 10000));
+ mLibraryLoadTimeMs, startTime % 10000, stopTime % 10000));
mLoaded = true;
}
@@ -318,11 +262,9 @@ public class LibraryLoader {
throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_LOAD_FAILED, e);
}
// Check that the version of the library we have loaded matches the version we expect
- Log.i(TAG, String.format(
- "Expected native library version number \"%s\","
- + "actual native library version number \"%s\"",
- NativeLibraries.sVersionNumber,
- nativeGetVersionNumber()));
+ Log.i(TAG, String.format("Expected native library version number \"%s\", "
+ + "actual native library version number \"%s\"",
+ NativeLibraries.sVersionNumber, nativeGetVersionNumber()));
if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) {
throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_WRONG_VERSION);
}
@@ -356,7 +298,7 @@ public class LibraryLoader {
// Load a native shared library with the Chromium linker. If the zip file
// path is not null, the library is loaded directly from the zip file.
private void loadLibrary(@Nullable String zipFilePath, String libFilePath) {
- Linker.loadLibrary(zipFilePath, libFilePath);
+ Linker.getInstance().loadLibrary(zipFilePath, libFilePath);
if (zipFilePath != null) {
mLibraryWasLoadedFromApk = true;
}
@@ -426,26 +368,22 @@ public class LibraryLoader {
// Record Chromium linker histogram state for the main browser process. Called from
// onNativeInitializationComplete().
private void recordBrowserProcessHistogram(Context context) {
- if (Linker.isUsed()) {
+ if (Linker.getInstance().isUsed()) {
nativeRecordChromiumAndroidLinkerBrowserHistogram(mIsUsingBrowserSharedRelros,
- mLoadAtFixedAddressFailed,
- getLibraryLoadFromApkStatus(context));
+ mLoadAtFixedAddressFailed, getLibraryLoadFromApkStatus(context),
+ mLibraryLoadTimeMs);
}
}
// Returns the device's status for loading a library directly from the APK file.
// This method can only be called when the Chromium linker is used.
private int getLibraryLoadFromApkStatus(Context context) {
- assert Linker.isUsed();
+ assert Linker.getInstance().isUsed();
if (mLibraryWasLoadedFromApk) {
return LibraryLoadFromApkStatusCodes.SUCCESSFUL;
}
- if (!mLibraryIsMappableInApk) {
- return LibraryLoadFromApkStatusCodes.USED_UNPACK_LIBRARY_FALLBACK;
- }
-
// There were no libraries to be loaded directly from the APK file.
return LibraryLoadFromApkStatusCodes.UNKNOWN;
}
@@ -456,9 +394,9 @@ public class LibraryLoader {
// RecordChromiumAndroidLinkerRendererHistogram() will record it correctly.
public void registerRendererProcessHistogram(boolean requestedSharedRelro,
boolean loadAtFixedAddressFailed) {
- if (Linker.isUsed()) {
- nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedSharedRelro,
- loadAtFixedAddressFailed);
+ if (Linker.getInstance().isUsed()) {
+ nativeRegisterChromiumAndroidLinkerRendererHistogram(
+ requestedSharedRelro, loadAtFixedAddressFailed, mLibraryLoadTimeMs);
}
}
@@ -485,18 +423,18 @@ public class LibraryLoader {
// Method called to record statistics about the Chromium linker operation for the main
// browser process. Indicates whether the linker attempted relro sharing for the browser,
// and if it did, whether the library failed to load at a fixed address. Also records
- // support for loading a library directly from the APK file.
+ // support for loading a library directly from the APK file, and the number of milliseconds
+ // it took to load the libraries.
private native void nativeRecordChromiumAndroidLinkerBrowserHistogram(
- boolean isUsingBrowserSharedRelros,
- boolean loadAtFixedAddressFailed,
- int libraryLoadFromApkStatus);
+ boolean isUsingBrowserSharedRelros, boolean loadAtFixedAddressFailed,
+ int libraryLoadFromApkStatus, long libraryLoadTime);
// Method called to register (for later recording) statistics about the Chromium linker
// operation for a renderer process. Indicates whether the linker attempted relro sharing,
- // and if it did, whether the library failed to load at a fixed address.
+ // and if it did, whether the library failed to load at a fixed address. Also records the
+ // number of milliseconds it took to load the libraries.
private native void nativeRegisterChromiumAndroidLinkerRendererHistogram(
- boolean requestedSharedRelro,
- boolean loadAtFixedAddressFailed);
+ boolean requestedSharedRelro, boolean loadAtFixedAddressFailed, long libraryLoadTime);
// Get the version of the native library. This is needed so that we can check we
// have the right version before initializing the (rest of the) JNI.

Powered by Google App Engine
This is Rietveld 408576698