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

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