Bug 863598 - SimplePush: Make PushService a module. r=dougt
authorNikhil Marathe <nsm.nikhil@gmail.com>
Thu, 02 May 2013 10:45:18 +0530
changeset 141499 ea6b923829e17e7de913b18dd47785c044fa0cd5
parent 141498 d28a41f49785503bfe30ae6c44e0f7f233ac0346
child 141500 e474b6cfebce4bc92055737bc1331ad002d7d0c1
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs863598
milestone23.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 863598 - SimplePush: Make PushService a module. r=dougt
b2g/chrome/content/shell.js
b2g/installer/package-manifest.in
dom/push/src/Makefile.in
dom/push/src/PushService.js
dom/push/src/PushService.jsm
dom/push/src/PushService.manifest
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -7,16 +7,17 @@
 Cu.import('resource://gre/modules/ContactService.jsm');
 Cu.import('resource://gre/modules/SettingsChangeNotifier.jsm');
 #ifdef MOZ_B2G_FM
 Cu.import('resource://gre/modules/DOMFMRadioParent.jsm');
 #endif
 Cu.import('resource://gre/modules/AlarmService.jsm');
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
 Cu.import('resource://gre/modules/PermissionPromptHelper.jsm');
+Cu.import('resource://gre/modules/PushService.jsm');
 Cu.import('resource://gre/modules/ObjectWrapper.jsm');
 Cu.import('resource://gre/modules/accessibility/AccessFu.jsm');
 Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 #ifdef MOZ_B2G_RIL
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -505,18 +505,16 @@
 @BINPATH@/components/TelemetryPing.js
 @BINPATH@/components/TelemetryPing.manifest
 @BINPATH@/components/Webapps.js
 @BINPATH@/components/Webapps.manifest
 @BINPATH@/components/AppsService.js
 @BINPATH@/components/AppsService.manifest
 @BINPATH@/components/Push.js
 @BINPATH@/components/Push.manifest
-@BINPATH@/components/PushService.js
-@BINPATH@/components/PushService.manifest
 
 @BINPATH@/components/nsDOMIdentity.js
 @BINPATH@/components/nsIDService.js
 @BINPATH@/components/Identity.manifest
 
 @BINPATH@/components/SystemMessageInternal.js
 @BINPATH@/components/SystemMessageManager.js
 @BINPATH@/components/SystemMessageManager.manifest
--- a/dom/push/src/Makefile.in
+++ b/dom/push/src/Makefile.in
@@ -7,14 +7,16 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_COMPONENTS = \
   Push.js \
   Push.manifest \
-  PushService.js \
-  PushService.manifest \
+  $(NULL)
+
+EXTRA_JS_MODULES = \
+  PushService.jsm \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
rename from dom/push/src/PushService.js
rename to dom/push/src/PushService.jsm
--- a/dom/push/src/PushService.js
+++ b/dom/push/src/PushService.jsm
@@ -1,30 +1,32 @@
 /* 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";
 
 function debug(s) {
-  // dump("-*- PushService.js: " + s + "\n");
+  // dump("-*- PushService.jsm: " + s + "\n");
 }
 
 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/Services.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/commonjs/sdk/core/promise.js");
 
+this.EXPORTED_SYMBOLS = ["PushService"];
+
 const prefs = new Preferences("services.push.");
 
 const kPUSHDB_DB_NAME = "push";
 const kPUSHDB_DB_VERSION = 1; // Change this if the IndexedDB format changes
 const kPUSHDB_STORE_NAME = "push";
 const kCONFLICT_RETRY_ATTEMPTS = 3; // If channelID registration says 409, how
                                     // many times to retry with a new channelID
 
@@ -256,57 +258,35 @@ this.PushWebSocketListener.prototype = {
 
   onServerClose: function(context, aStatusCode, aReason) {
     if (!this._pushService)
         return;
     this._pushService._wsOnServerClose(context, aStatusCode, aReason);
   }
 }
 
-/**
- * The implementation of the SimplePush system. This runs in the B2G parent
- * process and is started on boot. It uses WebSockets to communicate with the
- * server and PushDB (IndexedDB) for persistence.
- */
-function PushService()
-{
-  debug("PushService Constructor.");
-}
-
 // websocket states
 // websocket is off
 const STATE_SHUT_DOWN = 0;
 // websocket has been opened on client side, waiting for successful open
 // (_wsOnStart)
 const STATE_WAITING_FOR_WS_START = 1;
 // websocket opened, hello sent, waiting for server reply (_handleHelloReply)
 const STATE_WAITING_FOR_HELLO = 2;
 // websocket operational, handshake completed, begin protocol messaging
 const STATE_READY = 3;
 
