diff --git a/browser/base/content/browser-fxaccounts.js b/browser/base/content/browser-fxaccounts.js index ba1519b57928..c4284d8f42ef 100644 --- a/browser/base/content/browser-fxaccounts.js +++ b/browser/base/content/browser-fxaccounts.js @@ -110,14 +110,7 @@ let gFxAccounts = { // notified of fxa-migration:state-changed in response if necessary. Services.obs.notifyObservers(null, "fxa-migration:state-request", null); - let contentUri = Services.urlFormatter.formatURLPref("identity.fxaccounts.remote.webchannel.uri"); - // The FxAccountsWebChannel listens for events and updates - // the state machine accordingly. - let fxAccountsWebChannel = new FxAccountsWebChannel({ - content_uri: contentUri, - channel_id: this.FxAccountsCommon.WEBCHANNEL_ID - }); - + EnsureFxAccountsWebChannel(); this._initialized = true; this.updateUI(); @@ -482,5 +475,5 @@ XPCOMUtils.defineLazyGetter(gFxAccounts, "FxAccountsCommon", function () { XPCOMUtils.defineLazyModuleGetter(gFxAccounts, "fxaMigrator", "resource://services-sync/FxaMigrator.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsWebChannel", +XPCOMUtils.defineLazyModuleGetter(this, "EnsureFxAccountsWebChannel", "resource://gre/modules/FxAccountsWebChannel.jsm"); diff --git a/browser/base/content/test/general/browser_fxa_web_channel.js b/browser/base/content/test/general/browser_fxa_web_channel.js index 85af29238a9b..c511ffd8b491 100644 --- a/browser/base/content/test/general/browser_fxa_web_channel.js +++ b/browser/base/content/test/general/browser_fxa_web_channel.js @@ -12,8 +12,9 @@ XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () { XPCOMUtils.defineLazyModuleGetter(this, "WebChannel", "resource://gre/modules/WebChannel.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsWebChannel", - "resource://gre/modules/FxAccountsWebChannel.jsm"); +// FxAccountsWebChannel isn't explicitly exported by FxAccountsWebChannel.jsm +// but we can get it here via a backstage pass. +let {FxAccountsWebChannel} = Components.utils.import("resource://gre/modules/FxAccountsWebChannel.jsm", {}); const TEST_HTTP_PATH = "http://example.com"; const TEST_BASE_URL = TEST_HTTP_PATH + "/browser/browser/base/content/test/general/browser_fxa_web_channel.html"; diff --git a/services/fxaccounts/FxAccountsWebChannel.jsm b/services/fxaccounts/FxAccountsWebChannel.jsm index 10247bb244fe..f1163890ec40 100644 --- a/services/fxaccounts/FxAccountsWebChannel.jsm +++ b/services/fxaccounts/FxAccountsWebChannel.jsm @@ -9,7 +9,7 @@ * about account state changes. */ -this.EXPORTED_SYMBOLS = ["FxAccountsWebChannel"]; +this.EXPORTED_SYMBOLS = ["EnsureFxAccountsWebChannel"]; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; @@ -311,3 +311,21 @@ this.FxAccountsWebChannelHelpers.prototype = { return pressed === 0; // 0 is the "continue" button } }; + +let singleton; +// The entry-point for this module, which ensures only one of our channels is +// ever created - we require this because the WebChannel is global in scope +// (eg, it uses the observer service to tell interested parties of interesting +// things) and allowing multiple channels would cause such notifications to be +// sent multiple times. +this.EnsureFxAccountsWebChannel = function() { + if (!singleton) { + let contentUri = Services.urlFormatter.formatURLPref("identity.fxaccounts.remote.webchannel.uri"); + // The FxAccountsWebChannel listens for events and updates + // the state machine accordingly. + singleton = new this.FxAccountsWebChannel({ + content_uri: contentUri, + channel_id: WEBCHANNEL_ID, + }); + } +}