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 |
| 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 |