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

Side by Side Diff: chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.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
« no previous file with comments | « chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/MainActivity.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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; 7 import android.app.Service;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.Intent; 9 import android.content.Intent;
10 import android.content.SharedPreferences;
11 import android.content.pm.PackageInfo;
12 import android.content.pm.PackageManager;
13 import android.os.Bundle; 10 import android.os.Bundle;
14 import android.os.IBinder; 11 import android.os.IBinder;
15 import android.util.Log; 12 import android.util.Log;
16 13
17 import org.chromium.webapk.lib.common.WebApkUtils; 14 import org.chromium.webapk.lib.common.WebApkUtils;
18 15
19 import java.io.File;
20 import java.lang.reflect.Constructor; 16 import java.lang.reflect.Constructor;
21 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 * Shell class for services provided by WebAPK to Chrome. Extracts code with imp lementation of
25 * services from .dex file in Chrome APK. 20 * services from .dex file in Chrome APK.
26 */ 21 */
27 public class WebApkServiceFactory extends Service { 22 public class WebApkServiceFactory extends Service {
28 private static final String TAG = "cr_WebApkServiceFactory"; 23 private static final String TAG = "cr_WebApkServiceFactory";
29 24
30 /** 25 /**
31 * Name of the class with IBinder API implementation. 26 * Name of the class with IBinder API implementation.
32 */ 27 */
33 private static final String WEBAPK_SERVICE_IMPL_CLASS_NAME = 28 private static final String WEBAPK_SERVICE_IMPL_CLASS_NAME =
34 "org.chromium.webapk.lib.runtime_library.WebApkServiceImpl"; 29 "org.chromium.webapk.lib.runtime_library.WebApkServiceImpl";
35 30
36 /** 31 /**
37 * Name of the shared preferences file.
38 */
39 private static final String PREF_PACKAGE = "org.chromium.webapk.shell_apk";
40
41 /**
42 * Name of the shared preference for Chrome's version code.
43 */
44 private static final String REMOTE_VERSION_CODE_PREF =
45 "org.chromium.webapk.shell_apk.version_code";
46
47 /**
48 * Name of the shared preference for the version number of the dynamically l oaded dex.
49 */
50 private static final String RUNTIME_DEX_VERSION_PREF =
51 "org.chromium.webapk.shell_apk.dex_version";
52
53 /**
54 * Key for passing id of icon to represent WebAPK notifications in status ba r. 32 * Key for passing id of icon to represent WebAPK notifications in status ba r.
55 */ 33 */
56 private static final String KEY_SMALL_ICON_ID = "small_icon_id"; 34 private static final String KEY_SMALL_ICON_ID = "small_icon_id";
57 35
58 /** 36 /**
59 * Key for passing package name of only process allowed to call the service' s methods. 37 * Key for passing package name of only process allowed to call the service' s methods.
60 */ 38 */
61 private static final String KEY_HOST_BROWSER_PACKAGE = "host_browser_package "; 39 private static final String KEY_HOST_BROWSER_PACKAGE = "host_browser_package ";
62 40
63 /*
64 * ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}. Static so that all
65 * {@link WebApkServiceFactory} service instatiations use the same ClassLoad er during the app's
66 * lifetime.
67 */
68 private static ClassLoader sClassLoader;
69
70 @Override 41 @Override
71 public IBinder onBind(Intent intent) { 42 public IBinder onBind(Intent intent) {
72 ClassLoader webApkClassLoader = getClassLoaderInstance(this); 43 ClassLoader webApkClassLoader =
44 HostBrowserClassLoader.getClassLoaderInstance(this, WEBAPK_SERVI CE_IMPL_CLASS_NAME);
73 if (webApkClassLoader == null) { 45 if (webApkClassLoader == null) {
74 Log.w(TAG, "Unable to create ClassLoader."); 46 Log.w(TAG, "Unable to create ClassLoader.");
75 return null; 47 return null;
76 } 48 }
77 49
78 try { 50 try {
79 Class<?> webApkServiceImplClass = 51 Class<?> webApkServiceImplClass =
80 webApkClassLoader.loadClass(WEBAPK_SERVICE_IMPL_CLASS_NAME); 52 webApkClassLoader.loadClass(WEBAPK_SERVICE_IMPL_CLASS_NAME);
81 Constructor<?> webApkServiceImplConstructor = 53 Constructor<?> webApkServiceImplConstructor =
82 webApkServiceImplClass.getConstructor(Context.class, Bundle. class); 54 webApkServiceImplClass.getConstructor(Context.class, Bundle. class);
83 String hostPackageName = WebApkUtils.getHostBrowserPackageName(this) ; 55 String hostPackageName = WebApkUtils.getHostBrowserPackageName(this) ;
84 Bundle bundle = new Bundle(); 56 Bundle bundle = new Bundle();
85 bundle.putInt(KEY_SMALL_ICON_ID, R.drawable.app_icon); 57 bundle.putInt(KEY_SMALL_ICON_ID, R.drawable.app_icon);
86 bundle.putString(KEY_HOST_BROWSER_PACKAGE, hostPackageName); 58 bundle.putString(KEY_HOST_BROWSER_PACKAGE, hostPackageName);
87 return (IBinder) webApkServiceImplConstructor.newInstance(new Object [] {this, bundle}); 59 return (IBinder) webApkServiceImplConstructor.newInstance(new Object [] {this, bundle});
88 } catch (Exception e) { 60 } catch (Exception e) {
89 Log.w(TAG, "Unable to create WebApkServiceImpl."); 61 Log.w(TAG, "Unable to create WebApkServiceImpl.");
90 e.printStackTrace(); 62 e.printStackTrace();
91 return null; 63 return null;
92 } 64 }
93 } 65 }
94
95 /**
96 * Gets / creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_N AME}.
97 * @param context WebAPK's context.
98 * @return The ClassLoader.
99 */
100 private static ClassLoader getClassLoaderInstance(Context context) {
101 if (sClassLoader == null) {
102 sClassLoader = createClassLoader(context);
103 }
104 return sClassLoader;
105 }
106
107 /**
108 * Creates ClassLoader for loading {@link WEBAPK_SERVICE_IMPL_CLASS_NAME}.
109 * @param context WebAPK's context.
110 * @return The ClassLoader.
111 */
112 private static ClassLoader createClassLoader(Context context) {
113 Context remoteContext = WebApkUtils.getHostBrowserContext(context);
114 if (remoteContext == null) {
115 Log.w(TAG, "Failed to get remote context.");
116 return null;
117 }
118
119 SharedPreferences preferences = context.getSharedPreferences(PREF_PACKAG E, MODE_PRIVATE);
120
121 int runtimeDexVersion = preferences.getInt(RUNTIME_DEX_VERSION_PREF, -1) ;
122 int newRuntimeDexVersion = checkForNewRuntimeDexVersion(preferences, rem oteContext);
123 if (newRuntimeDexVersion == -1) {
124 newRuntimeDexVersion = runtimeDexVersion;
125 }
126 File localDexDir = context.getDir("dex", Context.MODE_PRIVATE);
127 if (newRuntimeDexVersion != runtimeDexVersion) {
128 Log.w(TAG, "Delete cached dex files.");
129 DexLoader.deleteCachedDexes(localDexDir);
130 }
131
132 String dexAssetName = WebApkUtils.getRuntimeDexName(newRuntimeDexVersion );
133 File remoteDexFile =
134 new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), dexA ssetName);
135 return DexLoader.load(remoteContext, dexAssetName, WEBAPK_SERVICE_IMPL_C LASS_NAME,
136 remoteDexFile, localDexDir);
137 }
138
139 /**
140 * Checks if there is a new "runtime dex" version number. If there is a new version number,
141 * updates SharedPreferences.
142 * @param preferences WebAPK's SharedPreferences.
143 * @param remoteContext
144 * @return The new "runtime dex" version number. -1 if there is no new versi on number.
145 */
146 private static int checkForNewRuntimeDexVersion(
147 SharedPreferences preferences, Context remoteContext) {
148 // The "runtime dex" version only changes when {@link remoteContext}'s A PK version code
149 // changes. Checking the APK's version code is less expensive than readi ng from the APK's
150 // assets.
151 PackageInfo remotePackageInfo = null;
152 try {
153 remotePackageInfo = remoteContext.getPackageManager().getPackageInfo (
154 remoteContext.getPackageName(), 0);
155 } catch (PackageManager.NameNotFoundException e) {
156 Log.e(TAG, "Failed to get remote package info.");
157 return -1;
158 }
159
160 int cachedRemoteVersionCode = preferences.getInt(REMOTE_VERSION_CODE_PRE F, -1);
161 if (cachedRemoteVersionCode == remotePackageInfo.versionCode) {
162 return -1;
163 }
164
165 int runtimeDexVersion = readAssetContentsToInt(remoteContext, "webapk_de x_version.txt");
166 SharedPreferences.Editor editor = preferences.edit();
167 editor.putInt(REMOTE_VERSION_CODE_PREF, remotePackageInfo.versionCode);
168 editor.putInt(RUNTIME_DEX_VERSION_PREF, runtimeDexVersion);
169 editor.apply();
170 return runtimeDexVersion;
171 }
172
173 /**
174 * Returns the first integer in an asset file's contents.
175 * @param context
176 * @param assetName The name of the asset.
177 * @return The first integer.
178 */
179 private static int readAssetContentsToInt(Context context, String assetName) {
180 Scanner scanner = null;
181 int value = -1;
182 try {
183 scanner = new Scanner(context.getAssets().open(assetName));
184 value = scanner.nextInt();
185 scanner.close();
186 } catch (Exception e) {
187 } finally {
188 if (scanner != null) {
189 try {
190 scanner.close();
191 } catch (Exception e) {
192 }
193 }
194 }
195 return value;
196 }
197 } 66 }
OLDNEW
« no previous file with comments | « chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/MainActivity.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698