Bug 1077996 - Allow disabling Loop FxA support and related items (contacts, direct calling) via loop.fxa.enabled. r=mikedeboer
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Tue, 07 Oct 2014 00:44:37 -0700
changeset 232334 1ecd8bc300ba6087211349f84c2733680580a5b4
parent 232311 896e255af48ebaf6fc0b5581865fcdbd53e07733
child 232335 4af29b25a7bff2e9b52ec704c47836855aad265c
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1077996
milestone35.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 1077996 - Allow disabling Loop FxA support and related items (contacts, direct calling) via loop.fxa.enabled. r=mikedeboer
browser/components/loop/MozLoopAPI.jsm
browser/components/loop/MozLoopService.jsm
browser/components/loop/content/js/panel.js
browser/components/loop/content/js/panel.jsx
browser/components/loop/test/desktop-local/panel_test.js
--- a/browser/components/loop/MozLoopAPI.jsm
+++ b/browser/components/loop/MozLoopAPI.jsm
@@ -469,16 +469,23 @@ function injectLoopAPI(targetWindow) {
 
     LOOP_SESSION_TYPE: {
       enumerable: true,
       get: function() {
         return Cu.cloneInto(LOOP_SESSION_TYPE, targetWindow);
       }
     },
 
+    fxAEnabled: {
+      enumerable: true,
+      get: function() {
+        return MozLoopService.fxAEnabled;
+      },
+    },
+
     logInToFxA: {
       enumerable: true,
       writable: true,
       value: function() {
         return MozLoopService.logInToFxA();
       }
     },
 
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -80,16 +80,17 @@ XPCOMUtils.defineLazyGetter(this, "log",
 // 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.
 let gRegisteredDeferred = null;
 let gPushHandler = null;
 let gHawkClient = null;
 let gLocalizedStrings =  null;
 let gInitializeTimer = null;
+let gFxAEnabled = true;
 let gFxAOAuthClientPromise = null;
 let gFxAOAuthClient = null;
 let gFxAOAuthTokenData = null;
 let gFxAOAuthProfile = null;
 let gErrors = new Map();
 
  /**
  * Attempts to open a websocket.
@@ -1068,16 +1069,23 @@ this.MozLoopService = {
     Object.freeze(this);
 
     // Don't do anything if loop is not enabled.
     if (!Services.prefs.getBoolPref("loop.enabled") ||
         Services.prefs.getBoolPref("loop.throttled")) {
       return;
     }
 
+    if (Services.prefs.getPrefType("loop.fxa.enabled") == Services.prefs.PREF_BOOL) {
+      gFxAEnabled = Services.prefs.getBoolPref("loop.fxa.enabled");
+      if (!gFxAEnabled) {
+        this.logOutFromFxA();
+      }
+    }
+
     // If expiresTime is in the future then kick-off registration.
     if (MozLoopServiceInternal.urlExpiryTimeIsInFuture()) {
       gInitializeTimerFunc();
     }
   },
 
   /**
    * If we're operating the service in "soft start" mode, and this browser
@@ -1255,16 +1263,20 @@ this.MozLoopService = {
    * Sets MozLoopService "do not disturb" value.
    *
    * @param {Boolean} aFlag
    */
   set doNotDisturb(aFlag) {
     MozLoopServiceInternal.doNotDisturb = aFlag;
   },
 
+  get fxAEnabled() {
+    return gFxAEnabled;
+  },
+
   get userProfile() {
     return gFxAOAuthProfile;
   },
 
   get errors() {
     return MozLoopServiceInternal.errors;
   },
 
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -225,16 +225,22 @@ loop.panel = (function(_, mozL10n) {
     },
 
     _isSignedIn: function() {
       return !!navigator.mozLoop.userProfile;
     },
 
     render: function() {
       var cx = React.addons.classSet;
+
+      // For now all of the menu entries require FxA so hide the whole gear if FxA is disabled.
+      if (!navigator.mozLoop.fxAEnabled) {
+        return null;
+      }
+
       return (
         React.DOM.div({className: "settings-menu dropdown"}, 
           React.DOM.a({className: "button-settings", onClick: this.showDropdownMenu, 
              title: __("settings_menu_button_tooltip")}), 
           React.DOM.ul({className: cx({"dropdown-menu": true, hide: !this.state.showMenu}), 
               onMouseLeave: this.hideDropdownMenu}, 
             SettingsDropdownEntry({label: __("settings_menu_item_settings"), 
                                    onClick: this.handleClickSettingsEntry, 
@@ -243,16 +249,17 @@ loop.panel = (function(_, mozL10n) {
             SettingsDropdownEntry({label: __("settings_menu_item_account"), 
                                    onClick: this.handleClickAccountEntry, 
                                    icon: "account", 
                                    displayed: this._isSignedIn()}), 
             SettingsDropdownEntry({label: this._isSignedIn() ?
                                           __("settings_menu_item_signout") :
                                           __("settings_menu_item_signin"), 
                                    onClick: this.handleClickAuthEntry, 
+                                   displayed: navigator.mozLoop.fxAEnabled, 
                                    icon: this._isSignedIn() ? "signout" : "signin"})
           )
         )
       );
     }
   });
 
   /**
@@ -400,17 +407,17 @@ loop.panel = (function(_, mozL10n) {
    * FxA sign in/up link component.
    */
   var AuthLink = React.createClass({displayName: 'AuthLink',
     handleSignUpLinkClick: function() {
       navigator.mozLoop.logInToFxA();
     },
 
     render: function() {
-      if (navigator.mozLoop.userProfile) {
+      if (!navigator.mozLoop.fxAEnabled || navigator.mozLoop.userProfile) {
         return null;
       }
       return (
         React.DOM.p({className: "signin-link"}, 
           React.DOM.a({href: "#", onClick: this.handleSignUpLinkClick}, 
             __("panel_footer_signin_or_signup_link")
           )
         )
@@ -577,16 +584,17 @@ loop.panel = (function(_, mozL10n) {
     var evtObject = document.createEvent('Event');
     evtObject.initEvent('loopPanelInitialized', true, false);
     window.dispatchEvent(evtObject);
   }
 
   return {
     init: init,
     UserIdentity: UserIdentity,
+    AuthLink: AuthLink,
     AvailabilityDropdown: AvailabilityDropdown,
     CallUrlResult: CallUrlResult,
     PanelView: PanelView,
     SettingsDropdown: SettingsDropdown,
     ToSView: ToSView
   };
 })(_, document.mozL10n);
 
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -225,16 +225,22 @@ loop.panel = (function(_, mozL10n) {
     },
 
     _isSignedIn: function() {
       return !!navigator.mozLoop.userProfile;
     },
 
     render: function() {
       var cx = React.addons.classSet;
+
+      // For now all of the menu entries require FxA so hide the whole gear if FxA is disabled.
+      if (!navigator.mozLoop.fxAEnabled) {
+        return null;
+      }
+
       return (
         <div className="settings-menu dropdown">
           <a className="button-settings" onClick={this.showDropdownMenu}
              title={__("settings_menu_button_tooltip")} />
           <ul className={cx({"dropdown-menu": true, hide: !this.state.showMenu})}
               onMouseLeave={this.hideDropdownMenu}>
             <SettingsDropdownEntry label={__("settings_menu_item_settings")}
                                    onClick={this.handleClickSettingsEntry}
@@ -243,16 +249,17 @@ loop.panel = (function(_, mozL10n) {
             <SettingsDropdownEntry label={__("settings_menu_item_account")}
                                    onClick={this.handleClickAccountEntry}
                                    icon="account"
                                    displayed={this._isSignedIn()} />
             <SettingsDropdownEntry label={this._isSignedIn() ?
                                           __("settings_menu_item_signout") :
                                           __("settings_menu_item_signin")}
                                    onClick={this.handleClickAuthEntry}
+                                   displayed={navigator.mozLoop.fxAEnabled}
                                    icon={this._isSignedIn() ? "signout" : "signin"} />
           </ul>
         </div>
       );
     }
   });
 
   /**
@@ -400,17 +407,17 @@ loop.panel = (function(_, mozL10n) {
    * FxA sign in/up link component.
    */
   var AuthLink = React.createClass({
     handleSignUpLinkClick: function() {
       navigator.mozLoop.logInToFxA();
     },
 
     render: function() {
-      if (navigator.mozLoop.userProfile) {
+      if (!navigator.mozLoop.fxAEnabled || navigator.mozLoop.userProfile) {
         return null;
       }
       return (
         <p className="signin-link">
           <a href="#" onClick={this.handleSignUpLinkClick}>
             {__("panel_footer_signin_or_signup_link")}
           </a>
         </p>
@@ -577,16 +584,17 @@ loop.panel = (function(_, mozL10n) {
     var evtObject = document.createEvent('Event');
     evtObject.initEvent('loopPanelInitialized', true, false);
     window.dispatchEvent(evtObject);
   }
 
   return {
     init: init,
     UserIdentity: UserIdentity,
+    AuthLink: AuthLink,
     AvailabilityDropdown: AvailabilityDropdown,
     CallUrlResult: CallUrlResult,
     PanelView: PanelView,
     SettingsDropdown: SettingsDropdown,
     ToSView: ToSView
   };
 })(_, document.mozL10n);
 
--- a/browser/components/loop/test/desktop-local/panel_test.js
+++ b/browser/components/loop/test/desktop-local/panel_test.js
@@ -20,16 +20,17 @@ describe("loop.panel", function() {
     // https://github.com/cjohansen/Sinon.JS/issues/393
     fakeXHR.xhr.onCreate = function (xhr) {
       requests.push(xhr);
     };
     notifications = new loop.shared.models.NotificationCollection();
 
     navigator.mozLoop = {
       doNotDisturb: true,
+      fxAEnabled: true,
       getStrings: function() {
         return JSON.stringify({textContent: "fakeText"});
       },
       get locale() {
         return "en-US";
       },
       setLoopCharPref: sandbox.stub(),
       getLoopCharPref: sandbox.stub().returns("unseen"),
@@ -172,27 +173,49 @@ describe("loop.panel", function() {
           navigator.mozLoop.loggedInToFxA = false;
           navigator.mozLoop.logInToFxA = sandbox.stub();
 
           TestUtils.Simulate.click(
             view.getDOMNode().querySelector(".signin-link a"));
 
           sinon.assert.calledOnce(navigator.mozLoop.logInToFxA);
         });
+
+      it("should be hidden if FxA is not enabled",
+        function() {
+          navigator.mozLoop.fxAEnabled = false;
+          var view = TestUtils.renderIntoDocument(loop.panel.AuthLink());
+          expect(view.getDOMNode()).to.be.null;
       });
 
+      afterEach(function() {
+        navigator.mozLoop.fxAEnabled = true;
+      });
+    });
+
     describe("SettingsDropdown", function() {
       var view;
 
       beforeEach(function() {
         navigator.mozLoop.logInToFxA = sandbox.stub();
         navigator.mozLoop.logOutFromFxA = sandbox.stub();
         navigator.mozLoop.openFxASettings = sandbox.stub();
       });
 
+      afterEach(function() {
+        navigator.mozLoop.fxAEnabled = true;
+      });
+
+      it("should be hidden if FxA is not enabled",
+        function() {
+          navigator.mozLoop.fxAEnabled = false;
+          var view = TestUtils.renderIntoDocument(loop.panel.SettingsDropdown());
+          expect(view.getDOMNode()).to.be.null;
+      });
+
       it("should show a signin entry when user is not authenticated",
         function() {
           navigator.mozLoop.loggedInToFxA = false;
 
           var view = TestUtils.renderIntoDocument(loop.panel.SettingsDropdown());
 
           expect(view.getDOMNode().querySelectorAll(".icon-signout"))
             .to.have.length.of(0);