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

Side by Side Diff: chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/MainActivity.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 2015 The Chromium Authors. All rights reserved. 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 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.Activity;
8 import android.content.ActivityNotFoundException; 7 import android.content.ActivityNotFoundException;
9 import android.content.Intent; 8 import android.content.Intent;
10 import android.content.pm.ApplicationInfo; 9 import android.content.pm.ApplicationInfo;
11 import android.content.pm.PackageManager; 10 import android.content.pm.PackageManager;
12 import android.content.pm.PackageManager.NameNotFoundException; 11 import android.content.pm.PackageManager.NameNotFoundException;
13 import android.net.Uri; 12 import android.net.Uri;
14 import android.os.Bundle; 13 import android.os.Bundle;
14 import android.support.v4.app.DialogFragment;
15 import android.support.v4.app.FragmentActivity;
16 import android.text.TextUtils;
15 import android.util.Log; 17 import android.util.Log;
16 18
17 import org.chromium.webapk.lib.common.WebApkConstants; 19 import org.chromium.webapk.lib.common.WebApkConstants;
18 import org.chromium.webapk.lib.common.WebApkMetaDataKeys; 20 import org.chromium.webapk.lib.common.WebApkMetaDataKeys;
19 21
20 import java.net.URISyntaxException; 22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.util.Set;
21 25
22 /** 26 /**
23 * WebAPK's main Activity. 27 * WebAPK's main Activity.
24 */ 28 */
25 public class MainActivity extends Activity { 29 public class MainActivity
30 extends FragmentActivity implements ChooseHostBrowserDialogFragment.Dial ogListener {
26 private static final String TAG = "cr_MainActivity"; 31 private static final String TAG = "cr_MainActivity";
27 32
28 /** 33 /**
29 * Name of class which launches browser in WebAPK mode. 34 * Name of class which launches browser in WebAPK mode.
30 */ 35 */
31 private static final String HOST_BROWSER_LAUNCHER_CLASS_NAME = 36 private static final String HOST_BROWSER_LAUNCHER_CLASS_NAME =
32 "org.chromium.webapk.lib.runtime_library.HostBrowserLauncher"; 37 "org.chromium.webapk.lib.runtime_library.HostBrowserLauncher";
33 38
34 // Action for launching {@link WebappLauncherActivity}. Must stay in sync wi th 39 // Action for launching {@link WebappLauncherActivity}. Must stay in sync wi th
35 // {@link WebappLauncherActivity#ACTION_START_WEBAPP}. 40 // {@link WebappLauncherActivity#ACTION_START_WEBAPP}.
36 public static final String ACTION_START_WEBAPK = 41 public static final String ACTION_START_WEBAPK =
37 "com.google.android.apps.chrome.webapps.WebappManager.ACTION_START_W EBAPP"; 42 "com.google.android.apps.chrome.webapps.WebappManager.ACTION_START_W EBAPP";
38 43
39 // Must stay in sync with 44 // Must stay in sync with
40 // {@link org.chromium.chrome.browser.ShortcutHelper#REUSE_URL_MATCHING_TAB_ ELSE_NEW_TAB}. 45 // {@link org.chromium.chrome.browser.ShortcutHelper#REUSE_URL_MATCHING_TAB_ ELSE_NEW_TAB}.
41 private static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB = 46 private static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB =
42 "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB"; 47 "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB";
43 48
44 /** 49 /**
45 * Key for passing app icon id. 50 * Key for passing app icon id.
46 */ 51 */
47 private static final String KEY_APP_ICON_ID = "app_icon_id"; 52 private static final String KEY_APP_ICON_ID = "app_icon_id";
48 53
54 private String mOverrideUrl;
55 private String mStartUrl;
56
49 /** 57 /**
50 * Creates install Intent. 58 * Creates install Intent.
51 * @param packageName Package to install. 59 * @param packageName Package to install.
52 * @return The intent. 60 * @return The intent.
53 */ 61 */
54 public static Intent createInstallIntent(String packageName) { 62 public static Intent createInstallIntent(String packageName) {
55 String marketUrl = "market://details?id=" + packageName; 63 String marketUrl = "market://details?id=" + packageName;
56 return new Intent(Intent.ACTION_VIEW, Uri.parse(marketUrl)); 64 return new Intent(Intent.ACTION_VIEW, Uri.parse(marketUrl));
57 } 65 }
58 66
59 @Override 67 @Override
60 protected void onCreate(Bundle savedInstanceState) { 68 protected void onCreate(Bundle savedInstanceState) {
61 super.onCreate(savedInstanceState); 69 super.onCreate(savedInstanceState);
62 launch(); 70 mOverrideUrl = getOverrideUrl();
63 finish(); 71 mStartUrl = (mOverrideUrl != null) ? mOverrideUrl : getStartUrl();
64 } 72 if (mStartUrl == null) {
65 73 finish();
66 /**
67 * Launches WebAPK.
68 */
69 private void launch() {
70 String overrideUrl = getOverrideUrl();
71 String startUrl = (overrideUrl != null) ? overrideUrl : getStartUrl();
72 if (startUrl == null) {
73 return; 74 return;
74 } 75 }
75 76
76 if (launchHostBrowserInWebApkMode(startUrl, overrideUrl)) { 77 Log.v(TAG, "Url of the WebAPK: " + mStartUrl);
77 return;
78 }
79 if (launchBrowser(startUrl)) {
80 return;
81 }
82 installBrowser();
83 }
84
85 /**
86 * Launches host browser in WebAPK mode.
87 * @return True if successful.
88 */
89 private boolean launchHostBrowserInWebApkMode(String startUrl, String overri deUrl) {
90 Log.v(TAG, "Url of the WebAPK: " + startUrl);
91 String packageName = getPackageName(); 78 String packageName = getPackageName();
92 Log.v(TAG, "Package name of the WebAPK:" + packageName); 79 Log.v(TAG, "Package name of the WebAPK:" + packageName);
93 80
94 String runtimeHost = WebApkUtils.getHostBrowserPackageName(this); 81 String runtimeHost = WebApkUtils.getHostBrowserPackageName(this);
82 if (!TextUtils.isEmpty(runtimeHost) && launchInHostBrowser(runtimeHost)) {
83 finish();
84 return;
85 }
86
87 String hostUrl = "";
88 try {
89 hostUrl = new URL(mStartUrl).getHost();
90 } catch (MalformedURLException e) {
91 Log.e(TAG, "Invalid URL of the WebApk.");
92 finish();
93 return;
94 }
pkotwicz 2017/05/26 22:38:39 Don't you need to call WebApkUtils#deleteSharedPre
Xi Han 2017/05/29 21:18:56 You are right. Call it inside launchiInHostBrowser
95 DialogFragment dialogFragment = ChooseHostBrowserDialogFragment.newInsta nce(hostUrl);
96 dialogFragment.show(getSupportFragmentManager(), "ChooseHostBrowserDialo gFragment");
97 }
98
99 /** Retrieves URL from the intent's data. Returns null if a URL could not be retrieved. */
100 private String getOverrideUrl() {
101 String overrideUrl = getIntent().getDataString();
102 if (overrideUrl != null && overrideUrl.startsWith("https:")) {
103 return overrideUrl;
104 }
105 return null;
106 }
107
108 /** Returns the start URL from the Android Manifest. */
109 private String getStartUrl() {
110 ApplicationInfo appInfo;
111 try {
112 appInfo = getPackageManager().getApplicationInfo(
113 getPackageName(), PackageManager.GET_META_DATA);
114 } catch (NameNotFoundException e) {
115 return null;
116 }
117 return appInfo.metaData.getString(WebApkMetaDataKeys.START_URL);
118 }
119
120 @Override
121 public void onHostBrowserSelected(String runtimeHost) {
122 Set<String> installedBrowsers = WebApkUtils.getInstalledBrowsers(getPack ageManager());
123 if (installedBrowsers.contains(runtimeHost)) {
124 launchInHostBrowser(runtimeHost);
125 } else {
126 installBrowser(runtimeHost);
127 }
pkotwicz 2017/05/26 22:38:39 Don't you need to call WebApkUtils#deleteSharedPre
Xi Han 2017/05/29 21:18:55 Add a call in |launchInHostBrowser|.
128 // It is safe to cache the runtimeHost to the share pref if user didn't install the browser
129 // in {@link installBrowser}. On next launch,
130 // {@link WebApkUtils#getHostBrowserPackageName()} will catch it, and th e dialog to choose
131 // host browser will show again. If user did install the browser chosen, saving the
132 // runtimeHost to the shared pref can avoid showing the dialog.
133 WebApkUtils.writeHostBrowserToSharedPref(this, runtimeHost);
134 finish();
135 }
136
137 @Override
138 public void onQuit() {
139 finish();
140 }
141
142 private boolean launchInHostBrowser(String runtimeHost) {
95 boolean forceNavigation = false; 143 boolean forceNavigation = false;
96 int source = getIntent().getIntExtra(WebApkConstants.EXTRA_SOURCE, 0); 144 int source = getIntent().getIntExtra(WebApkConstants.EXTRA_SOURCE, 0);
97 if (overrideUrl != null) { 145 if (mOverrideUrl != null) {
98 if (source == WebApkConstants.SHORTCUT_SOURCE_UNKNOWN) { 146 if (source == WebApkConstants.SHORTCUT_SOURCE_UNKNOWN) {
99 source = WebApkConstants.SHORTCUT_SOURCE_EXTERNAL_INTENT; 147 source = WebApkConstants.SHORTCUT_SOURCE_EXTERNAL_INTENT;
100 } 148 }
101 forceNavigation = getIntent().getBooleanExtra( 149 forceNavigation = getIntent().getBooleanExtra(
102 WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION, true); 150 WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION, true);
103 } 151 }
104 152
105 // The override URL is non null when the WebAPK is launched from a deep link. The WebAPK 153 // The override URL is non null when the WebAPK is launched from a deep link. The WebAPK
106 // should navigate to the URL in the deep link even if the WebAPK is alr eady open. 154 // should navigate to the URL in the deep link even if the WebAPK is alr eady open.
107 Intent intent = new Intent(); 155 Intent intent = new Intent();
108 intent.setAction(ACTION_START_WEBAPK); 156 intent.setAction(ACTION_START_WEBAPK);
109 intent.setPackage(runtimeHost); 157 intent.setPackage(runtimeHost);
110 intent.putExtra(WebApkConstants.EXTRA_URL, startUrl) 158 intent.putExtra(WebApkConstants.EXTRA_URL, mStartUrl)
111 .putExtra(WebApkConstants.EXTRA_SOURCE, source) 159 .putExtra(WebApkConstants.EXTRA_SOURCE, source)
112 .putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, packageName ) 160 .putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, getPackageN ame())
113 .putExtra(WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION, forceNa vigation); 161 .putExtra(WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION, forceNa vigation);
114 162
115 try { 163 try {
116 startActivity(intent); 164 startActivity(intent);
117 return true; 165 return true;
118 } catch (ActivityNotFoundException e) { 166 } catch (ActivityNotFoundException e) {
119 Log.w(TAG, "Unable to launch browser in WebAPK mode."); 167 Log.w(TAG, "Unable to launch browser in WebAPK mode.");
120 e.printStackTrace(); 168 e.printStackTrace();
121 return false; 169 return false;
122 } 170 }
123 } 171 }
124 172
125 /** 173 /**
126 * Launches browser (not necessarily the host browser).
127 * @param startUrl URL to navigate browser to.
128 * @return True if successful.
129 */
130 private boolean launchBrowser(String startUrl) {
131 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(startUrl));
132 intent.addCategory(Intent.CATEGORY_BROWSABLE);
133
134 // The WebAPK can handle {@link startUrl}. Set a selector to prevent the WebAPK from
135 // launching itself.
136 try {
137 Intent selectorIntent = Intent.parseUri("https://", Intent.URI_INTEN T_SCHEME);
138 intent.setSelector(selectorIntent);
139 } catch (URISyntaxException e) {
140 return false;
141 }
142
143 // Add extras in case that the URL is launched in Chrome.
144 int source =
145 getIntent().getIntExtra(WebApkConstants.EXTRA_SOURCE, Intent.URI _INTENT_SCHEME);
146 intent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true)
147 .putExtra(WebApkConstants.EXTRA_SOURCE, source);
148
149 try {
150 startActivity(intent);
151 } catch (ActivityNotFoundException e) {
152 return false;
153 }
154 return true;
155 }
156
157 /**
158 * Launches the Play Store with the host browser's page. 174 * Launches the Play Store with the host browser's page.
159 */ 175 */
160 private void installBrowser() { 176 private void installBrowser(String hostBrowserPackageName) {
161 String hostBrowserPackageName = WebApkUtils.getHostBrowserPackageName(th is);
162 if (hostBrowserPackageName == null) {
163 return;
164 }
165
166 try { 177 try {
167 startActivity(createInstallIntent(hostBrowserPackageName)); 178 startActivity(createInstallIntent(hostBrowserPackageName));
168 } catch (ActivityNotFoundException e) { 179 } catch (ActivityNotFoundException e) {
169 } 180 }
170 } 181 }
171
172 /** Retrieves URL from the intent's data. Returns null if a URL could not be retrieved. */
173 private String getOverrideUrl() {
174 String overrideUrl = getIntent().getDataString();
175 if (overrideUrl != null && overrideUrl.startsWith("https:")) {
176 return overrideUrl;
177 }
178 return null;
179 }
180
181 /** Returns the start URL from the Android Manifest. */
182 private String getStartUrl() {
183 ApplicationInfo appInfo;
184 try {
185 appInfo = getPackageManager().getApplicationInfo(
186 getPackageName(), PackageManager.GET_META_DATA);
187 } catch (NameNotFoundException e) {
188 return null;
189 }
190 return appInfo.metaData.getString(WebApkMetaDataKeys.START_URL);
191 }
192 } 182 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698