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

Unified Diff: chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java

Issue 2179163002: Make HostBrowserClassLoader#getClassLoaderInstance() work if Chrome gets updated (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge branch 'master' into webapk_chrome_updated Created 4 years, 5 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
« no previous file with comments | « chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/DexLoader.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java
index c727d2edc46fa830acc1c43d3a438c3cf0dc5ce2..2b16dd749c02958e0d857a5ce59ced9a8ebb7a29 100644
--- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java
+++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java
@@ -6,7 +6,6 @@ package org.chromium.webapk.shell_apk;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Looper;
import android.util.Log;
@@ -41,6 +40,8 @@ public class HostBrowserClassLoader {
/*
* ClassLoader for WebAPK dex. Static so that the same ClassLoader is used for app's lifetime.
+ * The ClassLoader is re-created if the host browser is upgraded while the WebAPK is still
+ * running.
*/
private static ClassLoader sClassLoader;
@@ -52,8 +53,15 @@ public class HostBrowserClassLoader {
*/
public static ClassLoader getClassLoaderInstance(Context context, String canaryClassName) {
assertRunningOnUiThread();
- if (sClassLoader == null) {
- sClassLoader = createClassLoader(context, canaryClassName);
+ Context remoteContext = WebApkUtils.getHostBrowserContext(context);
+ if (remoteContext == null) {
+ Log.w(TAG, "Failed to get remote context.");
+ return null;
+ }
+
+ if (sClassLoader == null || !canReuseClassLoaderInstance(context, remoteContext)) {
+ sClassLoader =
+ createClassLoader(context, remoteContext, new DexLoader(), canaryClassName);
}
return sClassLoader;
}
@@ -61,16 +69,13 @@ public class HostBrowserClassLoader {
/**
* Creates ClassLoader for WebAPK dex.
* @param context WebAPK's context.
+ * @param remoteContext Host browser's context.
* @param canaryClassName Class to load to check that ClassLoader is valid.
+ * @param dexLoader DexLoader for creating ClassLoader.
* @return The ClassLoader.
*/
- private static ClassLoader createClassLoader(Context context, String canaryClassName) {
- Context remoteContext = WebApkUtils.getHostBrowserContext(context);
- if (remoteContext == null) {
- Log.w(TAG, "Failed to get remote context.");
- return null;
- }
-
+ public static ClassLoader createClassLoader(
+ Context context, Context remoteContext, DexLoader dexLoader, String canaryClassName) {
SharedPreferences preferences =
context.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE);
@@ -82,14 +87,27 @@ public class HostBrowserClassLoader {
File localDexDir = context.getDir("dex", Context.MODE_PRIVATE);
if (newRuntimeDexVersion != runtimeDexVersion) {
Log.w(TAG, "Delete cached dex files.");
- DexLoader.deleteCachedDexes(localDexDir);
+ dexLoader.deleteCachedDexes(localDexDir);
}
String dexAssetName = WebApkVersionUtils.getRuntimeDexName(newRuntimeDexVersion);
File remoteDexFile =
new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), dexAssetName);
- return DexLoader.load(remoteContext, dexAssetName, canaryClassName,
- remoteDexFile, localDexDir);
+ return dexLoader.load(
+ remoteContext, dexAssetName, canaryClassName, remoteDexFile, localDexDir);
+ }
+
+ /**
+ * Returns whether {@link sClassLoader} can be reused.
+ */
+ public static boolean canReuseClassLoaderInstance(Context context, Context remoteContext) {
+ // WebAPK may still be running when the host browser gets upgraded. Prevent ClassLoader from
+ // getting reused in this scenario.
+ SharedPreferences preferences =
+ context.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE);
+ int cachedRemoteVersionCode = preferences.getInt(REMOTE_VERSION_CODE_PREF, -1);
+ int remoteVersionCode = getVersionCode(remoteContext);
+ return remoteVersionCode == cachedRemoteVersionCode;
}
/**
@@ -104,29 +122,35 @@ public class HostBrowserClassLoader {
// The "runtime dex" version only changes when {@link remoteContext}'s APK version code
// changes. Checking the APK's version code is less expensive than reading from the APK's
// assets.
- PackageInfo remotePackageInfo = null;
- try {
- remotePackageInfo = remoteContext.getPackageManager().getPackageInfo(
- remoteContext.getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Failed to get remote package info.");
- return -1;
- }
-
+ int remoteVersionCode = getVersionCode(remoteContext);
int cachedRemoteVersionCode = preferences.getInt(REMOTE_VERSION_CODE_PREF, -1);
- if (cachedRemoteVersionCode == remotePackageInfo.versionCode) {
+ if (cachedRemoteVersionCode == remoteVersionCode) {
return -1;
}
int runtimeDexVersion = readAssetContentsToInt(remoteContext, "webapk_dex_version.txt");
SharedPreferences.Editor editor = preferences.edit();
- editor.putInt(REMOTE_VERSION_CODE_PREF, remotePackageInfo.versionCode);
+ editor.putInt(REMOTE_VERSION_CODE_PREF, remoteVersionCode);
editor.putInt(RUNTIME_DEX_VERSION_PREF, runtimeDexVersion);
editor.apply();
return runtimeDexVersion;
}
/**
+ * Returns version code of {@link context}'s APK.
+ */
+ private static int getVersionCode(Context context) {
+ try {
+ return context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), 0)
+ .versionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Failed to get remote package info.");
+ }
+ return -1;
+ }
+
+ /**
* Returns the first integer in an asset file's contents.
* @param context
* @param assetName The name of the asset.
« no previous file with comments | « chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/DexLoader.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698