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

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

Powered by Google App Engine
This is Rietveld 408576698