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/WebApkServiceFactory.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java |
similarity index 62% |
copy from chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java |
copy to chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java |
index dced85dffd9d46dd19470510aab66dac358c98dc..e73754c165357e75e8e7cba61f85218b34c82943 100644 |
--- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java |
+++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java |
@@ -4,34 +4,22 @@ |
package org.chromium.webapk.shell_apk; |
-import android.app.Service; |
import android.content.Context; |
-import android.content.Intent; |
import android.content.SharedPreferences; |
import android.content.pm.PackageInfo; |
import android.content.pm.PackageManager; |
-import android.os.Bundle; |
-import android.os.IBinder; |
import android.util.Log; |
import org.chromium.webapk.lib.common.WebApkUtils; |
import java.io.File; |
-import java.lang.reflect.Constructor; |
import java.util.Scanner; |
/** |
- * Shell class for services provided by WebAPK to Chrome. Extracts code with implementation of |
- * services from .dex file in Chrome APK. |
+ * Creates ClassLoader for WebAPK-specific dex file in Chrome APK's assets. |
*/ |
-public class WebApkServiceFactory extends Service { |
- private static final String TAG = "cr_WebApkServiceFactory"; |
- |
- /** |
- * Name of the class with IBinder API implementation. |
- */ |
- private static final String WEBAPK_SERVICE_IMPL_CLASS_NAME = |
- "org.chromium.webapk.lib.runtime_library.WebApkServiceImpl"; |
+public class HostBrowserClassLoader { |
+ private static final String TAG = "cr_HostBrowserClassLoader"; |
/** |
* Name of the shared preferences file. |
@@ -50,73 +38,46 @@ public class WebApkServiceFactory extends Service { |
private static final String RUNTIME_DEX_VERSION_PREF = |
"org.chromium.webapk.shell_apk.dex_version"; |
- /** |
- * Key for passing id of icon to represent WebAPK notifications in status bar. |
- */ |
- private static final String KEY_SMALL_ICON_ID = "small_icon_id"; |
- |
- /** |
- * Key for passing package name of only process allowed to call the service's methods. |
- */ |
- private static final String KEY_HOST_BROWSER_PACKAGE = "host_browser_package"; |
- |
/* |
- * ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}. Static so that all |
- * {@link WebApkServiceFactory} service instatiations use the same ClassLoader during the app's |
- * lifetime. |
+ * ClassLoader for WebAPK dex. Static so that the same ClassLoader is used for app's lifetime. |
*/ |
private static ClassLoader sClassLoader; |
- @Override |
- public IBinder onBind(Intent intent) { |
- ClassLoader webApkClassLoader = getClassLoaderInstance(this); |
- if (webApkClassLoader == null) { |
- Log.w(TAG, "Unable to create ClassLoader."); |
- return null; |
- } |
- |
- try { |
- Class<?> webApkServiceImplClass = |
- webApkClassLoader.loadClass(WEBAPK_SERVICE_IMPL_CLASS_NAME); |
- Constructor<?> webApkServiceImplConstructor = |
- webApkServiceImplClass.getConstructor(Context.class, Bundle.class); |
- String hostPackageName = WebApkUtils.getHostBrowserPackageName(this); |
- Bundle bundle = new Bundle(); |
- bundle.putInt(KEY_SMALL_ICON_ID, R.drawable.app_icon); |
- bundle.putString(KEY_HOST_BROWSER_PACKAGE, hostPackageName); |
- return (IBinder) webApkServiceImplConstructor.newInstance(new Object[] {this, bundle}); |
- } catch (Exception e) { |
- Log.w(TAG, "Unable to create WebApkServiceImpl."); |
- e.printStackTrace(); |
- return null; |
- } |
- } |
+ /** |
+ * Guards all access to {@link sClassLoader}. |
+ */ |
+ private static final Object sLock = new Object(); |
/** |
- * Gets / creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}. |
+ * Gets / creates ClassLoader for WebAPK dex. |
* @param context WebAPK's context. |
+ * @param canaryClassname Class to load to check that ClassLoader is valid. |
* @return The ClassLoader. |
*/ |
- private static ClassLoader getClassLoaderInstance(Context context) { |
- if (sClassLoader == null) { |
- sClassLoader = createClassLoader(context); |
+ public static ClassLoader getClassLoaderInstance(Context context, String canaryClassName) { |
+ synchronized (sLock) { |
+ if (sClassLoader == null) { |
+ sClassLoader = createClassLoader(context, canaryClassName); |
+ } |
} |
return sClassLoader; |
} |
/** |
- * Creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}. |
+ * Creates ClassLoader for WebAPK dex. |
* @param context WebAPK's context. |
+ * @param canaryClassName Class to load to check that ClassLoader is valid. |
* @return The ClassLoader. |
*/ |
- private static ClassLoader createClassLoader(Context context) { |
+ 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; |
} |
- SharedPreferences preferences = context.getSharedPreferences(PREF_PACKAGE, MODE_PRIVATE); |
+ SharedPreferences preferences = |
+ context.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE); |
int runtimeDexVersion = preferences.getInt(RUNTIME_DEX_VERSION_PREF, -1); |
int newRuntimeDexVersion = checkForNewRuntimeDexVersion(preferences, remoteContext); |
@@ -132,7 +93,7 @@ public class WebApkServiceFactory extends Service { |
String dexAssetName = WebApkUtils.getRuntimeDexName(newRuntimeDexVersion); |
File remoteDexFile = |
new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), dexAssetName); |
- return DexLoader.load(remoteContext, dexAssetName, WEBAPK_SERVICE_IMPL_CLASS_NAME, |
+ return DexLoader.load(remoteContext, dexAssetName, canaryClassName, |
remoteDexFile, localDexDir); |
} |