Backed out changeset 19ae3d5f6884 (bug 1038648) for failures in test_loopservice_initialize.js
authorEd Morley <emorley@mozilla.com>
Wed, 23 Jul 2014 17:04:24 +0100
changeset 195690 42bb5d45012416ee83fd07b77f7986a1fc423215
parent 195689 cade5f2e7c84aa8b4057fc0bd51b76c9a486be3b
child 195707 c4db6f9060f68b19778a6d1c1528b6b492df0c79
push id27190
push userryanvm@gmail.com
push dateWed, 23 Jul 2014 19:14:34 +0000
treeherdermozilla-central@42bb5d450124 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1038648
milestone34.0a1
backs out19ae3d5f6884627775ba17686b636f135ea871a0
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
Backed out changeset 19ae3d5f6884 (bug 1038648) for failures in test_loopservice_initialize.js
browser/components/loop/MozLoopAPI.jsm
browser/components/loop/MozLoopService.jsm
--- a/browser/components/loop/MozLoopAPI.jsm
+++ b/browser/components/loop/MozLoopAPI.jsm
@@ -28,46 +28,49 @@ function injectLoopAPI(targetWindow) {
   let ringerStopper;
 
   let api = {
     /**
      * Sets and gets the "do not disturb" mode activation flag.
      */
     doNotDisturb: {
       enumerable: true,
+      configurable: true,
       get: function() {
         return MozLoopService.doNotDisturb;
       },
       set: function(aFlag) {
         MozLoopService.doNotDisturb = aFlag;
       }
     },
 
     /**
      * Returns the current locale of the browser.
      *
      * @returns {String} The locale string
      */
     locale: {
       enumerable: true,
+      configurable: true,
       get: function() {
         return MozLoopService.locale;
       }
     },
 
     /**
      * Returns translated strings associated with an element. Designed
      * for use with l10n.js
      *
      * @param {String} key The element id
      * @returns {Object} A JSON string containing the localized
      *                   attribute/value pairs for the element.
      */
     getStrings: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function(key) {
         return MozLoopService.getStrings(key);
       }
     },
 
     /**
      * Call to ensure that any necessary registrations for the Loop Service
@@ -77,16 +80,17 @@ function injectLoopAPI(targetWindow) {
      * - err null on successful registration, non-null otherwise.
      *
      * @param {Function} callback Will be called once registration is complete,
      *                            or straight away if registration has already
      *                            happened.
      */
     ensureRegistered: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function(callback) {
         // We translate from a promise to a callback, as we can't pass promises from
         // Promise.jsm across the priv versus unpriv boundary.
         return MozLoopService.register().then(() => {
           callback(null);
         }, err => {
           callback(err);
@@ -103,16 +107,17 @@ function injectLoopAPI(targetWindow) {
      * This is used to determine whether or not we should be registering with the
      * push server on start.
      *
      * @param {Integer} expiryTimeSeconds The seconds since epoch of the expiry time
      *                                    of the url.
      */
     noteCallUrlExpiry: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function(expiryTimeSeconds) {
         MozLoopService.noteCallUrlExpiry(expiryTimeSeconds);
       }
     },
 
     /**
      * Set any character preference under "loop."
@@ -120,16 +125,17 @@ function injectLoopAPI(targetWindow) {
      * @param {String} prefName The name of the pref without the preceding "loop."
      * @param {String} stringValue The value to set.
      *
      * Any errors thrown by the Mozilla pref API are logged to the console
      * and cause false to be returned.
      */
     setLoopCharPref: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function(prefName, value) {
         MozLoopService.setLoopCharPref(prefName, value);
       }
     },
 
     /**
      * Return any preference under "loop." that's coercible to a character
@@ -141,27 +147,29 @@ function injectLoopAPI(targetWindow) {
      * Any errors thrown by the Mozilla pref API are logged to the console
      * and cause null to be returned. This includes the case of the preference
      * not being found.
      *
      * @return {String} on success, null on error
      */
     getLoopCharPref: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function(prefName) {
         return MozLoopService.getLoopCharPref(prefName);
       }
     },
 
     /**
      * Starts alerting the user about an incoming call
      */
     startAlerting: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function() {
         let chromeWindow = getChromeWindow(targetWindow);
         chromeWindow.getAttention();
         ringer = new chromeWindow.Audio();
         ringer.src = Services.prefs.getCharPref("loop.ringtone");
         ringer.loop = true;
         ringer.load();
@@ -175,16 +183,17 @@ function injectLoopAPI(targetWindow) {
       }
     },
 
     /**
      * Stops alerting the user about an incoming call
      */
     stopAlerting: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function() {
         if (ringerStopper) {
           targetWindow.document.removeEventListener("visibilitychange",
                                                     ringerStopper);
           ringerStopper = null;
         }
         if (ringer) {
@@ -210,31 +219,31 @@ function injectLoopAPI(targetWindow) {
      * @param {String} path The path to make the request to.
      * @param {String} method The request method, e.g. 'POST', 'GET'.
      * @param {Object} payloadObj An object which is converted to JSON and
      *                            transmitted with the request.
      * @param {Function} callback Called when the request completes.
      */
     hawkRequest: {
       enumerable: true,
+      configurable: true,
       writable: true,
       value: function(path, method, payloadObj, callback) {
         // XXX Should really return a DOM promise here.
         return MozLoopService.hawkRequest(path, method, payloadObj).then((response) => {
           callback(null, response.body);
         }, (error) => {
           callback(Cu.cloneInto(error, targetWindow));
         });
       }
     },
   };
 
   let contentObj = Cu.createObjectIn(targetWindow);
   Object.defineProperties(contentObj, api);
-  Object.seal(contentObj);
   Cu.makeObjectPropsNormal(contentObj);
 
   targetWindow.navigator.wrappedJSObject.__defineGetter__("mozLoop", function() {
     // We do this in a getter, so that we create these objects
     // only on demand (this is a potential concern, since
     // otherwise we might add one per iframe, and keep them
     // alive for as long as the window is alive).
     delete targetWindow.navigator.wrappedJSObject.mozLoop;
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -42,33 +42,26 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
                                   "resource:///modules/loop/MozLoopPushHandler.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
                                    "@mozilla.org/uuid-generator;1",
                                    "nsIUUIDGenerator");
 
-let gRegisteredDeferred = null;
-let gPushHandler = null;
-let gHawkClient = null;
-let gRegisteredLoopServer = false;
-let gLocalizedStrings =  null;
-let gInitializeTimer = null;
-
 /**
  * Internal helper methods and state
  *
  * The registration is a two-part process. First we need to connect to
  * and register with the push server. Then we need to take the result of that
  * and register with the Loop server.
  */
 let MozLoopServiceInternal = {
   // The uri of the Loop server.
-  get loopServerUri() Services.prefs.getCharPref("loop.server"),
+  loopServerUri: Services.prefs.getCharPref("loop.server"),
 
   // The current deferred for the registration process. This is set if in progress
   // or the registration was successful. This is null if a registration attempt was
   // unsuccessful.
   _registeredDeferred: null,
 
   /**
    * The initial delay for push registration. This ensures we don't start
@@ -139,28 +132,28 @@ let MozLoopServiceInternal = {
    * with the Loop server. It will return early if already registered.
    *
    * @param {Object} mockPushHandler Optional, test-only mock push handler. Used
    *                                 to allow mocking of the MozLoopPushHandler.
    * @returns {Promise} a promise that is resolved with no params on completion, or
    *          rejected with an error code or string.
    */
   promiseRegisteredWithServers: function(mockPushHandler) {
-    if (gRegisteredDeferred) {
-      return gRegisteredDeferred.promise;
+    if (this._registeredDeferred) {
+      return this._registeredDeferred.promise;
     }
 
-    gRegisteredDeferred = Promise.defer();
+    this._registeredDeferred = Promise.defer();
     // We grab the promise early in case .initialize or its results sets
     // it back to null on error.
-    let result = gRegisteredDeferred.promise;
+    let result = this._registeredDeferred.promise;
 
-    gPushHandler = mockPushHandler || MozLoopPushHandler;
+    this._pushHandler = mockPushHandler || MozLoopPushHandler;
 
-    gPushHandler.initialize(this.onPushRegistered.bind(this),
+    this._pushHandler.initialize(this.onPushRegistered.bind(this),
       this.onHandleNotification.bind(this));
 
     return result;
   },
 
   /**
    * Performs a hawk based request to the loop server.
    *
@@ -170,35 +163,35 @@ let MozLoopServiceInternal = {
    *                            transmitted with the request.
    * @returns {Promise}
    *        Returns a promise that resolves to the response of the API call,
    *        or is rejected with an error.  If the server response can be parsed
    *        as JSON and contains an 'error' property, the promise will be
    *        rejected with this JSON-parsed response.
    */
   hawkRequest: function(path, method, payloadObj) {
-    if (!gHawkClient) {
-      gHawkClient = new HawkClient(this.loopServerUri);
+    if (!this._hawkClient) {
+      this._hawkClient = new HawkClient(this.loopServerUri);
     }
 
     let sessionToken;
     try {
       sessionToken = Services.prefs.getCharPref("loop.hawk-session-token");
     } catch (x) {
       // It is ok for this not to exist, we'll default to sending no-creds
     }
 
     let credentials;
     if (sessionToken) {
       // true = use a hex key, as required by the server (see bug 1032738).
       credentials = deriveHawkCredentials(sessionToken, "sessionToken",
                                           2 * 32, true);
     }
 
-    return gHawkClient.request(path, method, credentials, payloadObj);
+    return this._hawkClient.request(path, method, credentials, payloadObj);
   },
 
   /**
    * Used to store a session token from a request if it exists in the headers.
    *
    * @param {Object} headers The request headers, which may include a
    *                         "hawk-session-token" to be saved.
    * @return true on success or no token, false on failure.
@@ -207,34 +200,34 @@ let MozLoopServiceInternal = {
     let sessionToken = headers["hawk-session-token"];
     if (sessionToken) {
       // XXX should do more validation here
       if (sessionToken.length === 64) {
         Services.prefs.setCharPref("loop.hawk-session-token", sessionToken);
       } else {
         // XXX Bubble the precise details up to the UI somehow (bug 1013248).
         console.warn("Loop server sent an invalid session token");
-        gRegisteredDeferred.reject("session-token-wrong-size");
-        gRegisteredDeferred = null;
+        this._registeredDeferred.reject("session-token-wrong-size");
+        this._registeredDeferred = null;
         return false;
       }
     }
     return true;
   },
 
   /**
    * Callback from MozLoopPushHandler - The push server has been registered
    * and has given us a push url.
    *
    * @param {String} pushUrl The push url given by the push server.
    */
   onPushRegistered: function(err, pushUrl) {
     if (err) {
-      gRegisteredDeferred.reject(err);
-      gRegisteredDeferred = null;
+      this._registeredDeferred.reject(err);
+      this._registeredDeferred = null;
       return;
     }
 
     this.registerWithLoopServer(pushUrl);
   },
 
   /**
    * Registers with the Loop server.
@@ -246,17 +239,18 @@ let MozLoopServiceInternal = {
     this.hawkRequest("/registration", "POST", { simple_push_url: pushUrl})
       .then((response) => {
         // If this failed we got an invalid token. storeSessionToken rejects
         // the _registeredDeferred promise for us, so here we just need to
         // early return.
         if (!this.storeSessionToken(response.headers))
           return;
 
-        gRegisteredDeferred.resolve();
+        this.registeredLoopServer = true;
+        this._registeredDeferred.resolve();
         // No need to clear the promise here, everything was good, so we don't need
         // to re-register.
       }, (error) => {
         // There's other errors than invalid auth token, but we should only do the reset
         // as a last resort.
         if (error.code === 401 && error.errno === INVALID_AUTH_TOKEN) {
           if (this.urlExpiryTimeIsInFuture()) {
             // XXX Should this be reported to the user is a visible manner?
@@ -267,18 +261,18 @@ let MozLoopServiceInternal = {
           // Authorization failed, invalid token, we need to try again with a new token.
           Services.prefs.clearUserPref("loop.hawk-session-token");
           this.registerWithLoopServer(pushUrl, true);
           return;
         }
 
         // XXX Bubble the precise details up to the UI somehow (bug 1013248).
         Cu.reportError("Failed to register with the loop server. error: " + error);
-        gRegisteredDeferred.reject(error.errno);
-        gRegisteredDeferred = null;
+        this._registeredDeferred.reject(error.errno);
+        this._registeredDeferred = null;
       }
     );
   },
 
   /**
    * Callback from MozLoopPushHandler - A push notification has been received from
    * the server.
    *
@@ -294,18 +288,18 @@ let MozLoopServiceInternal = {
 
   /**
    * A getter to obtain and store the strings for loop. This is structured
    * for use by l10n.js.
    *
    * @returns {Object} a map of element ids with attributes to set.
    */
   get localizedStrings() {
-    if (gLocalizedStrings)
-      return gLocalizedStrings;
+    if (this._localizedStrings)
+      return this._localizedStrings;
 
     var stringBundle =
       Services.strings.createBundle('chrome://browser/locale/loop/loop.properties');
 
     var map = {};
     var enumerator = stringBundle.getSimpleEnumeration();
     while (enumerator.hasMoreElements()) {
       var string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
@@ -317,17 +311,17 @@ let MozLoopServiceInternal = {
         property = key.substring(i + 1);
         key = key.substring(0, i);
       }
       if (!(key in map))
         map[key] = {};
       map[key][property] = string.value;
     }
 
-    return gLocalizedStrings = map;
+    return this._localizedStrings = map;
   },
 
   /**
    * Saves loop logs to the saved-telemetry-pings folder.
    *
    * @param {Object} pc The peerConnection in question.
    */
   stageForTelemetryUpload: function(window, pc) {
@@ -446,17 +440,16 @@ let MozLoopServiceInternal = {
         let pc_static = new window.mozRTCPeerConnectionStatic();
         pc_static.registerPeerConnectionLifecycleCallback(onPCLifecycleChange);
       }.bind(this), true);
     };
 
     Chat.open(contentWindow, origin, title, url, undefined, undefined, callback);
   }
 };
-Object.freeze(MozLoopServiceInternal);
 
 /**
  * Public API
  */
 this.MozLoopService = {
   /**
    * Initialized the loop service, and starts registration with the
    * push and loop servers.
@@ -476,20 +469,20 @@ this.MozLoopService = {
   /**
    * Internal function, exposed for testing purposes only. Used to start the
    * initialize timer.
    */
   _startInitializeTimer: function() {
     // Kick off the push notification service into registering after a timeout
     // this ensures we're not doing too much straight after the browser's finished
     // starting up.
-    gInitializeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    gInitializeTimer.initWithCallback(function() {
+    this._initializeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    this._initializeTimer.initWithCallback(function() {
       this.register();
-      gInitializeTimer = null;
+      this._initializeTimer = null;
     }.bind(this),
     MozLoopServiceInternal.initialRegistrationDelayMilliseconds, Ci.nsITimer.TYPE_ONE_SHOT);
   },
 
   /**
    * Starts registration of Loop with the push server, and then will register
    * with the Loop server. It will return early if already registered.
    *
@@ -625,9 +618,8 @@ this.MozLoopService = {
    *        or is rejected with an error.  If the server response can be parsed
    *        as JSON and contains an 'error' property, the promise will be
    *        rejected with this JSON-parsed response.
    */
   hawkRequest: function(path, method, payloadObj) {
     return MozLoopServiceInternal.hawkRequest(path, method, payloadObj);
   },
 };
-Object.freeze(this.MozLoopService);