Bug 1544610 - Part 1 - Have certerror captive portal message exchanges happen over RPM. r=johannh
authorprathiksha <prathikshaprasadsuman@gmail.com>
Fri, 03 May 2019 23:30:35 +0000
changeset 531610 df46098ba4b559b4b62b8f05c51bacc424a9075b
parent 531609 500cdbe0977e74d4c166ff56cfeaa6690c9c71bf
child 531611 16545e6e556eb031b325e6012cf27419f5c56091
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1544610
milestone68.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 1544610 - Part 1 - Have certerror captive portal message exchanges happen over RPM. r=johannh Differential Revision: https://phabricator.services.mozilla.com/D28539
browser/actors/NetErrorChild.jsm
browser/base/content/aboutNetError.js
browser/base/content/browser-captivePortal.js
browser/base/content/browser.js
browser/components/BrowserGlue.jsm
browser/components/about/AboutNetErrorHandler.jsm
browser/components/about/moz.build
--- a/browser/actors/NetErrorChild.jsm
+++ b/browser/actors/NetErrorChild.jsm
@@ -608,19 +608,16 @@ class NetErrorChild extends ActorChild {
   handleEvent(aEvent) {
     // Documents have a null ownerDocument.
     let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
 
     switch (aEvent.type) {
     case "AboutNetErrorLoad":
       this.onPageLoad(aEvent.originalTarget, doc.defaultView);
       break;
-    case "AboutNetErrorOpenCaptivePortal":
-      this.openCaptivePortalPage(aEvent);
-      break;
     case "AboutNetErrorSetAutomatic":
       this.onSetAutomatic(aEvent);
       break;
     case "AboutNetErrorResetPreferences":
       this.onResetPreferences(aEvent);
       break;
     case "click":
       if (aEvent.button == 0) {
@@ -642,30 +639,19 @@ class NetErrorChild extends ActorChild {
       let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, this.docShell);
       // We need nsIWebNavigation to access docShell.document.
       frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
       if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
         return;
       }
 
       this.onCertErrorDetails(msg, frameDocShell);
-    } else if (msg.name == "Browser:CaptivePortalFreed") {
-      // TODO: This check is not correct for frames.
-      if (!this.isAboutCertError(this.content.document)) {
-        return;
-      }
-
-      this.onCaptivePortalFreed(msg);
     }
   }
 
-  onCaptivePortalFreed(msg) {
-    this.content.dispatchEvent(new this.content.CustomEvent("AboutNetErrorCaptivePortalFreed"));
-  }
-
   changedCertPrefs() {
     let prefSSLImpact = PREF_SSL_IMPACT_ROOTS.reduce((prefs, root) => {
        return prefs.concat(Services.prefs.getChildList(root));
     }, []);
     for (let prefName of prefSSLImpact) {
       if (Services.prefs.prefHasUserValue(prefName)) {
         return true;
       }
@@ -755,21 +741,16 @@ class NetErrorChild extends ActorChild {
         hideAddExceptionButton,
       }),
     }));
 
     this.mm.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
                             {reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN});
   }
 
