Bug 1443829 - Implement stub Enterprise Policies Manager component for non-browser apps. r=Gijs draft
authorFelipe Gomes <felipc@gmail.com>
Tue, 13 Mar 2018 01:50:28 -0300
changeset 766599 33e59c5e8a86364ab0f3494ad12d756465cb82db
parent 766597 6ff60a083701d08c52702daf50f28e8f46ae3a1c
push id102368
push userfelipc@gmail.com
push dateTue, 13 Mar 2018 04:51:02 +0000
reviewersGijs
bugs1443829
milestone61.0a1
Bug 1443829 - Implement stub Enterprise Policies Manager component for non-browser apps. r=Gijs Implement a stub implementation so that non-browser code doesn't need to keep checking for the existence of this component. This stub implementation will always return status as inactive, and true to any isAllowed call. MozReview-Commit-ID: CmHUb34LhfF
browser/base/content/aboutDialog-appUpdater.js
browser/components/enterprisepolicies/EnterprisePolicies.js
browser/components/preferences/in-content/main.js
toolkit/components/enterprisepolicies/EnterprisePoliciesStub.js
toolkit/components/enterprisepolicies/EnterprisePoliciesStub.manifest
toolkit/components/enterprisepolicies/moz.build
toolkit/content/aboutSupport.js
toolkit/modules/Services.jsm
toolkit/modules/Troubleshoot.jsm
toolkit/modules/tests/browser/browser_Troubleshoot.js
toolkit/modules/tests/xpcshell/test_Services.js
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
toolkit/mozapps/update/nsUpdateService.js
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -134,18 +134,17 @@ appUpdater.prototype =
     return this.um.activeUpdate &&
            this.um.activeUpdate.state == "downloading";
   },
 
   // true when updating is disabled by an administrator.
   get updateDisabledAndLocked() {
     return (!this.updateEnabled &&
            Services.prefs.prefIsLocked("app.update.enabled")) ||
-           (Services.policies &&
-           !Services.policies.isAllowed("appUpdate"));
+           !Services.policies.isAllowed("appUpdate");
   },
 
   // true when updating is enabled.
   get updateEnabled() {
     try {
       return Services.prefs.getBoolPref("app.update.enabled");
     } catch (e) { }
     return true; // Firefox default is true
--- a/browser/components/enterprisepolicies/EnterprisePolicies.js
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.js
@@ -42,48 +42,33 @@ XPCOMUtils.defineLazyGetter(this, "log",
     prefix: "Enterprise Policies",
     // tip: set maxLogLevel to "debug" and use log.debug() to create detailed
     // messages during development. See LOG_LEVELS in Console.jsm for details.
     maxLogLevel: "error",
     maxLogLevelPref: PREF_LOGLEVEL,
   });
 });
 
-// ==== Start XPCOM Boilerplate ==== \\
-
-// Factory object
-const EnterprisePoliciesFactory = {
-  _instance: null,
-  createInstance: function BGSF_createInstance(outer, iid) {
-    if (outer != null)
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    return this._instance == null ?
-      this._instance = new EnterprisePoliciesManager() : this._instance;
-  }
-};
-
-// ==== End XPCOM Boilerplate ==== //
-
 // Constructor
 function EnterprisePoliciesManager() {
   Services.obs.addObserver(this, "profile-after-change", true);
   Services.obs.addObserver(this, "final-ui-startup", true);
   Services.obs.addObserver(this, "sessionstore-windows-restored", true);
   Services.obs.addObserver(this, "EnterprisePolicies:Restart", true);
 }
 
 EnterprisePoliciesManager.prototype = {
   // for XPCOM
   classID:          Components.ID("{ea4e1414-779b-458b-9d1f-d18e8efbc145}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference,
                                          Ci.nsIEnterprisePolicies]),
 
   // redefine the default factory for XPCOMUtils
-  _xpcom_factory: EnterprisePoliciesFactory,
+  _xpcom_factory: XPCOMUtils.generateSingletonFactory(EnterprisePoliciesManager),
 
   _initialize() {
     if (!Services.prefs.getBoolPref(PREF_ENABLED, false)) {
       this.status = Ci.nsIEnterprisePolicies.INACTIVE;
       return;
     }
 
     let provider = this._chooseProvider();
@@ -229,17 +214,17 @@ EnterprisePoliciesManager.prototype = {
     });
 
     await PromiseUtils.idleDispatch(() => {
       this.observe(null, "sessionstore-windows-restored", null);
     });
   },
 
   // nsIObserver implementation
