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

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

Issue 2858563004: Add support for webapk without runtimeHost (Closed)
Patch Set: Use spy to partically mock. Created 3 years, 6 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.content.Context; 7 import android.content.Context;
8 import android.content.Intent;
9 import android.content.SharedPreferences;
8 import android.content.pm.ApplicationInfo; 10 import android.content.pm.ApplicationInfo;
9 import android.content.pm.PackageManager; 11 import android.content.pm.PackageManager;
10 import android.content.pm.PackageManager.NameNotFoundException; 12 import android.content.pm.PackageManager.NameNotFoundException;
13 import android.content.pm.ResolveInfo;
14 import android.graphics.drawable.Drawable;
15 import android.net.Uri;
11 import android.os.Bundle; 16 import android.os.Bundle;
17 import android.text.TextUtils;
12 18
19 import org.chromium.webapk.lib.common.WebApkConstants;
13 import org.chromium.webapk.lib.common.WebApkMetaDataKeys; 20 import org.chromium.webapk.lib.common.WebApkMetaDataKeys;
14 21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27
15 /** 28 /**
16 * Contains utility methods for interacting with WebAPKs. 29 * Contains utility methods for interacting with WebAPKs.
17 */ 30 */
18 public class WebApkUtils { 31 public class WebApkUtils {
32 public static final String SHARED_PREF_RUNTIME_HOST = "runtime_host";
33
34 // The package names of the channels of Chrome that support WebAPKs. The mos t preferred one
35 // comes first.
pkotwicz 2017/05/26 22:38:39 Nit: use block commenting style
Xi Han 2017/05/29 21:18:56 Done.
36 private static List<String> sBrowsersSupportingWebApk = new ArrayList<String >(
37 Arrays.asList("com.google.android.apps.chrome", "com.android.chrome" , "com.chrome.beta",
38 "com.chrome.dev", "com.chrome.canary"));
19 39
20 /** 40 /**
21 * Caches the value read from Application Metadata which specifies the host browser's package 41 * Stores information about a potential host browser for the WebAPK.
22 * name. 42 */
43 public static class BrowserItem {
44 private String mPackageName;
45 private CharSequence mApplicationLabel;
46 private Drawable mIcon;
47 private boolean mIsEnabled;
pkotwicz 2017/05/26 22:38:39 WebApkUtils should not know about the UI in which
Xi Han 2017/05/29 21:18:56 Done.
48
49 public BrowserItem(String packageName, CharSequence applicationLabel, Dr awable icon,
50 boolean isEnabled) {
51 mPackageName = packageName;
52 mApplicationLabel = applicationLabel;
53 mIcon = icon;
54 mIsEnabled = isEnabled;
55 }
56
57 // Returns the package name of a browser.
pkotwicz 2017/05/26 22:38:39 Nit: Use /** */ for comments in this class. https:
Xi Han 2017/05/29 21:18:56 Thanks!
58 public String getPackageName() {
59 return mPackageName;
60 }
61
62 // Returns the application name of a browser.
63 public CharSequence getApplicationName() {
64 return mApplicationLabel;
65 }
66
67 // Returns a drawable of the browser icon.
68 public Drawable getApplicationIcon() {
69 return mIcon;
70 }
71
72 // Returns whether this BrowserItem is clickable. An BrowserItem is clic kable only if the
73 // browser it represents supporting WebAPKs.
74 public boolean isEnabled() {
75 return mIsEnabled;
76 }
77 }
78
79 /**
80 * Caches the package name of the host browser. {@link sHostPackage} might r efer to a browser
81 * which has been uninstalled. A notification can keep the WebAPK process al ive after the host
82 * browser has been uninstalled.
23 */ 83 */
24 private static String sHostPackage; 84 private static String sHostPackage;
25 85
86 // For testing only.
87 public static void resetCachedHostPackageForTesting() {
88 sHostPackage = null;
89 }
90
91 public static void setBrowsersSupportingWebApkForTesting(List<String> browse rs) {
92 sBrowsersSupportingWebApk = browsers;
93 }
94
26 /** 95 /**
27 * Returns a Context for the host browser that was specified when building t he WebAPK. 96 * Returns a Context for the host browser that was specified when building t he WebAPK.
28 * @param context A context. 97 * @param context A context.
29 * @return The remote context. Returns null on an error. 98 * @return The remote context. Returns null on an error.
30 */ 99 */
31 public static Context getHostBrowserContext(Context context) { 100 public static Context getHostBrowserContext(Context context) {
32 try { 101 try {
33 String hostPackage = getHostBrowserPackageName(context); 102 String hostPackage = getHostBrowserPackageName(context);
34 return context.getApplicationContext().createPackageContext( 103 return context.getApplicationContext().createPackageContext(
35 hostPackage, 104 hostPackage,
36 Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_IN CLUDE_CODE); 105 Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_IN CLUDE_CODE);
37 } catch (NameNotFoundException e) { 106 } catch (NameNotFoundException e) {
38 e.printStackTrace(); 107 e.printStackTrace();
39 } 108 }
40 return null; 109 return null;
41 } 110 }
42 111
43 /** 112 /**
44 * Returns the package name for the host browser that was specified when bui lding the WebAPK. 113 * Returns the package name of the host browser to launch the WebAPK. Also c aches the package
114 * name in the SharedPreference if it is not null.
45 * @param context A context. 115 * @param context A context.
46 * @return The package name. Returns null on an error. 116 * @return The package name. Returns null on an error.
47 */ 117 */
48 public static String getHostBrowserPackageName(Context context) { 118 public static String getHostBrowserPackageName(Context context) {
49 if (sHostPackage != null) return sHostPackage; 119 if (sHostPackage == null) {
50 String hostPackage = null; 120 sHostPackage = getHostBrowserPackageNameInternal(context);
51 try { 121 if (sHostPackage != null) {
52 ApplicationInfo ai = context.getPackageManager().getApplicationInfo( 122 writeHostBrowserToSharedPref(context, sHostPackage);
53 context.getPackageName(), PackageManager.GET_META_DATA); 123 }
pkotwicz 2017/05/26 22:38:39 The Shared Preferences should be cleared if: 1) Th
Xi Han 2017/05/29 21:18:56 I moved the call of deleteSharedPref() in getHostB
54 Bundle bundle = ai.metaData;
55 hostPackage = bundle.getString(WebApkMetaDataKeys.RUNTIME_HOST);
56 } catch (NameNotFoundException e) {
57 e.printStackTrace();
58 } 124 }
59 // Set {@link sHostPackage} to a non-null value so that the value is com puted only once. 125
60 sHostPackage = hostPackage != null ? hostPackage : "";
61 return sHostPackage; 126 return sHostPackage;
62 } 127 }
63 128
64 /** 129 /**
130 * Returns the package name of the host browser to launch the WebAPK, or nul l if we did not find
131 * one.
132 */
133 private static String getHostBrowserPackageNameInternal(Context context) {
134 Set<String> installedBrowsers = getInstalledBrowsers(context.getPackageM anager());
135 if (installedBrowsers.isEmpty()) {
136 return null;
137 }
138
139 // Gets the package name of the host browser if it is stored in the Shar edPreference.
140 String cachedHostBrowser = getHostBrowserFromSharedPreference(context);
141 if (!TextUtils.isEmpty(cachedHostBrowser)
142 && installedBrowsers.contains(cachedHostBrowser)) {
143 return cachedHostBrowser;
144 }
145
146 // Gets the package name of the host browser if it is specified in Andro idManifest.xml.
147 String hostBrowserFromManifest = getHostBrowserFromAndroidManifest(
148 context.getPackageManager(), context.getPackageName());
149 if (!TextUtils.isEmpty(hostBrowserFromManifest)) {
150 if (installedBrowsers.contains(hostBrowserFromManifest)) {
151 return hostBrowserFromManifest;
152 }
153 return null;
154 }
155
156 deleteSharedPref(context);
157
158 // Gets the package name of the default browser on the Android device.
159 // TODO(hanxi): Investigate the best way to know which browser supports WebAPKs.
160 String defaultBrowser = getDefaultBrowserPackageName(context.getPackageM anager());
161 if (!TextUtils.isEmpty(defaultBrowser) && installedBrowsers.contains(def aultBrowser)
162 && sBrowsersSupportingWebApk.contains(defaultBrowser)) {
163 return defaultBrowser;
164 }
165
166 return null;
167 }
168
169 /**
170 * Returns a list of browsers to choose host browser from. The list includes all the installed
171 * browsers, and if none of the installed browser supports WebAPKs, Chrome w ill be added to the
172 * list as well.
173 */
174 public static List<BrowserItem> getBrowserInfosForHostBrowserSelection(
175 PackageManager packageManager) {
176 Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http:// "));
177 List<ResolveInfo> resolvedActivityList = packageManager.queryIntentActiv ities(
178 browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
179
180 boolean hasBrowserSupportingWebApks = false;
181 List<BrowserItem> browsers = new ArrayList<>();
182 for (ResolveInfo info : resolvedActivityList) {
183 boolean supportsWebApk = false;
184 if (sBrowsersSupportingWebApk.contains(info.activityInfo.packageName )) {
185 supportsWebApk = true;
186 hasBrowserSupportingWebApks = true;
187 }
188 browsers.add(new BrowserItem(info.activityInfo.packageName,
189 info.loadLabel(packageManager), info.loadIcon(packageManager ), supportsWebApk));
190 }
191
192 if (hasBrowserSupportingWebApks) return browsers;
193
194 // TODO(hanxi): add Chrome's icon to WebAPKs.
195 browsers.add(new BrowserItem("com.android.chrome", "Chrome", null, true) );
196 return browsers;
197 }
198
199 /**
65 * Returns the uid for the host browser that was specified when building the WebAPK. 200 * Returns the uid for the host browser that was specified when building the WebAPK.
66 * @param context A context. 201 * @param context A context.
67 * @return The application uid. Returns -1 on an error. 202 * @return The application uid. Returns -1 on an error.
68 */ 203 */
69 public static int getHostBrowserUid(Context context) { 204 public static int getHostBrowserUid(Context context) {
70 String hostPackageName = getHostBrowserPackageName(context); 205 String hostPackageName = getHostBrowserPackageName(context);
71 if (hostPackageName == null) { 206 if (hostPackageName == null) {
72 return -1; 207 return -1;
73 } 208 }
74 try { 209 try {
75 PackageManager packageManager = context.getPackageManager(); 210 PackageManager packageManager = context.getPackageManager();
76 ApplicationInfo appInfo = packageManager.getApplicationInfo( 211 ApplicationInfo appInfo = packageManager.getApplicationInfo(
77 hostPackageName, PackageManager.GET_META_DATA); 212 hostPackageName, PackageManager.GET_META_DATA);
78 return appInfo.uid; 213 return appInfo.uid;
79 } catch (NameNotFoundException e) { 214 } catch (NameNotFoundException e) {
80 e.printStackTrace(); 215 e.printStackTrace();
81 } 216 }
82 return -1; 217 return -1;
83 } 218 }
219
220 /** Returns the package name of the host browser cached in the SharedPrefere nces. */
221 private static String getHostBrowserFromSharedPreference(Context context) {
222 SharedPreferences sharedPref =
223 context.getSharedPreferences(WebApkConstants.PREF_PACKAGE, Conte xt.MODE_PRIVATE);
224 return sharedPref.getString(SHARED_PREF_RUNTIME_HOST, null);
225 }
226
227 /** Returns a set of package names of all the installed browsers on the devi ce. */
228 public static Set<String> getInstalledBrowsers(PackageManager packageManager ) {
229 Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http:// "));
230 List<ResolveInfo> resolvedActivityList = packageManager.queryIntentActiv ities(
231 browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
232
233 Set<String> packagesSupportingWebApks = new HashSet<String>();
234 for (ResolveInfo info : resolvedActivityList) {
235 packagesSupportingWebApks.add(info.activityInfo.packageName);
236 }
237 return packagesSupportingWebApks;
238 }
239
240 /** Returns the package name of the "runtime host" in the AndroidManifest.xm l. */
241 public static String getHostBrowserFromAndroidManifest(
242 PackageManager packageManager, String webApkPackageName) {
243 try {
244 ApplicationInfo ai = packageManager.getApplicationInfo(
245 webApkPackageName, PackageManager.GET_META_DATA);
246 Bundle bundle = ai.metaData;
247 return bundle.getString(WebApkMetaDataKeys.RUNTIME_HOST);
248 } catch (NameNotFoundException e) {
249 return null;
250 }
251 }
252
253 /** Returns the package name of the default browser on the Android device. * /
254 private static String getDefaultBrowserPackageName(PackageManager packageMan ager) {
255 Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http:// "));
256 ResolveInfo resolveInfo =
257 packageManager.resolveActivity(browserIntent, PackageManager.MAT CH_DEFAULT_ONLY);
258 if (resolveInfo == null || resolveInfo.activityInfo == null) return null ;
259
260 return resolveInfo.activityInfo.packageName;
261 }
262
263 /**
264 * Writes the package name of the host browser to the SharedPreferences. If the host browser is
265 * different than the previous one stored, delete the SharedPreference befor e storing the new
266 * host browser.
267 */
268 public static void writeHostBrowserToSharedPref(Context context, String host Package) {
269 if (TextUtils.isEmpty(hostPackage)) return;
270
271 SharedPreferences sharedPref =
272 context.getSharedPreferences(WebApkConstants.PREF_PACKAGE, Conte xt.MODE_PRIVATE);
273 SharedPreferences.Editor editor = sharedPref.edit();
274 editor.putString(SHARED_PREF_RUNTIME_HOST, hostPackage);
275 editor.apply();
276 }
277
278 /** Deletes the SharedPreferences. */
279 private static void deleteSharedPref(Context context) {
280 SharedPreferences sharedPref =
281 context.getSharedPreferences(WebApkConstants.PREF_PACKAGE, Conte xt.MODE_PRIVATE);
282 SharedPreferences.Editor editor = sharedPref.edit();
283 editor.clear();
284 editor.apply();
285 }
84 } 286 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698