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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java

Issue 1039013002: Use fallback URL more extensively (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/tab/TabRedirectHandler.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.chrome.browser.externalnav; 5 package org.chromium.chrome.browser.externalnav;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.app.Activity; 8 import android.app.Activity;
9 import android.content.ActivityNotFoundException; 9 import android.content.ActivityNotFoundException;
10 import android.content.ComponentName; 10 import android.content.ComponentName;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 public ExternalNavigationHandler(ExternalNavigationDelegate delegate) { 67 public ExternalNavigationHandler(ExternalNavigationDelegate delegate) {
68 mDelegate = delegate; 68 mDelegate = delegate;
69 } 69 }
70 70
71 /** 71 /**
72 * Determines whether the URL needs to be sent as an intent to the system, 72 * Determines whether the URL needs to be sent as an intent to the system,
73 * and sends it, if appropriate. 73 * and sends it, if appropriate.
74 * @return Whether the URL generated an intent, caused a navigation in 74 * @return Whether the URL generated an intent, caused a navigation in
75 * current tab, or wasn't handled at all. 75 * current tab, or wasn't handled at all.
76 */ 76 */
77 public OverrideUrlLoadingResult shouldOverrideUrlLoading(ExternalNavigationP arams params) {
78 Intent intent;
79 // Perform generic parsing of the URI to turn it into an Intent.
80 try {
81 intent = Intent.parseUri(params.getUrl(), Intent.URI_INTENT_SCHEME);
82 } catch (URISyntaxException ex) {
83 Log.w(TAG, "Bad URI " + params.getUrl() + ": " + ex.getMessage());
84 return OverrideUrlLoadingResult.NO_OVERRIDE;
85 }
86
87 boolean hasBrowserFallbackUrl = false;
88 String browserFallbackUrl =
89 IntentUtils.safeGetStringExtra(intent, EXTRA_BROWSER_FALLBACK_UR L);
90 if (browserFallbackUrl != null
91 && UrlUtilities.isValidForIntentFallbackNavigation(browserFallba ckUrl)) {
92 hasBrowserFallbackUrl = true;
93 } else {
94 browserFallbackUrl = null;
95 }
96
97 OverrideUrlLoadingResult result = shouldOverrideUrlLoadingInternal(
98 params, intent, hasBrowserFallbackUrl, browserFallbackUrl);
99
100 if (result == OverrideUrlLoadingResult.NO_OVERRIDE && hasBrowserFallback Url
101 && (params.getRedirectHandler() == null
102 // For instance, if this is a chained fallback URL, we i gnore it.
103 || !params.getRedirectHandler().shouldNotOverrideUrlLoad ing())) {
104 return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params);
105 }
106 return result;
107 }
108
77 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) 109 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
78 public OverrideUrlLoadingResult shouldOverrideUrlLoading(ExternalNavigationP arams params) { 110 private OverrideUrlLoadingResult shouldOverrideUrlLoadingInternal(
111 ExternalNavigationParams params, Intent intent, boolean hasBrowserFa llbackUrl,
112 String browserFallbackUrl) {
79 // http://crbug.com/441284 : Disallow firing external intent while Chrom e is in the 113 // http://crbug.com/441284 : Disallow firing external intent while Chrom e is in the
80 // background. 114 // background.
81 if (params.isApplicationMustBeInForeground() && !mDelegate.isChromeAppIn Foreground()) { 115 if (params.isApplicationMustBeInForeground() && !mDelegate.isChromeAppIn Foreground()) {
82 return OverrideUrlLoadingResult.NO_OVERRIDE; 116 return OverrideUrlLoadingResult.NO_OVERRIDE;
83 } 117 }
84 // http://crbug.com/464669 : Disallow firing external intent from backgr ound tab. 118 // http://crbug.com/464669 : Disallow firing external intent from backgr ound tab.
85 if (params.isBackgroundTabNavigation()) { 119 if (params.isBackgroundTabNavigation()) {
86 return OverrideUrlLoadingResult.NO_OVERRIDE; 120 return OverrideUrlLoadingResult.NO_OVERRIDE;
87 } 121 }
88 122
(...skipping 15 matching lines...) Expand all
104 // This should be covered by not showing the picker if the core type i s reload. 138 // This should be covered by not showing the picker if the core type i s reload.
105 139
106 // http://crbug.com/164194 . A navigation forwards or backwards should n ever trigger 140 // http://crbug.com/164194 . A navigation forwards or backwards should n ever trigger
107 // the intent picker. 141 // the intent picker.
108 if (isForwardBackNavigation) { 142 if (isForwardBackNavigation) {
109 return OverrideUrlLoadingResult.NO_OVERRIDE; 143 return OverrideUrlLoadingResult.NO_OVERRIDE;
110 } 144 }
111 145
112 // http://crbug/331571 : Do not override a navigation started from user typing. 146 // http://crbug/331571 : Do not override a navigation started from user typing.
113 // http://crbug/424029 : Need to stay in Chrome for an intent heading ex plicitly to Chrome. 147 // http://crbug/424029 : Need to stay in Chrome for an intent heading ex plicitly to Chrome.
114 if (params.getRedirectHandler() != null 148 if (params.getRedirectHandler() != null) {
115 && params.getRedirectHandler().shouldStayInChrome()) { 149 if (params.getRedirectHandler().shouldStayInChrome()
116 return OverrideUrlLoadingResult.NO_OVERRIDE; 150 || params.getRedirectHandler().shouldNotOverrideUrlLoading() ) {
151 return OverrideUrlLoadingResult.NO_OVERRIDE;
152 }
117 } 153 }
118 154
119 // http://crbug.com/149218: We want to show the intent picker for ordina ry links, providing 155 // http://crbug.com/149218: We want to show the intent picker for ordina ry links, providing
120 // the link is not an incoming intent from another application, unless i t's a redirect (see 156 // the link is not an incoming intent from another application, unless i t's a redirect (see
121 // below). 157 // below).
122 boolean linkNotFromIntent = isLink && !isFromIntent; 158 boolean linkNotFromIntent = isLink && !isFromIntent;
123 159
124 boolean isOnEffectiveIntentRedirect = params.getRedirectHandler() == nul l ? false 160 boolean isOnEffectiveIntentRedirect = params.getRedirectHandler() == nul l ? false
125 : params.getRedirectHandler().isOnEffectiveIntentRedirectChain() ; 161 : params.getRedirectHandler().isOnEffectiveIntentRedirectChain() ;
126 162
(...skipping 15 matching lines...) Expand all
142 // page, there is clear intent to complete the navigation in Chrome. 178 // page, there is clear intent to complete the navigation in Chrome.
143 if (params.getReferrerUrl() != null && params.getReferrerUrl().startsWit h( 179 if (params.getReferrerUrl() != null && params.getReferrerUrl().startsWit h(
144 UrlConstants.CHROME_SCHEME) && (params.getUrl().startsWith(UrlCo nstants.HTTP_SCHEME) 180 UrlConstants.CHROME_SCHEME) && (params.getUrl().startsWith(UrlCo nstants.HTTP_SCHEME)
145 || params.getUrl().startsWith(UrlConstants.HTTPS_SCHEME) )) { 181 || params.getUrl().startsWith(UrlConstants.HTTPS_SCHEME) )) {
146 return OverrideUrlLoadingResult.NO_OVERRIDE; 182 return OverrideUrlLoadingResult.NO_OVERRIDE;
147 } 183 }
148 184
149 if (params.getUrl().startsWith(SCHEME_WTAI_MC)) { 185 if (params.getUrl().startsWith(SCHEME_WTAI_MC)) {
150 // wtai://wp/mc;number 186 // wtai://wp/mc;number
151 // number=string(phone-number) 187 // number=string(phone-number)
152 Intent intent = new Intent(Intent.ACTION_VIEW, 188 mDelegate.startActivity(new Intent(Intent.ACTION_VIEW,
153 Uri.parse(WebView.SCHEME_TEL 189 Uri.parse(WebView.SCHEME_TEL
154 + params.getUrl().substring(SCHEME_WTAI_MC.length()) )); 190 + params.getUrl().substring(SCHEME_WTAI_MC.length()) )));
155 mDelegate.startActivity(intent);
156 return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT; 191 return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT;
157 } else if (params.getUrl().startsWith(SCHEME_WTAI)) { 192 } else if (params.getUrl().startsWith(SCHEME_WTAI)) {
158 // TODO: handle other WTAI schemes. 193 // TODO: handle other WTAI schemes.
159 return OverrideUrlLoadingResult.NO_OVERRIDE; 194 return OverrideUrlLoadingResult.NO_OVERRIDE;
160 } 195 }
161 196
162 // The "about:" schemes are internal to the browser; don't want these to 197 // The "about:" schemes are internal to the browser; don't want these to
163 // be dispatched to other apps. 198 // be dispatched to other apps.
164 if (params.getUrl().startsWith("about:")) { 199 if (params.getUrl().startsWith("about:")) {
165 return OverrideUrlLoadingResult.NO_OVERRIDE; 200 return OverrideUrlLoadingResult.NO_OVERRIDE;
(...skipping 11 matching lines...) Expand all
177 if (params.getUrl().matches(".*youtube\\.com.*[?&]pairingCode=.*")) { 212 if (params.getUrl().matches(".*youtube\\.com.*[?&]pairingCode=.*")) {
178 return OverrideUrlLoadingResult.NO_OVERRIDE; 213 return OverrideUrlLoadingResult.NO_OVERRIDE;
179 } 214 }
180 215
181 // TODO(changwan): check if we need to handle URL even when external int ent is off. 216 // TODO(changwan): check if we need to handle URL even when external int ent is off.
182 if (CommandLine.getInstance().hasSwitch( 217 if (CommandLine.getInstance().hasSwitch(
183 ChromeSwitches.DISABLE_EXTERNAL_INTENT_REQUESTS)) { 218 ChromeSwitches.DISABLE_EXTERNAL_INTENT_REQUESTS)) {
184 return OverrideUrlLoadingResult.NO_OVERRIDE; 219 return OverrideUrlLoadingResult.NO_OVERRIDE;
185 } 220 }
186 221
187 Intent intent;
188 // perform generic parsing of the URI to turn it into an Intent.
189 try {
190 intent = Intent.parseUri(params.getUrl(), Intent.URI_INTENT_SCHEME);
191 } catch (URISyntaxException ex) {
192 Log.w(TAG, "Bad URI " + params.getUrl() + ": " + ex.getMessage());
193 return OverrideUrlLoadingResult.NO_OVERRIDE;
194 }
195
196 boolean hasBrowserFallbackUrl = false;
197 String browserFallbackUrl = IntentUtils.safeGetStringExtra(
198 intent, EXTRA_BROWSER_FALLBACK_URL);
199 if (browserFallbackUrl != null
200 && UrlUtilities.isValidForIntentFallbackNavigation(browserFallba ckUrl)) {
201 hasBrowserFallbackUrl = true;
202 }
203
204 // check whether the intent can be resolved. If not, we will see 222 // check whether the intent can be resolved. If not, we will see
205 // whether we can download it from the Market. 223 // whether we can download it from the Market.
206 if (!mDelegate.canResolveActivity(intent)) { 224 if (!mDelegate.canResolveActivity(intent)) {
207 if (hasBrowserFallbackUrl) { 225 if (hasBrowserFallbackUrl) {
208 // NOTE: any further redirection from fall-back URL should not o verride URL loading. 226 return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, para ms);
209 // Otherwise, it can be used in chain for fingerprinting multipl e app installation
210 // status in one shot. In order to prevent this scenario, we not ify redirection
211 // handler that redirection from the current navigation should s tay in Chrome.
212 if (params.getRedirectHandler() != null) {
213 params.getRedirectHandler()
214 .setShouldStayInChromeUntilNewUrlLoading();
215 }
216 return mDelegate.clobberCurrentTab(browserFallbackUrl, params.ge tReferrerUrl(),
217 params.getTab());
218 } 227 }
219 String packagename = intent.getPackage(); 228 String packagename = intent.getPackage();
220 if (packagename != null) { 229 if (packagename != null) {
221 try { 230 try {
222 intent = new Intent(Intent.ACTION_VIEW, Uri.parse( 231 intent = new Intent(Intent.ACTION_VIEW, Uri.parse(
223 "market://details?id=" + packagename 232 "market://details?id=" + packagename
224 + "&referrer=" + mDelegate.getPackageName())); 233 + "&referrer=" + mDelegate.getPackageName()));
225 intent.addCategory(Intent.CATEGORY_BROWSABLE); 234 intent.addCategory(Intent.CATEGORY_BROWSABLE);
226 intent.setPackage("com.android.vending"); 235 intent.setPackage("com.android.vending");
227 mDelegate.startActivity(intent); 236 mDelegate.startActivity(intent);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 } 343 }
335 } catch (ActivityNotFoundException ex) { 344 } catch (ActivityNotFoundException ex) {
336 // Ignore the error. If no application can handle the URL, 345 // Ignore the error. If no application can handle the URL,
337 // assume the browser can handle it. 346 // assume the browser can handle it.
338 } 347 }
339 348
340 return OverrideUrlLoadingResult.NO_OVERRIDE; 349 return OverrideUrlLoadingResult.NO_OVERRIDE;
341 } 350 }
342 351
343 /** 352 /**
353 * Clobber the current tab with fallback URL.
354 *
355 * @param browserFallbackUrl The fallback URL.
356 * @param params The external navigation params.
357 * @return {@link OverrideUrlLoadingResult} if the tab was clobbered, or we launched an
358 * intent.
359 */
360 private OverrideUrlLoadingResult clobberCurrentTabWithFallbackUrl(
361 String browserFallbackUrl, ExternalNavigationParams params) {
362 // NOTE: any further redirection from fall-back URL should not override URL loading.
363 // Otherwise, it can be used in chain for fingerprinting multiple app in stallation
364 // status in one shot. In order to prevent this scenario, we notify redi rection
365 // handler that redirection from the current navigation should stay in C hrome.
366 if (params.getRedirectHandler() != null) {
367 params.getRedirectHandler().setShouldNotOverrideUrlLoadingUntilNewUr lLoading();
368 }
369 return mDelegate.clobberCurrentTab(
370 browserFallbackUrl, params.getReferrerUrl(), params.getTab());
371 }
372
373 /**
344 * @return Whether the |url| could be handled by an external application on the system. 374 * @return Whether the |url| could be handled by an external application on the system.
345 */ 375 */
346 public boolean canExternalAppHandleUrl(String url) { 376 public boolean canExternalAppHandleUrl(String url) {
347 if (url.startsWith(SCHEME_WTAI_MC)) return true; 377 if (url.startsWith(SCHEME_WTAI_MC)) return true;
348 try { 378 try {
349 Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME); 379 Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
350 return intent.getPackage() != null || mDelegate.canResolveActivity(i ntent); 380 return intent.getPackage() != null || mDelegate.canResolveActivity(i ntent);
351 } catch (URISyntaxException ex) { 381 } catch (URISyntaxException ex) {
352 // Ignore the error. 382 // Ignore the error.
353 } 383 }
354 return false; 384 return false;
355 } 385 }
356 } 386 }
OLDNEW
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/tab/TabRedirectHandler.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698