Bug 1369436 - Alphabetize and lazily import push modules. r?florian draft
authorKit Cambridge <kit@yakshaving.ninja>
Wed, 21 Jun 2017 10:42:33 -0700
changeset 603352 74d4fe78cc5d9120968104a9e2960e2da2fd738e
parent 603265 283debe8155accfec5812c66e33384ce217d02c2
child 603353 47adf223afeaf8e68c1e4f0abd080aa50c3f327a
push id66770
push userbmo:kit@mozilla.com
push dateMon, 03 Jul 2017 20:56:27 +0000
reviewersflorian
bugs1369436
milestone56.0a1
Bug 1369436 - Alphabetize and lazily import push modules. r?florian MozReview-Commit-ID: 1VhxsxSwgAF
dom/push/Push.js
dom/push/PushComponents.js
dom/push/PushCrypto.jsm
dom/push/PushDB.jsm
dom/push/PushRecord.jsm
dom/push/PushService.jsm
dom/push/PushServiceAndroidGCM.jsm
dom/push/PushServiceHttp2.jsm
dom/push/PushServiceWebSocket.jsm
dom/push/test/xpcshell/head.js
--- a/dom/push/Push.js
+++ b/dom/push/Push.js
@@ -4,19 +4,19 @@
 
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "Push",
   });
 });
--- a/dom/push/PushComponents.js
+++ b/dom/push/PushComponents.js
@@ -6,29 +6,29 @@
 
 /**
  * This file exports XPCOM components for C++ and chrome JavaScript callers to
  * interact with the Push service.
  */
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
+Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-var isParent = Services.appinfo.processType === Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
 
 // The default Push service implementation.
 XPCOMUtils.defineLazyGetter(this, "PushService", function() {
   const {PushService} = Cu.import("resource://gre/modules/PushService.jsm",
                                   {});
   PushService.init();
   return PushService;
 });
 
