| Index: chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.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/WebApkServiceFactory.java
|
| index 9bc602db7669e8b66fb23266a35506ef75c806ff..6513050c52d7f1be52d5745053118c90ea2a41fe 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/WebApkServiceFactory.java
|
| @@ -5,18 +5,86 @@
|
| package org.chromium.webapk.shell_apk;
|
|
|
| import android.app.Service;
|
| +import android.content.Context;
|
| import android.content.Intent;
|
| import android.os.IBinder;
|
| +import android.util.Log;
|
|
|
| -import org.chromium.webapk.lib.runtime_library.WebApkServiceImpl;
|
| +import org.chromium.webapk.lib.common.WebApkUtils;
|
| +
|
| +import java.io.File;
|
| +import java.lang.reflect.Constructor;
|
|
|
| /**
|
| - * Implements services offered by the WebAPK to Chrome.
|
| + * Shell class for services provided by WebAPK to Chrome. Extracts code with implementation of
|
| + * services from .dex file in Chrome APK.
|
| */
|
| 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";
|
| +
|
| + /*
|
| + * 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.
|
| + */
|
| + private static ClassLoader sClassLoader;
|
|
|
| @Override
|
| public IBinder onBind(Intent intent) {
|
| - return new WebApkServiceImpl(this, R.drawable.app_icon);
|
| + 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, int.class);
|
| + return (IBinder) webApkServiceImplConstructor.newInstance(
|
| + new Object[] {this, R.drawable.app_icon});
|
| + } catch (Exception e) {
|
| + Log.w(TAG, "Unable to create WebApkServiceImpl.");
|
| + e.printStackTrace();
|
| + return null;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Gets / creates ClassLaoder for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}.
|
| + * @param context WebAPK's context.
|
| + * @return The ClassLoader.
|
| + */
|
| + private static ClassLoader getClassLoaderInstance(Context context) {
|
| + if (sClassLoader == null) {
|
| + sClassLoader = createClassLoader(context);
|
| + }
|
| + return sClassLoader;
|
| + }
|
| +
|
| + /**
|
| + * Creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}.
|
| + * @param context WebAPK's context.
|
| + * @return The ClassLoader.
|
| + */
|
| + private static ClassLoader createClassLoader(Context context) {
|
| + Context remoteContext = WebApkUtils.getHostBrowserContext(context);
|
| + if (remoteContext == null) {
|
| + Log.w(TAG, "Failed to get remote context.");
|
| + return null;
|
| + }
|
| +
|
| + File localDexDir = context.getDir("dex", Context.MODE_PRIVATE);
|
| + File remoteDexFile =
|
| + new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), "web_apk.dex");
|
| + return DexLoader.load(remoteContext, "web_apk.dex", WEBAPK_SERVICE_IMPL_CLASS_NAME,
|
| + remoteDexFile, localDexDir);
|
| }
|
| }
|
|
|