-  observe: function BG_observe(subject, topic, data) {
+  observe(subject, topic, data) {
     switch (topic) {
       case "policies-startup":
         // Before the first set of policy callbacks runs, we must
         // initialize the service.
         this._initialize();
 
         this._runPoliciesCallbacks("onBeforeAddons");
         break;
@@ -301,17 +286,17 @@ EnterprisePoliciesManager.prototype = {
     }
     return val;
   },
 
   get status() {
     return this._status;
   },
 
-  isAllowed: function BG_sanitize(feature) {
+  isAllowed(feature) {
     return !(feature in DisallowedFeatures);
   },
 };
 
 let DisallowedFeatures = {};
 
 /**
  * areEnterpriseOnlyPoliciesAllowed
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -1417,18 +1417,17 @@ var gMainPane = {
    *                   i     t/f    *t*     *true*
    *                   ii    t/f    f       false
    *                   ii    t/f    *t*     *true*
    */
   updateReadPrefs() {
     if (AppConstants.MOZ_UPDATER) {
       var enabledPref = Preferences.get("app.update.enabled");
       var autoPref = Preferences.get("app.update.auto");
-      let disabledByPolicy = Services.policies &&
-                             !Services.policies.isAllowed("appUpdate");
+      let disabledByPolicy = !Services.policies.isAllowed("appUpdate");
       var radiogroup = document.getElementById("updateRadioGroup");
 
       if (!enabledPref.value || disabledByPolicy) // Don't care for autoPref.value in this case.
         radiogroup.value = "manual"; // 3. Never check for updates.
       else if (autoPref.value) // enabledPref.value && autoPref.value
         radiogroup.value = "auto"; // 1. Automatically install updates
       else // enabledPref.value && !autoPref.value
         radiogroup.value = "checkOnly"; // 2. Check, but let me choose
@@ -1464,18 +1463,17 @@ var gMainPane = {
       }
     }
   },
 
   /**
    * Sets the pref values based on the selected item of the radiogroup.
    */
   updateWritePrefs() {
-    let disabledByPolicy = Services.policies &&
-                           !Services.policies.isAllowed("appUpdate");
+    let disabledByPolicy = !Services.policies.isAllowed("appUpdate");
     if (AppConstants.MOZ_UPDATER && !disabledByPolicy) {
       var enabledPref = Preferences.get("app.update.enabled");
       var autoPref = Preferences.get("app.update.auto");
       var radiogroup = document.getElementById("updateRadioGroup");
       switch (radiogroup.value) {
         case "auto": // 1. Automatically install updates for Desktop only
           enabledPref.value = true;
           autoPref.value = true;
new file mode 100644
--- /dev/null
+++ b/toolkit/components/enterprisepolicies/EnterprisePoliciesStub.js
@@ -0,0 +1,36 @@
+/* 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/. */
+
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// Constructor
+function EnterprisePoliciesManager() {
+}
+
+EnterprisePoliciesManager.prototype = {
+  // for XPCOM
+  classID:          Components.ID("{c34982d6-a4f0-4924-9cda-da1c10e2555a}"),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+                                         Ci.nsISupportsWeakReference,
+                                         Ci.nsIEnterprisePolicies]),
+
+  // redefine the default factory for XPCOMUtils
+  _xpcom_factory: XPCOMUtils.generateSingletonFactory(EnterprisePoliciesManager),
+
+  // nsIObserver implementation
+  observe(subject, topic, data) {
+  },
+
+  // nsIEnterprisePolicies implementation
+  get status() {
+    return Ci.nsIEnterprisePolicies.INACTIVE;
+  },
+
+  isAllowed(feature) {
+    return true;
+  },
+};
+
+var components = [EnterprisePoliciesManager];
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
new file mode 100644
--- /dev/null
+++ b/toolkit/components/enterprisepolicies/EnterprisePoliciesStub.manifest
@@ -0,0 +1,3 @@
+component {c34982d6-a4f0-4924-9cda-da1c10e2555a} EnterprisePoliciesStub.js
+contract @mozilla.org/browser/enterprisepolicies;1 {c34982d6-a4f0-4924-9cda-da1c10e2555a}
+
--- a/toolkit/components/enterprisepolicies/moz.build
+++ b/toolkit/components/enterprisepolicies/moz.build
@@ -6,9 +6,17 @@
 
 with Files("**"):
     BUG_COMPONENT = ("Firefox", "Enterprise Policies")
 
 XPIDL_SOURCES += [
     'nsIEnterprisePolicies.idl',
 ]
 
+if CONFIG['MOZ_BUILD_APP'] != 'browser':
+    EXTRA_COMPONENTS += [
+        'EnterprisePoliciesStub.js',
+        'EnterprisePoliciesStub.manifest',
+    ]
+
+FINAL_LIBRARY = 'xul'
+
 XPIDL_MODULE = 'enterprisepolicies'
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -96,17 +96,17 @@ var snapshotFormatters = {
                                               data.styloChromeDefault);
     }
     styloReason = strings.GetStringFromName(styloReason);
     styloChromeReason = strings.GetStringFromName(styloChromeReason);
     $("stylo-box").textContent =
       `content = ${data.styloResult} (${styloReason}), ` +
       `chrome = ${data.styloChromeResult} (${styloChromeReason})`;
 
-    if (Services.policies) {
+    if (AppConstants.MOZ_BUILD_APP == "browser") {
       let policiesText = "";
       switch (data.policiesStatus) {
         case Services.policies.INACTIVE:
           policiesText = strings.GetStringFromName("policies.inactive");
           break;
 
         case Services.policies.ACTIVE:
           policiesText = strings.GetStringFromName("policies.active");
--- a/toolkit/modules/Services.jsm
+++ b/toolkit/modules/Services.jsm
@@ -79,16 +79,17 @@ var initTable = {
   droppedLinkHandler: ["@mozilla.org/content/dropped-link-handler;1", "nsIDroppedLinkHandler"],
   els: ["@mozilla.org/eventlistenerservice;1", "nsIEventListenerService"],
   eTLD: ["@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"],
   intl: ["@mozilla.org/mozintl;1", "mozIMozIntl"],
   locale: ["@mozilla.org/intl/localeservice;1", "mozILocaleService"],
   logins: ["@mozilla.org/login-manager;1", "nsILoginManager"],
   obs: ["@mozilla.org/observer-service;1", "nsIObserverService"],
   perms: ["@mozilla.org/permissionmanager;1", "nsIPermissionManager"],
+  policies: ["@mozilla.org/browser/enterprisepolicies;1", "nsIEnterprisePolicies"],
   prompt: ["@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService"],
   scriptloader: ["@mozilla.org/moz/jssubscript-loader;1", "mozIJSSubScriptLoader"],
   scriptSecurityManager: ["@mozilla.org/scriptsecuritymanager;1", "nsIScriptSecurityManager"],
   storage: ["@mozilla.org/storage/service;1", "mozIStorageService"],
   domStorageManager: ["@mozilla.org/dom/localStorage-manager;1", "nsIDOMStorageManager"],
   strings: ["@mozilla.org/intl/stringbundle;1", "nsIStringBundleService"],
   telemetry: ["@mozilla.org/base/telemetry;1", "nsITelemetry"],
   textToSubURI: ["@mozilla.org/intl/texttosuburi;1", "nsITextToSubURI"],
@@ -113,15 +114,12 @@ if (AppConstants.platform == "android") 
   initTable.androidBridge = ["@mozilla.org/android/bridge;1", "nsIAndroidBridge"];
 }
 if (AppConstants.MOZ_GECKO_PROFILER) {
   initTable.profiler = ["@mozilla.org/tools/profiler;1", "nsIProfiler"];
 }
 if (AppConstants.MOZ_TOOLKIT_SEARCH) {
   initTable.search = ["@mozilla.org/browser/search-service;1", "nsIBrowserSearchService"];
 }
-if ("@mozilla.org/browser/enterprisepolicies;1" in Cc) {
-  initTable.policies = ["@mozilla.org/browser/enterprisepolicies;1", "nsIEnterprisePolicies"];
-}
 
 XPCOMUtils.defineLazyServiceGetters(Services, initTable);
 
 initTable = undefined;
--- a/toolkit/modules/Troubleshoot.jsm
+++ b/toolkit/modules/Troubleshoot.jsm
@@ -246,19 +246,17 @@ var dataProviders = {
     data.styloChromeResult = false;
     if (data.styloResult) {
       let winUtils = Services.wm.getMostRecentWindow("").
                      QueryInterface(Ci.nsIInterfaceRequestor).
                      getInterface(Ci.nsIDOMWindowUtils);
       data.styloChromeResult = winUtils.isStyledByServo;
     }
 
-    if (Services.policies) {
-      data.policiesStatus = Services.policies.status;
-    }
+    data.policiesStatus = Services.policies.status;
 
     const keyGoogle = Services.urlFormatter.formatURL("%GOOGLE_API_KEY%").trim();
     data.keyGoogleFound = keyGoogle != "no-google-api-key" && keyGoogle.length > 0;
 
     const keyMozilla = Services.urlFormatter.formatURL("%MOZILLA_API_KEY%").trim();
     data.keyMozillaFound = keyMozilla != "no-mozilla-api-key" && keyMozilla.length > 0;
 
     done(data);
--- a/toolkit/modules/tests/browser/browser_Troubleshoot.js
+++ b/toolkit/modules/tests/browser/browser_Troubleshoot.js
@@ -156,16 +156,17 @@ const SNAPSHOT_SCHEMA = {
         styloChromeDefault: {
           type: "boolean",
         },
         styloChromeResult: {
           type: "boolean",
         },
         policiesStatus: {
           type: "number",
+          required: true,
         },
         keyGoogleFound: {
           type: "boolean",
         },
         keyMozillaFound: {
           type: "boolean",
         },
         safeMode: {
--- a/toolkit/modules/tests/xpcshell/test_Services.js
+++ b/toolkit/modules/tests/xpcshell/test_Services.js
@@ -37,16 +37,17 @@ function run_test() {
   checkService("eTLD", Ci.nsIEffectiveTLDService);
   checkService("focus", Ci.nsIFocusManager);
   checkService("io", Ci.nsIIOService);
   checkService("intl", Ci.mozIMozIntl);
   checkService("locale", Ci.mozILocaleService);
   checkService("logins", Ci.nsILoginManager);
   checkService("obs", Ci.nsIObserverService);
   checkService("perms", Ci.nsIPermissionManager);
+  checkService("policies", Ci.nsIEnterprisePolicies);
   checkService("prefs", Ci.nsIPrefBranch);
   checkService("prefs", Ci.nsIPrefService);
   checkService("prompt", Ci.nsIPromptService);
   checkService("scriptSecurityManager", Ci.nsIScriptSecurityManager);
   checkService("scriptloader", Ci.mozIJSSubScriptLoader);
   checkService("startup", Ci.nsIAppStartup);
   checkService("storage", Ci.mozIStorageService);
   checkService("strings", Ci.nsIStringBundleService);
@@ -59,20 +60,16 @@ function run_test() {
   checkService("wm", Ci.nsIWindowMediator);
   checkService("ww", Ci.nsIWindowWatcher);
   if ("nsIBrowserSearchService" in Ci) {
     checkService("search", Ci.nsIBrowserSearchService);
   }
   if ("nsIAndroidBridge" in Ci) {
     checkService("androidBridge", Ci.nsIAndroidBridge);
   }
-  if ("@mozilla.org/browser/enterprisepolicies;1" in Cc) {
-    checkService("policies", Ci.nsIEnterprisePolicies);
-  }
-
 
   // In xpcshell tests, the "@mozilla.org/xre/app-info;1" component implements
   // only the nsIXULRuntime interface, but not nsIXULAppInfo.  To test the
   // service getter for the latter interface, load mock app-info.
   let tmp = {};
   ChromeUtils.import("resource://testing-common/AppInfo.jsm", tmp);
   tmp.updateAppInfo();
 
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -1326,20 +1326,17 @@ var AddonManagerInternal = {
   },
 
   // Returns true if System Addons should be updated
   systemUpdateEnabled() {
     if (!Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED) ||
         !Services.prefs.getBoolPref(PREF_APP_UPDATE_AUTO)) {
       return false;
     }
-    if (Services.policies && !Services.policies.isAllowed("SysAddonUpdate")) {
-      return false;
-    }
-    return true;
+    return Services.policies.isAllowed("SysAddonUpdate");
   },
 
   /**
    * Performs a background update check by starting an update for all add-ons
    * that can be updated.
    * @return Promise{null} Resolves when the background update check is complete
    *                       (the resulting addon installations may still be in progress).
    */
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -30,16 +30,17 @@ tags = blocklist
 [test_shutdown.js]
 [test_system_update_blank.js]
 fail-if = os == 'win' && ccov
 [test_system_update_checkSizeHash.js]
 [test_system_update_custom.js]
 [test_system_update_empty.js]
 skip-if = true # Failing intermittently due to a race condition in the test, see bug 1348981
 [test_system_update_enterprisepolicy.js]
+# The policies toolkit stub doesn't actually implement the behavior to block system addon updates
 skip-if = appname == "thunderbird"
 [test_system_update_fail.js]
 [test_system_update_newset.js]
 [test_system_update_overlapping.js]
 [test_system_update_upgrades.js]
 [test_system_repository.js]
 [test_system_reset.js]
 [test_XPIcancel.js]
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -532,17 +532,17 @@ XPCOMUtils.defineLazyGetter(this, "gCanC
   // getter since locked prefs don't change until the application is restarted.
   var enabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED, true);
   if (!enabled && Services.prefs.prefIsLocked(PREF_APP_UPDATE_ENABLED)) {
     LOG("gCanCheckForUpdates - unable to automatically check for updates, " +
         "the preference is disabled and admistratively locked.");
     return false;
   }
 
-  if (Services.policies && !Services.policies.isAllowed("appUpdate")) {
+  if (!Services.policies.isAllowed("appUpdate")) {
     LOG("gCanCheckForUpdates - unable to automatically check for updates. " +
         "Functionality disabled by enterprise policy.");
     return false;
   }
 
   // If we don't know the binary platform we're updating, we can't update.
   if (!UpdateUtils.ABI) {
     LOG("gCanCheckForUpdates - unable to check for updates, unknown ABI");