Bug 1278581 - Show neterror page if you enter an unknown URI scheme into urlbar on Android r=sebastian
authorJames Willcox <snorp@snorp.net>
Tue, 27 Sep 2016 09:23:32 -0500
changeset 315816 a13cbb3da4019d38f8426b323be5ff8a198d5f4d
parent 315815 41dd7c0d25eb7a0639cab67893f8885d6a178b0d
child 315817 2af19b7c731b363ff93fed151aee22979f8f44c9
push id30757
push usercbook@mozilla.com
push dateFri, 30 Sep 2016 10:02:43 +0000
treeherdermozilla-central@5ffed033557e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1278581
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1278581 - Show neterror page if you enter an unknown URI scheme into urlbar on Android r=sebastian
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]);