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

Side by Side Diff: webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java

Issue 1965583002: Move //webapk to //chrome/android/webapk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 | « webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkApplication.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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.webapk.shell_apk;
6
7 import android.app.Service;
8 import android.content.Context;
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;
14 import android.os.IBinder;
15 import android.util.Log;
16
17 import org.chromium.webapk.lib.common.WebApkUtils;
18
19 import java.io.File;
20 import java.lang.reflect.Constructor;
21 import java.util.Scanner;
22
23 /**
24 * Shell class for services provided by WebAPK to Chrome. Extracts code with imp lementation of
25 * services from .dex file in Chrome APK.
26 */
27 public class WebApkServiceFactory extends Service {
28 private static final String TAG = "cr.WebApkServiceFactory";
29
30 /**
31 * Name of the class with IBinder API implementation.
32 */
33 private static final String MINTED_SERVICE_IMPL_CLASS_NAME =
34 "org.chromium.webapk.lib.runtime_library.WebApkServiceImpl";
35
36 private static final String KEY_APP_ICON_ID = "app_icon_id";
37 private static final String KEY_EXPECTED_HOST_BROWSER = "expected_host_brows er";
38
39 /**
40 * Name of the shared preferences file.
41 */
42 private static final String PREF_FILE_NAME = "MINT_PREFS";
43
44 /**
45 * Name of the shared preference for Chrome's version code.
46 */
47 private static final String REMOTE_VERSION_CODE_PREF =
48 "webapk_service_factory_remote_version_code";
49
50 /**
51 * Name of the shared preference for the version number of the dynamically l oaded dex.
52 */
53 private static final String RUNTIME_DEX_VERSION_PREF =
54 "webapk_service_factory_runtime_dex_version";
55
56 /*
57 * ClassLoader for loading {@link MINTED_SERVICE_IMPL_CLASS_NAME}. Static so that all
58 * {@link WebApkServiceFactory} service instatiations use the same ClassLoad er during the app's
59 * lifetime.
60 */
61 private static ClassLoader sClassLoader;
62
63 @Override
64 public IBinder onBind(Intent intent) {
65 if (sClassLoader == null) {
66 sClassLoader = createClassLoader(this);
67 if (sClassLoader == null) {
68 Log.w(TAG, "Unable to create ClassLoader.");
69 return null;
70 }
71 }
72
73 try {
74 Class<?> mintedServiceImplClass =
75 sClassLoader.loadClass(MINTED_SERVICE_IMPL_CLASS_NAME);
76 Constructor<?> mintedServiceImplConstructor =
77 mintedServiceImplClass.getConstructor(Context.class, Bundle. class);
78 String expectedHostPackageName = WebApkUtils.getHostBrowserPackageNa me(this);
79 Bundle bundle = new Bundle();
80 bundle.putInt(KEY_APP_ICON_ID, R.drawable.app_icon);
81 bundle.putString(KEY_EXPECTED_HOST_BROWSER, expectedHostPackageName) ;
82 return (IBinder) mintedServiceImplConstructor.newInstance(new Object [] {this, bundle});
83 } catch (Exception e) {
84 Log.w(TAG, "Unable to create WebApkServiceImpl.");
85 e.printStackTrace();
86 return null;
87 }
88 }
89
90 /**
91 * Creates ClassLoader for loading {@link MINTED_SERVICE_IMPL_CLASS_NAME}.
92 * @param context WebAPK's context.
93 * @return The ClassLoader.
94 */
95 private static ClassLoader createClassLoader(Context context) {
96 Context remoteContext = WebApkUtils.getHostBrowserContext(context);
97 if (remoteContext == null) {
98 Log.w(TAG, "Failed to get remote context.");
99 return null;
100 }
101
102 SharedPreferences preferences = context.getSharedPreferences(PREF_FILE_N AME, MODE_PRIVATE);
103
104 int runtimeDexVersion = preferences.getInt(RUNTIME_DEX_VERSION_PREF, -1) ;
105 int newRuntimeDexVersion = checkForNewRuntimeDexVersion(preferences, rem oteContext);
106 if (newRuntimeDexVersion == -1) {
107 newRuntimeDexVersion = runtimeDexVersion;
108 }
109 File localDexDir = context.getDir("dex", Context.MODE_PRIVATE);
110 if (newRuntimeDexVersion != runtimeDexVersion) {
111 Log.w(TAG, "Delete cached dex files.");
112 DexLoader.deleteCachedDexes(localDexDir);
113 }
114
115 String dexAssetName = WebApkUtils.getRuntimeDexName(newRuntimeDexVersion );
116 File remoteDexFile =
117 new File(remoteContext.getDir("dex", Context.MODE_PRIVATE), dexA ssetName);
118 return DexLoader.load(remoteContext, dexAssetName, MINTED_SERVICE_IMPL_C LASS_NAME,
119 remoteDexFile, localDexDir);
120 }
121
122 /**
123 * Checks if there is a new "runtime dex" version number. If there is a new version number,
124 * updates SharedPreferences.
125 * @param preferences WebAPK's SharedPreferences.
126 * @param remoteContext
127 * @return The new "runtime dex" version number. -1 if there is no new versi on number.
128 */
129 private static int checkForNewRuntimeDexVersion(
130 SharedPreferences preferences, Context remoteContext) {
131 // The "runtime dex" version only changes when {@link remoteContext}'s A PK version code
132 // changes. Checking the APK's version code is less expensive than readi ng from the APK's
133 // assets.
134 PackageInfo remotePackageInfo = null;
135 try {
136 remotePackageInfo = remoteContext.getPackageManager().getPackageInfo (
137 remoteContext.getPackageName(), 0);
138 } catch (PackageManager.NameNotFoundException e) {
139 Log.e(TAG, "Failed to get remote package info.");
140 return -1;
141 }
142
143 int cachedRemoteVersionCode = preferences.getInt(REMOTE_VERSION_CODE_PRE F, -1);
144 if (cachedRemoteVersionCode == remotePackageInfo.versionCode) {
145 return -1;
146 }
147
148 int runtimeDexVersion = readAssetContentsToInt(remoteContext, "web_apk_d ex_version.txt");
149 SharedPreferences.Editor editor = preferences.edit();
150 editor.putInt(REMOTE_VERSION_CODE_PREF, remotePackageInfo.versionCode);
151 editor.putInt(RUNTIME_DEX_VERSION_PREF, runtimeDexVersion);
152 editor.apply();
153 return runtimeDexVersion;
154 }
155
156 /**
157 * Returns the first integer in an asset file's contents.
158 * @param context
159 * @param assetName The name of the asset.
160 */
161 private static int readAssetContentsToInt(Context context, String assetName) {
162 try (Scanner scanner = new Scanner(context.getAssets().open(assetName))) {
163 return scanner.nextInt();
164 } catch (Exception e) {
165 return -1;
166 }
167 }
168 }
OLDNEW
« no previous file with comments | « webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkApplication.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698