-PushService.prototype = {
-  classID : Components.ID("{0ACE8D15-9B15-41F4-992F-C88820421DBF}"),
-
-  QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
-                                          Ci.nsIUDPServerSocketListener]),
-
+/**
+ * The implementation of the SimplePush system. This runs in the B2G parent
+ * process and is started on boot. It uses WebSockets to communicate with the
+ * server and PushDB (IndexedDB) for persistence.
+ */
+this.PushService = {
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
-      case "app-startup":
-
-        if (!prefs.get("enabled"))
-          return;
-
-        Services.obs.addObserver(this, "final-ui-startup", false);
-        Services.obs.addObserver(this, "profile-change-teardown", false);
-        Services.obs.addObserver(this,
-                                 "network-interface-state-changed",
-                                 false);
-        Services.obs.addObserver(this, "webapps-uninstall", false);
-        break;
       case "final-ui-startup":
         Services.obs.removeObserver(this, "final-ui-startup");
         this.init();
         break;
       case "profile-change-teardown":
         Services.obs.removeObserver(this, "profile-change-teardown");
         this._shutdown();
         break;
@@ -378,16 +358,17 @@ PushService.prototype = {
               debug("Had a connection, so telling the server");
               this._request("unregister", {channelID: records[i].channelID});
             }
           }
         }.bind(this), function() {
           debug("Error in getAllByManifestURL: url " + app.manifestURL);
         });
 
+        break;
     }
   },
 
   get _UAID() {
     return prefs.get("userAgentID");
   },
 
   set _UAID(newID) {
@@ -437,16 +418,23 @@ PushService.prototype = {
    * shouldn't re-establish the connection. If the server says that it will
    * wake up the client over UDP, this is set to true in wsOnServerClose. It is
    * checked in wsOnStop.
    */
   _willBeWokenUpByUDP: false,
 
   init: function() {
     debug("init()");
+    if (!prefs.get("enabled"))
+        return null;
+
+    Services.obs.addObserver(this, "profile-change-teardown", false);
+    Services.obs.addObserver(this, "network-interface-state-changed",
+                             false);
+    Services.obs.addObserver(this, "webapps-uninstall", false);
     this._db = new PushDB(this);
 
     let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
                  .getService(Ci.nsIMessageBroadcaster);
 
     kCHILD_PROCESS_MESSAGES.forEach(function addMessage(msgName) {
         ppmm.addMessageListener(msgName, this);
     }.bind(this));
@@ -482,28 +470,44 @@ PushService.prototype = {
     try {
         this._ws.close(0, null);
     } catch (e) {}
     this._ws = null;
   },
 
   _shutdown: function() {
     debug("_shutdown()");
-    this._db.close();
-    this._db = null;
+
+    Services.obs.removeObserver(this, "network-interface-state-changed",
+                                false);
+    Services.obs.removeObserver(this, "webapps-uninstall", false);
+
+    if (this._db) {
+      this._db.close();
+      this._db = null;
+    }
 
     if (this._udpServer) {
       this._udpServer.close();
     }
 
     // All pending requests (ideally none) are dropped at this point. We
     // shouldn't have any applications performing registration/unregistration
     // or receiving notifications.
     this._shutdownWS();
 
+    // At this point, profile-change-net-teardown has already fired, so the
+    // WebSocket has been closed with NS_ERROR_ABORT (if it was up) and will
+    // try to reconnect. Stop the timer.
+    if (this._retryTimeoutTimer)
+      this._retryTimeoutTimer.cancel();
+
+    if (this._requestTimeoutTimer)
+      this._requestTimeoutTimer.cancel();
+
     debug("shutdown complete!");
   },
 
   // aStatusCode is an NS error from Components.results
   _socketError: function(aStatusCode) {
     debug("socketError()");
 
     // Calculate new timeout, but cap it to
@@ -1168,16 +1172,17 @@ PushService.prototype = {
    * This statusCode is not the websocket protocol status code, but the TCP
    * connection close status code.
    *
    * If we do not explicitly call ws.close() then statusCode is always
    * NS_BASE_STREAM_CLOSED, even on a successful close.
    */
   _wsOnStop: function(context, statusCode) {
     debug("wsOnStop()");
+
     if (statusCode != Cr.NS_OK &&
         !(statusCode == Cr.NS_BASE_STREAM_CLOSED && this._willBeWokenUpByUDP)) {
       debug("Socket error " + statusCode);
       this._socketError(statusCode);
     }
 
     this._shutdownWS();
   },
@@ -1315,9 +1320,9 @@ PushService.prototype = {
     return {
       mcc: 0,
       mnc: 0,
       ip: undefined
     };
   }
 }
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PushService]);
+PushService.init();
deleted file mode 100644
--- a/dom/push/src/PushService.manifest
+++ /dev/null
@@ -1,4 +0,0 @@
-component {0ACE8D15-9B15-41F4-992F-C88820421DBF} PushService.js
-contract @mozilla.org/PushService;1 {0ACE8D15-9B15-41F4-992F-C88820421DBF}
-category app-startup PushService service,@mozilla.org/PushService;1
-