Index: chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java |
index 8d05569e2b9ff0506315b1801ce01e4c221d46b3..a64f13f6abfa630c0b654870e183f951a6b89fe9 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java |
@@ -74,8 +74,42 @@ public class ExternalNavigationHandler { |
* @return Whether the URL generated an intent, caused a navigation in |
* current tab, or wasn't handled at all. |
*/ |
- @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) |
public OverrideUrlLoadingResult shouldOverrideUrlLoading(ExternalNavigationParams params) { |
+ Intent intent; |
+ // Perform generic parsing of the URI to turn it into an Intent. |
+ try { |
+ intent = Intent.parseUri(params.getUrl(), Intent.URI_INTENT_SCHEME); |
+ } catch (URISyntaxException ex) { |
+ Log.w(TAG, "Bad URI " + params.getUrl() + ": " + ex.getMessage()); |
+ return OverrideUrlLoadingResult.NO_OVERRIDE; |
+ } |
+ |
+ boolean hasBrowserFallbackUrl = false; |
+ String browserFallbackUrl = |
+ IntentUtils.safeGetStringExtra(intent, EXTRA_BROWSER_FALLBACK_URL); |
+ if (browserFallbackUrl != null |
+ && UrlUtilities.isValidForIntentFallbackNavigation(browserFallbackUrl)) { |
+ hasBrowserFallbackUrl = true; |
+ } else { |
+ browserFallbackUrl = null; |
+ } |
+ |
+ OverrideUrlLoadingResult result = shouldOverrideUrlLoadingInternal( |
+ params, intent, hasBrowserFallbackUrl, browserFallbackUrl); |
+ |
+ if (result == OverrideUrlLoadingResult.NO_OVERRIDE && hasBrowserFallbackUrl |
+ && (params.getRedirectHandler() == null |
+ // For instance, if this is a chained fallback URL, we ignore it. |
+ || !params.getRedirectHandler().shouldNotOverrideUrlLoading())) { |
+ return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); |
+ } |
+ return result; |
+ } |
+ |
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) |
+ private OverrideUrlLoadingResult shouldOverrideUrlLoadingInternal( |
+ ExternalNavigationParams params, Intent intent, boolean hasBrowserFallbackUrl, |
+ String browserFallbackUrl) { |
// http://crbug.com/441284 : Disallow firing external intent while Chrome is in the |
// background. |
if (params.isApplicationMustBeInForeground() && !mDelegate.isChromeAppInForeground()) { |
@@ -111,9 +145,11 @@ public class ExternalNavigationHandler { |
// http://crbug/331571 : Do not override a navigation started from user typing. |
// http://crbug/424029 : Need to stay in Chrome for an intent heading explicitly to Chrome. |
- if (params.getRedirectHandler() != null |
- && params.getRedirectHandler().shouldStayInChrome()) { |
- return OverrideUrlLoadingResult.NO_OVERRIDE; |
+ if (params.getRedirectHandler() != null) { |
+ if (params.getRedirectHandler().shouldStayInChrome() |
+ || params.getRedirectHandler().shouldNotOverrideUrlLoading()) { |
+ return OverrideUrlLoadingResult.NO_OVERRIDE; |
+ } |
} |
// http://crbug.com/149218: We want to show the intent picker for ordinary links, providing |
@@ -149,10 +185,9 @@ public class ExternalNavigationHandler { |
if (params.getUrl().startsWith(SCHEME_WTAI_MC)) { |
// wtai://wp/mc;number |
// number=string(phone-number) |
- Intent intent = new Intent(Intent.ACTION_VIEW, |
+ mDelegate.startActivity(new Intent(Intent.ACTION_VIEW, |
Uri.parse(WebView.SCHEME_TEL |
- + params.getUrl().substring(SCHEME_WTAI_MC.length()))); |
- mDelegate.startActivity(intent); |
+ + params.getUrl().substring(SCHEME_WTAI_MC.length())))); |
return OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT; |
} else if (params.getUrl().startsWith(SCHEME_WTAI)) { |
// TODO: handle other WTAI schemes. |
@@ -184,37 +219,11 @@ public class ExternalNavigationHandler { |
return OverrideUrlLoadingResult.NO_OVERRIDE; |
} |
- Intent intent; |
- // perform generic parsing of the URI to turn it into an Intent. |
- try { |
- intent = Intent.parseUri(params.getUrl(), Intent.URI_INTENT_SCHEME); |
- } catch (URISyntaxException ex) { |
- Log.w(TAG, "Bad URI " + params.getUrl() + ": " + ex.getMessage()); |
- return OverrideUrlLoadingResult.NO_OVERRIDE; |
- } |
- |
- boolean hasBrowserFallbackUrl = false; |
- String browserFallbackUrl = IntentUtils.safeGetStringExtra( |
- intent, EXTRA_BROWSER_FALLBACK_URL); |
- if (browserFallbackUrl != null |
- && UrlUtilities.isValidForIntentFallbackNavigation(browserFallbackUrl)) { |
- hasBrowserFallbackUrl = true; |
- } |
- |
// check whether the intent can be resolved. If not, we will see |
// whether we can download it from the Market. |
if (!mDelegate.canResolveActivity(intent)) { |
if (hasBrowserFallbackUrl) { |
- // NOTE: any further redirection from fall-back URL should not override URL loading. |
- // Otherwise, it can be used in chain for fingerprinting multiple app installation |
- // status in one shot. In order to prevent this scenario, we notify redirection |
- // handler that redirection from the current navigation should stay in Chrome. |
- if (params.getRedirectHandler() != null) { |
- params.getRedirectHandler() |
- .setShouldStayInChromeUntilNewUrlLoading(); |
- } |
- return mDelegate.clobberCurrentTab(browserFallbackUrl, params.getReferrerUrl(), |
- params.getTab()); |
+ return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); |
} |
String packagename = intent.getPackage(); |
if (packagename != null) { |
@@ -341,6 +350,27 @@ public class ExternalNavigationHandler { |
} |
/** |
+ * Clobber the current tab with fallback URL. |
+ * |
+ * @param browserFallbackUrl The fallback URL. |
+ * @param params The external navigation params. |
+ * @return {@link OverrideUrlLoadingResult} if the tab was clobbered, or we launched an |
+ * intent. |
+ */ |
+ private OverrideUrlLoadingResult clobberCurrentTabWithFallbackUrl( |
+ String browserFallbackUrl, ExternalNavigationParams params) { |
+ // NOTE: any further redirection from fall-back URL should not override URL loading. |
+ // Otherwise, it can be used in chain for fingerprinting multiple app installation |
+ // status in one shot. In order to prevent this scenario, we notify redirection |
+ // handler that redirection from the current navigation should stay in Chrome. |
+ if (params.getRedirectHandler() != null) { |
+ params.getRedirectHandler().setShouldNotOverrideUrlLoadingUntilNewUrlLoading(); |
+ } |
+ return mDelegate.clobberCurrentTab( |
+ browserFallbackUrl, params.getReferrerUrl(), params.getTab()); |
+ } |
+ |
+ /** |
* @return Whether the |url| could be handled by an external application on the system. |
*/ |
public boolean canExternalAppHandleUrl(String url) { |