+var isParent = Services.appinfo.processType === Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+
 // Observer notification topics for push messages and subscription status
 // changes. These are duplicated and used in `nsIPushNotifier`. They're exposed
 // on `nsIPushService` so that JS callers only need to import this service.
 const OBSERVER_TOPIC_PUSH = "push-message";
 const OBSERVER_TOPIC_SUBSCRIPTION_CHANGE = "push-subscription-change";
 const OBSERVER_TOPIC_SUBSCRIPTION_MODIFIED = "push-subscription-modified";
 
 /**
--- a/dom/push/PushCrypto.jsm
+++ b/dom/push/PushCrypto.jsm
@@ -1,27 +1,26 @@
-/* jshint moz: true, esnext: true */
 /* 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';
 
 const Cu = Components.utils;
 
+this.EXPORTED_SYMBOLS = ['PushCrypto'];
+
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
+Cu.importGlobalProperties(['crypto']);
+
 XPCOMUtils.defineLazyGetter(this, 'gDOMBundle', () =>
   Services.strings.createBundle('chrome://global/locale/dom/dom.properties'));
 
-Cu.importGlobalProperties(['crypto']);
-
-this.EXPORTED_SYMBOLS = ['PushCrypto', 'concatArray'];
-
 var UTF8 = new TextEncoder('utf-8');
 
 var ECDH_KEY = { name: 'ECDH', namedCurve: 'P-256' };
 var ECDSA_KEY =  { name: 'ECDSA', namedCurve: 'P-256' };
 
 // A default keyid with a name that won't conflict with a real keyid.
 var DEFAULT_KEYID = '';
 
@@ -215,17 +214,17 @@ function chunkArray(array, size) {
     index += size;
   }
   if (index < array.byteLength) {
     result.push(new Uint8Array(array, start + index));
   }
   return result;
 }
 
-this.concatArray = function(arrays) {
+function concatArray(arrays) {
   var size = arrays.reduce((total, a) => total + a.byteLength, 0);
   var index = 0;
   return arrays.reduce((result, a) => {
     result.set(new Uint8Array(a), index);
     index += a.byteLength;
     return result;
   }, new Uint8Array(size));
 };
@@ -559,16 +558,17 @@ class aesgcm128Decoder extends OldScheme
   }
 
   get padSize() {
     return 1;
   }
 }
 
 this.PushCrypto = {
+  concatArray,
 
   generateAuthenticationSecret() {
     return crypto.getRandomValues(new Uint8Array(16));
   },
 
   validateAppServerKey(key) {
     return crypto.subtle.importKey('raw', key, ECDSA_KEY,
                                    true, ['verify'])
--- a/dom/push/PushDB.jsm
+++ b/dom/push/PushDB.jsm
@@ -1,23 +1,23 @@
-/* jshint moz: true, esnext: true */
 /* 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";
 
 const Cu = Components.utils;
-Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.importGlobalProperties(["indexedDB"]);
 
 this.EXPORTED_SYMBOLS = ["PushDB"];
 
+Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+Cu.importGlobalProperties(["indexedDB"]);
+
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushDB",
   });
 });
 
--- a/dom/push/PushRecord.jsm
+++ b/dom/push/PushRecord.jsm
@@ -4,33 +4,33 @@
 
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
+this.EXPORTED_SYMBOLS = ["PushRecord"];
+
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+                                  "resource://gre/modules/AppConstants.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "EventDispatcher",
                                   "resource://gre/modules/Messaging.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
-
-this.EXPORTED_SYMBOLS = ["PushRecord"];
-
-const prefs = new Preferences("dom.push.");
+XPCOMUtils.defineLazyGetter(this, "prefs", () => new Preferences("dom.push."));
 
 /**
  * The push subscription record, stored in IndexedDB.
  */
 function PushRecord(props) {
   this.pushEndpoint = props.pushEndpoint;
   this.scope = props.scope;
   this.originAttributes = props.originAttributes;
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -1,59 +1,51 @@
-/* jshint moz: true, esnext: true */
 /* 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";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
+this.EXPORTED_SYMBOLS = ["PushService"];
+
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-const {
-  PushCrypto,
-  getCryptoParams,
-  CryptoError,
-} = Cu.import("resource://gre/modules/PushCrypto.jsm");
-const {PushDB} = Cu.import("resource://gre/modules/PushDB.jsm");
-
-const CONNECTION_PROTOCOLS = (function() {
-  if ('android' != AppConstants.MOZ_WIDGET_TOOLKIT) {
-    const {PushServiceWebSocket} = Cu.import("resource://gre/modules/PushServiceWebSocket.jsm");
-    const {PushServiceHttp2} = Cu.import("resource://gre/modules/PushServiceHttp2.jsm");
-    return [PushServiceWebSocket, PushServiceHttp2];
-  } else {
-    const {PushServiceAndroidGCM} = Cu.import("resource://gre/modules/PushServiceAndroidGCM.jsm");
-    return [PushServiceAndroidGCM];
-  }
-})();
-
-XPCOMUtils.defineLazyServiceGetter(this, "gPushNotifier",
-                                   "@mozilla.org/push/Notifier;1",
-                                   "nsIPushNotifier");
-
-this.EXPORTED_SYMBOLS = ["PushService"];
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+                                  "resource://gre/modules/AppConstants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushCrypto",
+                                  "resource://gre/modules/PushCrypto.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushServiceAndroidGCM",
+                                  "resource://gre/modules/PushServiceAndroidGCM.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushServiceWebSocket",
+                                  "resource://gre/modules/PushServiceWebSocket.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushServiceHttp2",
+                                  "resource://gre/modules/PushServiceHttp2.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushService",
   });
 });
 
-const prefs = new Preferences("dom.push.");
+XPCOMUtils.defineLazyGetter(this, "prefs", () => new Preferences("dom.push."));
+
+XPCOMUtils.defineLazyServiceGetter(this, "gPushNotifier",
+                                   "@mozilla.org/push/Notifier;1",
+                                   "nsIPushNotifier");
 
 const PUSH_SERVICE_UNINIT = 0;
 const PUSH_SERVICE_INIT = 1; // No serverURI
 const PUSH_SERVICE_ACTIVATING = 2;//activating db
 const PUSH_SERVICE_CONNECTION_DISABLE = 3;
 const PUSH_SERVICE_ACTIVE_OFFLINE = 4;
 const PUSH_SERVICE_RUNNING = 5;
 
@@ -74,16 +66,35 @@ const PUSH_SERVICE_RUNNING = 5;
  **/
 
 // This is for starting and stopping service.
 const STARTING_SERVICE_EVENT = 0;
 const CHANGING_SERVICE_EVENT = 1;
 const STOPPING_SERVICE_EVENT = 2;
 const UNINIT_EVENT = 3;
 
+// Returns the backend for the given server URI.
+function getServiceForServerURI(uri) {
+  // Insecure server URLs are allowed for development and testing.
+  let allowInsecure = prefs.get("testing.allowInsecureServerURL");
+  if (AppConstants.MOZ_WIDGET_TOOLKIT == "android") {
+    if (uri.scheme == "https" || (allowInsecure && uri.scheme == "http")) {
+      return PushServiceAndroidGCM;
+    }
+    return null;
+  }
+  if (uri.scheme == "wss" || (allowInsecure && uri.scheme == "ws")) {
+    return PushServiceWebSocket;
+  }
+  if (uri.scheme == "https" || (allowInsecure && uri.scheme == "http")) {
+    return PushServiceHttp2;
+  }
+  return null;
+}
+
 /**
  * Annotates an error with an XPCOM result code. We use this helper
  * instead of `Components.Exception` because the latter can assert in
  * `nsXPCComponents_Exception::HasInstance` when inspected at shutdown.
  */
 function errorWithResult(message, result = Cr.NS_ERROR_FAILURE) {
   let error = new Error(message);
   error.result = result;
@@ -371,38 +382,31 @@ this.PushService = {
     }).catch(e => {
       console.error("backgroundUnregister: Error notifying server", e);
     });
   },
 
   _findService: function(serverURL) {
     console.debug("findService()");
 
-    let uri;
-    let service;
-
     if (!serverURL) {
       console.warn("findService: No dom.push.serverURL found");
       return [];
     }
 
+    let uri;
     try {
       uri = Services.io.newURI(serverURL);
     } catch (e) {
       console.warn("findService: Error creating valid URI from",
         "dom.push.serverURL", serverURL);
       return [];
     }
 
-    for (let connProtocol of CONNECTION_PROTOCOLS) {
-      if (connProtocol.validServerURI(uri)) {
-        service = connProtocol;
-        break;
-      }
-    }
+    let service = getServiceForServerURI(uri);
     return [service, uri];
   },
 
   _changeServerURL: function(serverURI, event, options = {}) {
     console.debug("changeServerURL()");
 
     switch(event) {
       case UNINIT_EVENT:
--- a/dom/push/PushServiceAndroidGCM.jsm
+++ b/dom/push/PushServiceAndroidGCM.jsm
@@ -1,81 +1,72 @@
-/* jshint moz: true, esnext: true */
 /* 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";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
-const {PushDB} = Cu.import("resource://gre/modules/PushDB.jsm");
-const {PushRecord} = Cu.import("resource://gre/modules/PushRecord.jsm");
-const {PushCrypto} = Cu.import("resource://gre/modules/PushCrypto.jsm");
-Cu.import("resource://gre/modules/Messaging.jsm"); /*global: EventDispatcher */
-Cu.import("resource://gre/modules/Services.jsm"); /*global: Services */
-Cu.import("resource://gre/modules/Preferences.jsm"); /*global: Preferences */
-Cu.import("resource://gre/modules/XPCOMUtils.jsm"); /*global: XPCOMUtils */
+this.EXPORTED_SYMBOLS = ["PushServiceAndroidGCM"];
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-const Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.bind("Push");
-
-this.EXPORTED_SYMBOLS = ["PushServiceAndroidGCM"];
+XPCOMUtils.defineLazyModuleGetter(this, "Messaging",
+                                  "resource://gre/modules/Messaging.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushCrypto",
+                                  "resource://gre/modules/PushCrypto.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushDB",
+                                  "resource://gre/modules/PushDB.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushRecord",
+                                  "resource://gre/modules/PushRecord.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     dump: Log.i,
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushServiceAndroidGCM",
   });
 });
 
