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

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

Issue 2101433002: WebAPK: Move MainActivity#onCreate() to runtime library (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge branch 'master' into webapk_more_meta2_loader 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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.webapk.shell_apk; 5 package org.chromium.webapk.shell_apk;
6 6
7 import android.app.Service;
8 import android.content.Context; 7 import android.content.Context;
9 import android.content.Intent;
10 import android.content.SharedPreferences; 8 import android.content.SharedPreferences;
11 import android.content.pm.PackageInfo; 9 import android.content.pm.PackageInfo;
12 import android.content.pm.PackageManager; 10 import android.content.pm.PackageManager;
13 import android.os.Bundle;
14 import android.os.IBinder;
15 import android.util.Log; 11 import android.util.Log;
16 12
17 import org.chromium.webapk.lib.common.WebApkUtils; 13 import org.chromium.webapk.lib.common.WebApkUtils;
18 14
19 import java.io.File; 15 import java.io.File;
20 import java.lang.reflect.Constructor;
21 import java.util.Scanner; 16 import java.util.Scanner;
22 17
23 /** 18 /**
24 * Shell class for services provided by WebAPK to Chrome. Extracts code with imp lementation of 19 * Creates ClassLoader for WebAPK-specific dex file in Chrome APK's assets.
25 * services from .dex file in Chrome APK.
26 */ 20 */
27 public class WebApkServiceFactory extends Service { 21 public class HostBrowserClassLoader {
28 private static final String TAG = "cr_WebApkServiceFactory"; 22 private static final String TAG = "cr_HostBrowserClassLoader";
29
30 /**
31 * Name of the class with IBinder API implementation.
32 */
33 private static final String WEBAPK_SERVICE_IMPL_CLASS_NAME =
34 "org.chromium.webapk.lib.runtime_library.WebApkServiceImpl";
35 23
36 /** 24 /**
37 * Name of the shared preferences file. 25 * Name of the shared preferences file.
38 */ 26 */
39 private static final String PREF_PACKAGE = "org.chromium.webapk.shell_apk"; 27 private static final String PREF_PACKAGE = "org.chromium.webapk.shell_apk";
40 28
41 /** 29 /**
42 * Name of the shared preference for Chrome's version code. 30 * Name of the shared preference for Chrome's version code.
43 */ 31 */
44 private static final String REMOTE_VERSION_CODE_PREF = 32 private static final String REMOTE_VERSION_CODE_PREF =
45 "org.chromium.webapk.shell_apk.version_code"; 33 "org.chromium.webapk.shell_apk.version_code";
46 34
47 /** 35 /**
48 * Name of the shared preference for the version number of the dynamically l oaded dex. 36 * Name of the shared preference for the version number of the dynamically l oaded dex.
49 */ 37 */
50 private static final String RUNTIME_DEX_VERSION_PREF = 38 private static final String RUNTIME_DEX_VERSION_PREF =
51 "org.chromium.webapk.shell_apk.dex_version"; 39 "org.chromium.webapk.shell_apk.dex_version";
52 40
53 /**
54 * Key for passing id of icon to represent WebAPK notifications in status ba r.
55 */
56 private static final String KEY_SMALL_ICON_ID = "small_icon_id";
57
58 /**
59 * Key for passing package name of only process allowed to call the service' s methods.
60 */
61 private static final String KEY_HOST_BROWSER_PACKAGE = "host_browser_package ";
62
63 /* 41 /*
64 * ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}. Static so that all 42 * ClassLoader for WebAPK dex. Static so that the same ClassLoader is used f or app's lifetime.
65 * {@link WebApkServiceFactory} service instatiations use the same ClassLoad er during the app's
66 * lifetime.
67 */ 43 */
68 private static ClassLoader sClassLoader; 44 private static ClassLoader sClassLoader;
69 45
70 @Override 46 /**
71 public IBinder onBind(Intent intent) { 47 * Guards all access to {@link sClassLoader}.
72 ClassLoader webApkClassLoader = getClassLoaderInstance(this); 48 */
73 if (webApkClassLoader == null) { 49 private static final Object sLock = new Object();
74 Log.w(TAG, "Unable to create ClassLoader.");
75 return null;
76 }
77
78 try {
79 Class<?> webApkServiceImplClass =
80 webApkClassLoader.loadClass(WEBAPK_SERVICE_IMPL_CLASS_NAME);
81 Constructor<?> webApkServiceImplConstructor =
82 webApkServiceImplClass.getConstructor(Context.class, Bundle. class);
83 String hostPackageName = WebApkUtils.getHostBrowserPackageName(this) ;
84 Bundle bundle = new Bundle();
85 bundle.putInt(KEY_SMALL_ICON_ID, R.drawable.app_icon);
86 bundle.putString(KEY_HOST_BROWSER_PACKAGE, hostPackageName);
87 return (IBinder) webApkServiceImplConstructor.newInstance(new Object [] {this, bundle});
88 } catch (Exception e) {
89 Log.w(TAG, "Unable to create WebApkServiceImpl.");
90 e.printStackTrace();
91 return null;
92 }
93 }
94 50
95 /** 51 /**
96 * Gets / creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_N AME}. 52 * Gets / creates ClassLoader for WebAPK dex.
97 * @param context WebAPK's context. 53 * @param context WebAPK's context.
54 * @param canaryClassname Class to load to check that ClassLoader is valid.
98 * @return The ClassLoader. 55 * @return The ClassLoader.
99 */ 56 */
100 private static ClassLoader getClassLoaderInstance(Context context) { 57 public static ClassLoader getClassLoaderInstance(Context context, String can aryClassName) {
101 if (sClassLoader == null) { 58 synchronized (sLock) {
102 sClassLoader = createClassLoader(context); 59 if (sClassLoader == null) {
60 sClassLoader = createClassLoader(context, canaryClassName);
61 }
103 } 62 }
104 return sClassLoader; 63 return sClassLoader;
105 } 64 }
106 65
107 /** 66 /**
108 * Creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}. 67 * Creates ClassLoader for WebAPK dex.
109 * @param context WebAPK's context. 68 * @param context WebAPK's context.
69 * @param canaryClassName Class to load to check that ClassLoader is valid.
110 * @return The ClassLoader. 70 * @return The ClassLoader.
111 */ 71 */
112 private static ClassLoader createClassLoader(Context context) { 72 private static ClassLoader createClassLoader(Context context, String canaryC lassName) {
113 Context remoteContext = WebApkUtils.getHostBrowserContext(context); 73 Context remoteContext = WebApkUtils.getHostBrowserContext(context);
114 if (remoteContext == null) { 74 if (remoteContext == null) {
115 Log.w(TAG, "Failed to get remote context."); 75 Log.w(TAG, "Failed to get remote context.");
116 return null; 76 return null;
117 } 77 }
118 78
119 SharedPreferences preferences = context.getSharedPreferences(PREF_PACKAG E, MODE_PRIVATE); 79 SharedPreferences preferences =
80 context.getSharedPreferences(PREF_PACKAGE, Context.MODE_PRIVATE) ;
120 81
121 int runtimeDexVersion = preferences.getInt(RUNTIME_DEX_VERSION_PREF, -1) ; 82 int runtimeDexVersion = preferences.getInt(RUNTIME_DEX_VERSION_PREF, -1) ;
122 int newRuntimeDexVersion = checkForNewRuntimeDexVersion(preferences, rem oteContext); 83 int newRuntimeDexVersion = checkForNewRuntimeDexVersion(preferences, rem oteContext);
123 if (newRuntimeDexVersion == -1) { 84 if (newRuntimeDexVersion == -1) {
124 newRuntimeDexVersion = runtimeDexVersion; 85 newRuntimeDexVersion = runtimeDexVersion;
125 } 86 }
126 File localDexDir = context.getDir("dex", Context.MODE_PRIVATE); 87 File localDexDir = context.getDir("dex", Context.MODE_PRIVATE);
127 if (newRuntimeDexVersion != runtimeDexVersion) { 88 if (newRuntimeDexVersion != runtimeDexVersion) {
128 Log.w(TAG, "Delete cached dex files."); 89 Log.w(TAG, "Delete cached dex files.");
129 DexLoader.deleteCachedDexes(localDexDir); 90 DexLoader.deleteCachedDexes(localDexDir);
130 } 91 }
131 92
132 String dexAssetName = WebApkUtils.getRuntimeDexName(newRuntimeDexVersion ); 93 String dexAssetName = WebApkUtils.getRuntimeDexName(newRuntimeDexVersion );
133 File remoteDexFile = 94 File remoteDexFile =
134 new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), dexA ssetName); 95 new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), dexA ssetName);
135 return DexLoader.load(remoteContext, dexAssetName, WEBAPK_SERVICE_IMPL_C LASS_NAME, 96 return DexLoader.load(remoteContext, dexAssetName, canaryClassName,
136 remoteDexFile, localDexDir); 97 remoteDexFile, localDexDir);
137 } 98 }
138 99
139 /** 100 /**
140 * Checks if there is a new "runtime dex" version number. If there is a new version number, 101 * Checks if there is a new "runtime dex" version number. If there is a new version number,
141 * updates SharedPreferences. 102 * updates SharedPreferences.
142 * @param preferences WebAPK's SharedPreferences. 103 * @param preferences WebAPK's SharedPreferences.
143 * @param remoteContext 104 * @param remoteContext
144 * @return The new "runtime dex" version number. -1 if there is no new versi on number. 105 * @return The new "runtime dex" version number. -1 if there is no new versi on number.
145 */ 106 */
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 if (scanner != null) { 149 if (scanner != null) {
189 try { 150 try {
190 scanner.close(); 151 scanner.close();
191 } catch (Exception e) { 152 } catch (Exception e) {
192 } 153 }
193 } 154 }
194 } 155 }
195 return value; 156 return value;
196 } 157 }
197 } 158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698