-  openCaptivePortalPage(evt) {
-    this.mm.sendAsyncMessage("Browser:OpenCaptivePortalPage");
-  }
-
-
   onResetPreferences(evt) {
     this.mm.sendAsyncMessage("Browser:ResetSSLPreferences");
   }
 
   onSetAutomatic(evt) {
     this.mm.sendAsyncMessage("Browser:SetSSLErrorReportAuto", {
       automatic: evt.detail,
     });
--- a/browser/base/content/aboutNetError.js
+++ b/browser/base/content/aboutNetError.js
@@ -1,8 +1,10 @@
+/* eslint-env mozilla/frame-script */
+
 // The following parameters are parsed from the error URL:
 //   e - the error code
 //   s - custom CSS class to allow alternate styling/favicons
 //   d - error description
 //   captive - "true" to indicate we're behind a captive portal.
 //             Any other value is ignored.
 
 // Note that this file uses document.documentURI to get
@@ -308,26 +310,25 @@ function updateContainerPosition() {
     }
   }
 }
 
 function initPageCaptivePortal() {
   document.body.className = "captiveportal";
   document.getElementById("openPortalLoginPageButton")
           .addEventListener("click", () => {
-    let event = new CustomEvent("AboutNetErrorOpenCaptivePortal", {bubbles: true});
-    document.dispatchEvent(event);
+    RPMSendAsyncMessage("Browser:OpenCaptivePortalPage");
   });
 
   addAutofocus("openPortalLoginPageButton");
   setupAdvancedButton();
 
-  // When the portal is freed, an event is generated by the frame script
+  // When the portal is freed, an event is sent by the parent process
   // that we can pick up and attempt to reload the original page.
-  window.addEventListener("AboutNetErrorCaptivePortalFreed", () => {
+  RPMAddMessageListener("AboutNetErrorCaptivePortalFreed", () => {
     document.location.reload();
   });
 }
 
 function initPageCertError() {
   document.body.classList.add("certerror");
   for (let host of document.querySelectorAll(".hostname")) {
     host.textContent = document.location.hostname;
--- a/browser/base/content/browser-captivePortal.js
+++ b/browser/base/content/browser-captivePortal.js
@@ -33,16 +33,17 @@ var CaptivePortalWatcher = {
 
   get _browserBundle() {
     delete this._browserBundle;
     return this._browserBundle =
       Services.strings.createBundle("chrome://browser/locale/browser.properties");
   },
 
   init() {
+    Services.obs.addObserver(this, "ensure-captive-portal-tab");
     Services.obs.addObserver(this, "captive-portal-login");
     Services.obs.addObserver(this, "captive-portal-login-abort");
     Services.obs.addObserver(this, "captive-portal-login-success");
 
     this._cps = Cc["@mozilla.org/network/captive-portal-service;1"]
                   .getService(Ci.nsICaptivePortalService);
 
     if (this._cps.state == this._cps.LOCKED_PORTAL) {
@@ -62,32 +63,36 @@ var CaptivePortalWatcher = {
     // This constant is chosen to be large enough for a portal recheck to complete,
     // and small enough that the delay in opening a tab isn't too noticeable.
     // Please see comments for _delayedCaptivePortalDetected for more details.
     XPCOMUtils.defineLazyPreferenceGetter(this, "PORTAL_RECHECK_DELAY_MS",
                                           "captivedetect.portalRecheckDelayMS", 500);
   },
 
   uninit() {
+    Services.obs.removeObserver(this, "ensure-captive-portal-tab");
     Services.obs.removeObserver(this, "captive-portal-login");
     Services.obs.removeObserver(this, "captive-portal-login-abort");
     Services.obs.removeObserver(this, "captive-portal-login-success");
 
     this._cancelDelayedCaptivePortal();
   },
 
   delayedStartup() {
     if (this._delayedRecheckPending) {
       delete this._delayedRecheckPending;
       this._cps.recheckCaptivePortal();
     }
   },
 
   observe(aSubject, aTopic, aData) {
     switch (aTopic) {
+      case "ensure-captive-portal-tab":
+        this.ensureCaptivePortalTab();
+        break;
       case "captive-portal-login":
         this._captivePortalDetected();
         break;
       case "captive-portal-login-abort":
       case "captive-portal-login-success":
         this._captivePortalGone();
         break;
       case "delayed-captive-portal-handled":
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3046,68 +3046,47 @@ const PREF_SSL_IMPACT_ROOTS = ["security
  * Handle command events bubbling up from error page content
  * or from about:newtab or from remote error pages that invoke
  * us via async messaging.
  */
 var BrowserOnClick = {
   init() {
     let mm = window.messageManager;
     mm.addMessageListener("Browser:CertExceptionError", this);
-    mm.addMessageListener("Browser:OpenCaptivePortalPage", this);
     mm.addMessageListener("Browser:SiteBlockedError", this);
     mm.addMessageListener("Browser:EnableOnlineMode", this);
     mm.addMessageListener("Browser:SetSSLErrorReportAuto", this);
     mm.addMessageListener("Browser:ResetSSLPreferences", this);
     mm.addMessageListener("Browser:SSLErrorReportTelemetry", this);
     mm.addMessageListener("Browser:SSLErrorGoBack", this);
     mm.addMessageListener("Browser:PrimeMitm", this);
     mm.addMessageListener("Browser:ResetEnterpriseRootsPref", this);
-
-    Services.obs.addObserver(this, "captive-portal-login-abort");
-    Services.obs.addObserver(this, "captive-portal-login-success");
   },
 
   uninit() {
     let mm = window.messageManager;
     mm.removeMessageListener("Browser:CertExceptionError", this);
     mm.removeMessageListener("Browser:SiteBlockedError", this);
     mm.removeMessageListener("Browser:EnableOnlineMode", this);
     mm.removeMessageListener("Browser:SetSSLErrorReportAuto", this);
     mm.removeMessageListener("Browser:ResetSSLPreferences", this);
     mm.removeMessageListener("Browser:SSLErrorReportTelemetry", this);
     mm.removeMessageListener("Browser:SSLErrorGoBack", this);
     mm.removeMessageListener("Browser:PrimeMitm", this);
     mm.removeMessageListener("Browser:ResetEnterpriseRootsPref", this);
-
-    Services.obs.removeObserver(this, "captive-portal-login-abort");
-    Services.obs.removeObserver(this, "captive-portal-login-success");
-  },
-
-  observe(aSubject, aTopic, aData) {
-    switch (aTopic) {
-      case "captive-portal-login-abort":
-      case "captive-portal-login-success":
-        // Broadcast when a captive portal is freed so that error pages
-        // can refresh themselves.
-        window.messageManager.broadcastAsyncMessage("Browser:CaptivePortalFreed");
-      break;
-    }
   },
 
   receiveMessage(msg) {
     switch (msg.name) {
       case "Browser:CertExceptionError":
         this.onCertError(msg.target, msg.data.elementId,
                          msg.data.isTopFrame, msg.data.location,
                          msg.data.securityInfoAsString,
                          msg.data.frameId);
       break;
-      case "Browser:OpenCaptivePortalPage":
-        CaptivePortalWatcher.ensureCaptivePortalTab();
-      break;
       case "Browser:SiteBlockedError":
         this.onAboutBlocked(msg.data.elementId, msg.data.reason,
                             msg.data.isTopFrame, msg.data.location,
                             msg.data.blockedInfo);
       break;
       case "Browser:EnableOnlineMode":
         if (Services.io.offline) {
           // Reset network state and refresh the page.
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -170,25 +170,23 @@ let LEGACY_ACTORS = {
     },
   },
 
   NetError: {
     child: {
       module: "resource:///actors/NetErrorChild.jsm",
       events: {
         "AboutNetErrorLoad": {wantUntrusted: true},
-        "AboutNetErrorOpenCaptivePortal": {wantUntrusted: true},
         "AboutNetErrorSetAutomatic": {wantUntrusted: true},
         "AboutNetErrorResetPreferences": {wantUntrusted: true},
         "click": {},
       },
       matches: ["about:certerror?*", "about:neterror?*"],
       allFrames: true,
       messages: [
-        "Browser:CaptivePortalFreed",
         "CertErrorDetails",
       ],
     },
   },
 
   OfflineApps: {
     child: {
       module: "resource:///actors/OfflineAppsChild.jsm",
@@ -389,16 +387,17 @@ XPCOMUtils.defineLazyServiceGetters(this
 });
 XPCOMUtils.defineLazyGetter(this, "WeaveService", () =>
   Cc["@mozilla.org/weave/service;1"].getService().wrappedJSObject
 );
 
 // lazy module getters
 
 XPCOMUtils.defineLazyModuleGetters(this, {
+  AboutNetErrorHandler: "resource:///modules/aboutpages/AboutNetErrorHandler.jsm",
   AboutPrivateBrowsingHandler: "resource:///modules/aboutpages/AboutPrivateBrowsingHandler.jsm",
   AddonManager: "resource://gre/modules/AddonManager.jsm",
   AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.jsm",
   AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
   AutoCompletePopup: "resource://gre/modules/AutoCompletePopup.jsm",
   Blocklist: "resource://gre/modules/Blocklist.jsm",
   BookmarkHTMLUtils: "resource://gre/modules/BookmarkHTMLUtils.jsm",
   BookmarkJSONUtils: "resource://gre/modules/BookmarkJSONUtils.jsm",
@@ -1350,16 +1349,18 @@ BrowserGlue.prototype = {
     if (Services.prefs.prefHasUserValue("services.sync.username")) {
       WeaveService.init();
     }
 
     PageThumbs.init();
 
     NewTabUtils.init();
 
+    AboutNetErrorHandler.init();
+
     AboutPrivateBrowsingHandler.init();
 
     PageActions.init();
 
     this._firstWindowTelemetry(aWindow);
     this._firstWindowLoaded();
 
     this._collectStartupConditionsTelemetry();
@@ -1494,16 +1495,17 @@ BrowserGlue.prototype = {
     SearchTelemetry.uninit();
     // Only uninit PingCentre if the getter has initialized it
     if (Object.prototype.hasOwnProperty.call(this, "pingCentre")) {
       this.pingCentre.uninit();
     }
 
     PageThumbs.uninit();
     NewTabUtils.uninit();
+    AboutNetErrorHandler.uninit();
     AboutPrivateBrowsingHandler.uninit();
     AutoCompletePopup.uninit();
     DateTimePickerParent.uninit();
 
     Normandy.uninit();
     RFPHelper.uninit();
   },
 
new file mode 100644
--- /dev/null
+++ b/browser/components/about/AboutNetErrorHandler.jsm
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["AboutNetErrorHandler"];
+
+const {RemotePages} = ChromeUtils.import("resource://gre/modules/remotepagemanager/RemotePageManagerParent.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+var AboutNetErrorHandler = {
+  _inited: false,
+
+  init() {
+    this._boundReceiveMessage = this.receiveMessage.bind(this);
+    this.pageListener = new RemotePages(["about:certerror", "about:neterror"]);
+    this.pageListener.addMessageListener("Browser:OpenCaptivePortalPage", this._boundReceiveMessage);
+    this._inited = true;
+
+    Services.obs.addObserver(this, "captive-portal-login-abort");
+    Services.obs.addObserver(this, "captive-portal-login-success");
+  },
+
+  uninit() {
+    if (!this._inited) {
+      return;
+    }
+
+    this.pageListener.removeMessageListener("Browser:OpenCaptivePortalPage", this._boundReceiveMessage);
+    this.pageListener.destroy();
+
+    Services.obs.removeObserver(this, "captive-portal-login-abort");
+    Services.obs.removeObserver(this, "captive-portal-login-success");
+  },
+
+  observe(aSubject, aTopic, aData) {
+    switch (aTopic) {
+      case "captive-portal-login-abort":
+      case "captive-portal-login-success":
+        // Send a message to the content when a captive portal is freed
+        // so that error pages can refresh themselves.
+        this.pageListener.sendAsyncMessage("AboutNetErrorCaptivePortalFreed");
+      break;
+    }
+  },
+
+  receiveMessage(msg) {
+    switch (msg.name) {
+      case "Browser:OpenCaptivePortalPage":
+        Services.obs.notifyObservers(null, "ensure-captive-portal-tab");
+      break;
+    }
+  },
+};
--- a/browser/components/about/moz.build
+++ b/browser/components/about/moz.build
@@ -17,16 +17,17 @@ SOURCES += [
     'AboutRedirector.cpp',
 ]
 
 XPCOM_MANIFESTS += [
     'components.conf',
 ]
 
 EXTRA_JS_MODULES.aboutpages = [
+    'AboutNetErrorHandler.jsm',
     'AboutPrivateBrowsingHandler.jsm',
 ]
 
 FINAL_LIBRARY = 'browsercomps'
 
 LOCAL_INCLUDES += [
     '../build',
 ]