Bug 1278581 - Show neterror page if you enter an unknown URI scheme into urlbar on Android. r=sebastian, a=ritu
authorJames Willcox <snorp@snorp.net>
Fri, 30 Sep 2016 08:21:55 -0700
changeset 340329 1eb42c3dd320f1942264bd0178815c93c90af1fa
parent 340328 d44e7c69653cbf223b583e80b7cd56532455d44b
child 340330 45c3cb513380fdc3f0f46be42324c46c38f36ea9
push id10083
push userryanvm@gmail.com
push dateFri, 30 Sep 2016 19:42:13 +0000
treeherdermozilla-aurora@7c06ade5c9d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian, ritu
bugs1278581
milestone51.0a2
Bug 1278581 - Show neterror page if you enter an unknown URI scheme into urlbar on Android. r=sebastian, a=ritu
mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
mobile/android/components/ContentDispatchChooser.js
--- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
@@ -519,27 +519,27 @@ public final class IntentHelper implemen
 
             // (Bug 1192436) We don't know if marketIntent matches any Activities (e.g. non-Play
             // Store devices). If it doesn't, clicking the link will cause no action to occur.
             ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser(
                     activity, activity.getSupportFragmentManager(), marketIntent);
             callback.sendSuccess(null);
 
         }  else {
-            // We originally loaded about:neterror when we failed to match the Intent. However, many
-            // websites worked around Chrome's implementation, which does nothing in this case. For
-            // example, the site might set a timeout and load a play store url for their app if the
-            // intent link fails to load, i.e. the app is not installed. These work-arounds would often
-            // end with our users seeing about:neterror instead of the intended experience. While I
-            // feel showing about:neterror is a better solution for users (when not hacked around),
+            // We return the error page here, but it will only be shown if we think the load did
+            // not come from clicking a link. Chrome does not show error pages in that case, and
+            // many websites have catered to this behavior. For example, the site might set a timeout and load a play
+            // store url for their app if the intent link fails to load, i.e. the app is not installed.
+            // These work-arounds would often end with our users seeing about:neterror instead of the intended experience.
+            // While I feel showing about:neterror is a better solution for users (when not hacked around),
             // we should match the status quo for the good of our users.
             //
             // Don't log the URI to prevent leaking it.
-            Log.w(LOGTAG, "Unable to open URI - ignoring click");
-            callback.sendSuccess(null); // pretend we opened the page.
+            Log.w(LOGTAG, "Unable to open URI, maybe showing neterror");
+            callback.sendError(getUnknownProtocolErrorPageUri(intent.getData().toString()));
         }
     }
 
     private static boolean isFallbackUrlValid(@Nullable final String fallbackUrl) {
         if (fallbackUrl == null) {
             return false;
         }
 
--- a/mobile/android/components/ContentDispatchChooser.js
+++ b/mobile/android/components/ContentDispatchChooser.js
@@ -61,20 +61,23 @@ ContentDispatchChooser.prototype =
       let msg = {
         type: "Intent:OpenNoHandler",
         uri: aURI.spec,
       };
 
       Messaging.sendRequestForResult(msg).then(() => {
         // Java opens an app on success: take no action.
       }, (uri) => {
-        // Java didn't load a page so load the page that Java wants us to load.
-        //
-        // Note: when we load the page here (rather than into the selected tab in
-        // java), we load it in the same context where the uri was specified (e.g.
-        // if it's in an iframe, we load the page in an iframe).
-        window.location.href = uri;
+        // We couldn't open this. If this was from a click, it's likely that we just
+        // want this to fail silently. If the user entered this on the address bar, though,
+        // we want to show the neterror page.
+
+        let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+        let millis = dwu.millisSinceLastUserInput;
+        if (millis > 0 && millis >= 1000) {
+          window.location.href = uri;
+        }
       });
     }
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentDispatchChooser]);