Chromium Code Reviews| 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.SharedPreferences; | |
| 9 import android.content.pm.ApplicationInfo; | 10 import android.content.pm.ApplicationInfo; |
| 10 import android.content.pm.PackageInfo; | 11 import android.content.pm.PackageInfo; |
| 11 import android.content.pm.PackageManager.NameNotFoundException; | 12 import android.content.pm.PackageManager.NameNotFoundException; |
| 12 import android.os.AsyncTask; | 13 import android.os.AsyncTask; |
| 13 import android.os.Build; | 14 import android.os.Build; |
| 14 import android.os.SystemClock; | 15 import android.os.SystemClock; |
| 15 | 16 |
| 16 import org.chromium.base.CommandLine; | 17 import org.chromium.base.CommandLine; |
| 17 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
| 18 import org.chromium.base.PackageUtils; | 19 import org.chromium.base.PackageUtils; |
| 19 import org.chromium.base.TraceEvent; | 20 import org.chromium.base.TraceEvent; |
| 20 import org.chromium.base.annotations.CalledByNative; | 21 import org.chromium.base.annotations.CalledByNative; |
| 21 import org.chromium.base.annotations.JNINamespace; | 22 import org.chromium.base.annotations.JNINamespace; |
| 22 import org.chromium.base.metrics.RecordHistogram; | 23 import org.chromium.base.metrics.RecordHistogram; |
| 23 | 24 |
| 24 import java.io.File; | |
| 25 import java.util.concurrent.atomic.AtomicBoolean; | 25 import java.util.concurrent.atomic.AtomicBoolean; |
| 26 | 26 |
| 27 import javax.annotation.Nullable; | 27 import javax.annotation.Nullable; |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * This class provides functionality to load and register the native libraries. | 30 * This class provides functionality to load and register the native libraries. |
| 31 * Callers are allowed to separate loading the libraries from initializing them. | 31 * Callers are allowed to separate loading the libraries from initializing them. |
| 32 * This may be an advantage for Android Webview, where the libraries can be load ed | 32 * This may be an advantage for Android Webview, where the libraries can be load ed |
| 33 * by the zygote process, but then needs per process initialization after the | 33 * by the zygote process, but then needs per process initialization after the |
| 34 * application processes are forked from the zygote process. | 34 * application processes are forked from the zygote process. |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 // in the final .apk don't need to be explicitly loaded. | 252 // in the final .apk don't need to be explicitly loaded. |
| 253 if (linker.isChromiumLinkerLibrary(library)) { | 253 if (linker.isChromiumLinkerLibrary(library)) { |
| 254 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); | 254 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); |
| 255 continue; | 255 continue; |
| 256 } | 256 } |
| 257 | 257 |
| 258 // Determine where the library should be loaded from. | 258 // Determine where the library should be loaded from. |
| 259 String zipFilePath = null; | 259 String zipFilePath = null; |
| 260 String libFilePath = System.mapLibraryName(library); | 260 String libFilePath = System.mapLibraryName(library); |
| 261 if (Linker.isInZipFile()) { | 261 if (Linker.isInZipFile()) { |
| 262 SharedPreferences prefs = context.getSharedPreferenc es( | |
| 263 "MINT_PREFS", Context.MODE_PRIVATE); | |
| 264 String packageString = prefs.getString("CHROME_PACK AGE_PREF", | |
| 265 DEFAULT_CHROME_PACKAGE_NAME); | |
| 266 Context remoteContext = context; | |
| 267 if (mLibraryProcessType == LibraryProcessType.PROCES S_CHILD | |
| 268 && !context.getPackageName().equals(packageS tring)) { | |
| 269 try { | |
| 270 // Construct the context of the WebAPK host, which has native | |
| 271 // libraries that the WebAPK. | |
| 272 Log.w(TAG, "package name from context: %s", | |
| 273 context.getPackageName()); | |
| 274 remoteContext = | |
| 275 context.getApplicationContext().crea tePackageContext( | |
| 276 packageString, | |
| 277 Context.CONTEXT_IGNORE_SECUR ITY | |
| 278 | Context.CONTEXT_INCLUDE_CO DE); | |
| 279 } catch (NameNotFoundException e) { | |
| 280 e.printStackTrace(); | |
| 281 } | |
| 282 } | |
| 262 // Load directly from the APK. | 283 // Load directly from the APK. |
| 263 zipFilePath = getLibraryApkPath(context); | 284 zipFilePath = getLibraryApkPath(remoteContext); |
| 264 Log.i(TAG, "Loading " + library + " from within " + zipFilePath); | 285 Log.i(TAG, "Loading " + library + " from within " + zipFilePath); |
| 265 } else { | 286 } else { |
| 266 // The library is in its own file. | 287 // The library is in its own file. |
| 267 Log.i(TAG, "Loading " + library); | 288 Log.i(TAG, "Loading " + library); |
| 268 } | 289 } |
| 269 | 290 |
| 270 // Load the library using this Linker. May throw Unsatis fiedLinkError. | 291 // Load the library using this Linker. May throw Unsatis fiedLinkError. |
| 271 loadLibrary(linker, zipFilePath, libFilePath); | 292 loadLibrary(linker, zipFilePath, libFilePath); |
| 272 } | 293 } |
| 273 | 294 |
| 274 linker.finishLibraryLoad(); | 295 linker.finishLibraryLoad(); |
| 275 } else { | 296 } else { |
| 276 // TODO(yfriedman): Extract library for Chrome to depend on when using Minted | 297 // Load libraries using the system linker. |
| 277 // APKs. This should come from that library instead of readi ng the same shared | 298 for (String library : NativeLibraries.LIBRARIES) { |
| 278 // prefs. | 299 System.loadLibrary(library); |
| 279 String packageString = | |
| 280 context.getSharedPreferences(MINT_PREFS, Context.MOD E_PRIVATE) | |
| 281 .getString(CHROME_PACKAGE_PREF, DEFAULT_CHROME_PACKA GE_NAME); | |
| 282 | |
| 283 if (mLibraryProcessType == LibraryProcessType.PROCESS_CHILD | |
| 284 && !context.getPackageName().equals(packageString)) { | |
| 285 Context remoteContext = null; | |
| 286 try { | |
| 287 Log.w(TAG, "package name from context: %s", context. getPackageName()); | |
| 288 remoteContext = context.getApplicationContext().crea tePackageContext( | |
| 289 packageString, | |
| 290 Context.CONTEXT_IGNORE_SECURITY | Context.CONT EXT_INCLUDE_CODE); | |
| 291 } catch (NameNotFoundException e1) { | |
| 292 e1.printStackTrace(); | |
| 293 } | |
| 294 File input = new File(remoteContext.getApplicationInfo() .nativeLibraryDir); | |
| 295 Log.w(TAG, "load native libraries from remote context: " | |
| 296 + input.getAbsolutePath()); | |
| 297 for (String library : NativeLibraries.LIBRARIES) { | |
| 298 System.load(input.getAbsolutePath() + "/lib" + libra ry + ".so"); | |
| 299 } | |
| 300 } else { | |
| 301 // Load libraries using the system linker. | |
| 302 for (String library : NativeLibraries.LIBRARIES) { | |
| 303 System.loadLibrary(library); | |
| 304 } | |
| 305 } | 300 } |
| 306 } | 301 } |
| 307 | 302 |
| 308 long stopTime = SystemClock.uptimeMillis(); | 303 long stopTime = SystemClock.uptimeMillis(); |
| 309 mLibraryLoadTimeMs = stopTime - startTime; | 304 mLibraryLoadTimeMs = stopTime - startTime; |
| 310 Log.i(TAG, String.format("Time to load native libraries: %d ms ( timestamps %d-%d)", | 305 Log.i(TAG, String.format("Time to load native libraries: %d ms ( timestamps %d-%d)", |
| 311 mLibraryLoadTimeMs, | 306 mLibraryLoadTimeMs, |
| 312 startTime % 10000, | 307 startTime % 10000, |
| 313 stopTime % 10000)); | 308 stopTime % 10000)); |
| 314 | 309 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 335 } | 330 } |
| 336 | 331 |
| 337 // Returns the path to the .apk that holds the native libraries. | 332 // Returns the path to the .apk that holds the native libraries. |
| 338 // This is either the main .apk, or the abi split apk. | 333 // This is either the main .apk, or the abi split apk. |
| 339 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 334 @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
| 340 private static String getLibraryApkPath(Context context) { | 335 private static String getLibraryApkPath(Context context) { |
| 341 ApplicationInfo appInfo = context.getApplicationInfo(); | 336 ApplicationInfo appInfo = context.getApplicationInfo(); |
| 342 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { | 337 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { |
| 343 return appInfo.sourceDir; | 338 return appInfo.sourceDir; |
| 344 } | 339 } |
| 340 // In minted runtime, getApplicationContext() of its host context return s null, since | |
|
Yaron
2016/02/19 22:10:19
I wonder if this might bite us elsewhere but seems
Xi Han
2016/02/24 19:09:38
Do you know when the splitSourceDirs are used?
Yaron
2016/02/25 05:32:50
It's not used. We thought we'd be using split apks
Xi Han
2016/02/25 14:55:37
Got it. We need to be more careful with dealing wi
| |
| 341 // we use reflection to construct the host's context. In this case, simp ly | |
| 342 // return its host's sourceDir. | |
| 343 if (context.getApplicationContext() == null) { | |
| 344 return appInfo.sourceDir; | |
| 345 } | |
| 345 PackageInfo packageInfo = PackageUtils.getOwnPackageInfo(context); | 346 PackageInfo packageInfo = PackageUtils.getOwnPackageInfo(context); |
| 346 if (packageInfo.splitNames != null) { | 347 if (packageInfo.splitNames != null) { |
| 347 for (int i = 0; i < packageInfo.splitNames.length; ++i) { | 348 for (int i = 0; i < packageInfo.splitNames.length; ++i) { |
| 348 if (isAbiSplit(packageInfo.splitNames[i])) { | 349 if (isAbiSplit(packageInfo.splitNames[i])) { |
| 349 return appInfo.splitSourceDirs[i]; | 350 return appInfo.splitSourceDirs[i]; |
| 350 } | 351 } |
| 351 } | 352 } |
| 352 } | 353 } |
| 353 return appInfo.sourceDir; | 354 return appInfo.sourceDir; |
| 354 } | 355 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 | 498 |
| 498 // Finds the ranges corresponding to the native library pages, forks a new | 499 // Finds the ranges corresponding to the native library pages, forks a new |
| 499 // process to prefetch these pages and waits for it. The new process then | 500 // process to prefetch these pages and waits for it. The new process then |
| 500 // terminates. This is blocking. | 501 // terminates. This is blocking. |
| 501 private static native boolean nativeForkAndPrefetchNativeLibrary(); | 502 private static native boolean nativeForkAndPrefetchNativeLibrary(); |
| 502 | 503 |
| 503 // Returns the percentage of the native library code page that are currently reseident in | 504 // Returns the percentage of the native library code page that are currently reseident in |
| 504 // memory. | 505 // memory. |
| 505 private static native int nativePercentageOfResidentNativeLibraryCode(); | 506 private static native int nativePercentageOfResidentNativeLibraryCode(); |
| 506 } | 507 } |
| OLD | NEW |