+XPCOMUtils.defineLazyGetter(this, "Log", () =>
+  Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.bind("Push")
+);
+
+XPCOMUtils.defineLazyGetter(this, "prefs", () => new Preferences("dom.push."));
+
 const kPUSHANDROIDGCMDB_DB_NAME = "pushAndroidGCM";
 const kPUSHANDROIDGCMDB_DB_VERSION = 5; // Change this if the IndexedDB format changes
 const kPUSHANDROIDGCMDB_STORE_NAME = "pushAndroidGCM";
 
 const FXA_PUSH_SCOPE = "chrome://fxa-push";
 
-const prefs = new Preferences("dom.push.");
-
 /**
  * The implementation of WebPush push backed by Android's GCM
  * delivery.
  */
 this.PushServiceAndroidGCM = {
   _mainPushService: null,
   _serverURI: null,
 
   newPushDB: function() {
     return new PushDB(kPUSHANDROIDGCMDB_DB_NAME,
                       kPUSHANDROIDGCMDB_DB_VERSION,
                       kPUSHANDROIDGCMDB_STORE_NAME,
                       "channelID",
                       PushRecordAndroidGCM);
   },
 
-  validServerURI: function(serverURI) {
-    if (!serverURI) {
-      return false;
-    }
-
-    if (serverURI.scheme == "https") {
-      return true;
-    }
-    if (serverURI.scheme == "http") {
-      // Allow insecure server URLs for development and testing.
-      return !!prefs.get("testing.allowInsecureServerURL");
-    }
-    console.info("Unsupported Android GCM dom.push.serverURL scheme", serverURI.scheme);
-    return false;
-  },
-
   observe: function(subject, topic, data) {
     switch (topic) {
       case "nsPref:changed":
         if (data == "dom.push.debug") {
           // Reconfigure.
           let debug = !!prefs.get("debug");
           console.info("Debug parameter changed; updating configuration with new debug", debug);
           this._configure(this._serverURI, debug);
--- a/dom/push/PushServiceHttp2.jsm
+++ b/dom/push/PushServiceHttp2.jsm
@@ -1,45 +1,45 @@
-/* jshint moz: true, esnext: true */
 /* 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";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
-const {PushDB} = Cu.import("resource://gre/modules/PushDB.jsm");
-const {PushRecord} = Cu.import("resource://gre/modules/PushRecord.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+this.EXPORTED_SYMBOLS = ["PushServiceHttp2"];
+
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-const {
-  PushCrypto,
-  concatArray,
-} = Cu.import("resource://gre/modules/PushCrypto.jsm");
-
-this.EXPORTED_SYMBOLS = ["PushServiceHttp2"];
+XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
+                                  "resource://gre/modules/NetUtil.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushCrypto",
+                                  "resource://gre/modules/PushCrypto.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushDB",
+                                  "resource://gre/modules/PushDB.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushRecord",
+                                  "resource://gre/modules/PushRecord.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushServiceHttp2",
   });
 });
 
-const prefs = new Preferences("dom.push.");
+XPCOMUtils.defineLazyGetter(this, "prefs", () => new Preferences("dom.push."));
 
 const kPUSHHTTP2DB_DB_NAME = "pushHttp2";
 const kPUSHHTTP2DB_DB_VERSION = 5; // Change this if the IndexedDB format changes
 const kPUSHHTTP2DB_STORE_NAME = "pushHttp2";
 
 /**
  * A proxy between the PushService and connections listening for incoming push
  * messages. The PushService can silence messages from the connections by
@@ -150,17 +150,17 @@ PushChannelListener.prototype = {
         this._mainListener &&
         this._mainListener._pushService) {
       let headers = {
         encryption_key: getHeaderField(aRequest, "Encryption-Key"),
         crypto_key: getHeaderField(aRequest, "Crypto-Key"),
         encryption: getHeaderField(aRequest, "Encryption"),
         encoding: getHeaderField(aRequest, "Content-Encoding"),
       };
-      let msg = concatArray(this._message);
+      let msg = PushCrypto.concatArray(this._message);
 
       this._mainListener._pushService._pushChannelOnStop(this._mainListener.uri,
                                                          this._ackUri,
                                                          headers,
                                                          msg);
     }
   }
 };
@@ -425,23 +425,16 @@ this.PushServiceHttp2 = {
                       "subscriptionUri",
                       PushRecordHttp2);
   },
 
   hasmainPushService: function() {
     return this._mainPushService !== null;
   },
 
-  validServerURI: function(serverURI) {
-    if (serverURI.scheme == "http") {
-      return !!prefs.get("testing.allowInsecureServerURL");
-    }
-    return serverURI.scheme == "https";
-  },
-
   connect: function(subscriptions) {
     this.startConnections(subscriptions);
   },
 
   isConnected: function() {
     return this._mainPushService != null;
   },
 
--- a/dom/push/PushServiceWebSocket.jsm
+++ b/dom/push/PushServiceWebSocket.jsm
@@ -1,29 +1,44 @@
-/* jshint moz: true, esnext: true */
 /* 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";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
+this.EXPORTED_SYMBOLS = ["PushServiceWebSocket"];
+
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-const {PushDB} = Cu.import("resource://gre/modules/PushDB.jsm");
-const {PushRecord} = Cu.import("resource://gre/modules/PushRecord.jsm");
-const {PushCrypto} = Cu.import("resource://gre/modules/PushCrypto.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+                                  "resource://gre/modules/AppConstants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+                                  "resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushCrypto",
+                                  "resource://gre/modules/PushCrypto.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushDB",
+                                  "resource://gre/modules/PushDB.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PushRecord",
+                                  "resource://gre/modules/PushRecord.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "console", () => {
+  let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
+  return new ConsoleAPI({
+    maxLogLevelPref: "dom.push.loglevel",
+    prefix: "PushServiceWebSocket",
+  });
+});
+
+XPCOMUtils.defineLazyGetter(this, "prefs", () => new Preferences("dom.push."));
 
 const kPUSHWSDB_DB_NAME = "pushapi";
 const kPUSHWSDB_DB_VERSION = 5; // Change this if the IndexedDB format changes
 const kPUSHWSDB_STORE_NAME = "pushapi";
 
 // WebSocket close code sent by the server to indicate that the client should
 // not automatically reconnect.
 const kBACKOFF_WS_STATUS_CODE = 4774;
@@ -43,28 +58,16 @@ const kUNREGISTER_REASON_TO_CODE = {
 };
 
 const kDELIVERY_REASON_TO_CODE = {
   [Ci.nsIPushErrorReporter.DELIVERY_UNCAUGHT_EXCEPTION]: 301,
   [Ci.nsIPushErrorReporter.DELIVERY_UNHANDLED_REJECTION]: 302,
   [Ci.nsIPushErrorReporter.DELIVERY_INTERNAL_ERROR]: 303,
 };
 
-const prefs = new Preferences("dom.push.");
-
-this.EXPORTED_SYMBOLS = ["PushServiceWebSocket"];
-
-XPCOMUtils.defineLazyGetter(this, "console", () => {
-  let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
-  return new ConsoleAPI({
-    maxLogLevelPref: "dom.push.loglevel",
-    prefix: "PushServiceWebSocket",
-  });
-});
-
 /**
  * A proxy between the PushService and the WebSocket. The listener is used so
  * that the PushService can silence messages from the WebSocket by setting
  * PushWebSocketListener._pushService to null. This is required because
  * a WebSocket can continue to send messages or errors after it has been
  * closed but the PushService may not be interested in these. It's easier to
  * stop listening than to have checks at specific points.
  */
@@ -235,23 +238,16 @@ this.PushServiceWebSocket = {
 
     // The most likely reason for a pong or registration request timing out is
     // that the socket has disconnected. Best to reconnect.
     if (requestTimedOut) {
       this._reconnect();
     }
   },
 
-  validServerURI: function(serverURI) {
-    if (serverURI.scheme == "ws") {
-      return !!prefs.get("testing.allowInsecureServerURL");
-    }
-    return serverURI.scheme == "wss";
-  },
-
   get _UAID() {
     return prefs.get("userAgentID");
   },
 
   set _UAID(newID) {
     if (typeof(newID) !== "string") {
       console.warn("Got invalid, non-string UAID", newID,
         "Not updating userAgentID");
--- a/dom/push/test/xpcshell/head.js
+++ b/dom/push/test/xpcshell/head.js
@@ -12,17 +12,27 @@ Cu.import('resource://gre/modules/Prefer
 Cu.import('resource://gre/modules/PlacesUtils.jsm');
 Cu.import('resource://gre/modules/ObjectUtils.jsm');
 
 XPCOMUtils.defineLazyModuleGetter(this, 'PlacesTestUtils',
                                   'resource://testing-common/PlacesTestUtils.jsm');
 XPCOMUtils.defineLazyServiceGetter(this, 'PushServiceComponent',
                                    '@mozilla.org/push/Service;1', 'nsIPushService');
 
-const serviceExports = Cu.import('resource://gre/modules/PushService.jsm', {});
+const serviceExports = [
+  'PushCrypto',
+  'PushDB',
+  'PushService',
+  'PushServiceWebSocket',
+  'PushServiceHttp2',
+].reduce((exports, name) => {
+  XPCOMUtils.defineLazyModuleGetter(exports, name,
+    `resource://gre/modules/${name}.jsm`);
+  return exports;
+}, {});
 const servicePrefs = new Preferences('dom.push.');
 
 const WEBSOCKET_CLOSE_GOING_AWAY = 1001;
 
 const MS_IN_ONE_DAY = 24 * 60 * 60 * 1000;
 
 var isParent = Cc['@mozilla.org/xre/runtime;1']
                  .getService(Ci.nsIXULRuntime).processType ==