Bug 1418131: Part 3 - Add Windows Security Center info to telemetry environment; r?gfritzsche draft
authorAaron Klotz <aklotz@mozilla.com>
Thu, 16 Nov 2017 18:10:41 -0700
changeset 720750 7485f172bc03db53654c4026708ccfa0d3818480
parent 720749 b4883101f3274df55b4f0331331e1e3ec6cf053c
child 746136 dfef8e18aa092d9ea67dd6493b72ac7d61129a32
push id95621
push useraklotz@mozilla.com
push dateTue, 16 Jan 2018 05:54:07 +0000
reviewersgfritzsche
bugs1418131
milestone59.0a1
Bug 1418131: Part 3 - Add Windows Security Center info to telemetry environment; r?gfritzsche MozReview-Commit-ID: 3Cw7XIrROTn
toolkit/components/telemetry/TelemetryEnvironment.jsm
toolkit/components/telemetry/docs/data/environment.rst
toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -1593,16 +1593,41 @@ EnvironmentCache.prototype = {
       system:  { // hdd where the system files are located
         model: getSysinfoProperty("winHDDModel", null),
         revision: getSysinfoProperty("winHDDRevision", null),
       },
     };
   },
 
   /**
+   * Get registered security product information.
+   * @return Object containing the security product data
+   */
+  _getSecurityAppData() {
+    const maxStringLength = 256;
+
+    const keys = [ ["registeredAntiVirus", "antivirus"],
+                   ["registeredAntiSpyware", "antispyware"],
+                   ["registeredFirewall", "firewall"] ];
+
+    let result = {};
+
+    for (let [inKey, outKey] of keys) {
+      let prop = getSysinfoProperty(inKey, null);
+      if (prop) {
+        prop = limitStringToLength(prop, maxStringLength).split(";");
+      }
+
+      result[outKey] = prop;
+    }
+
+    return result;
+  },
+
+  /**
    * Get the GFX information.
    * @return Object containing the GFX data.
    */
   _getGFXData() {
     let gfxData = {
       D2DEnabled: getGfxField("D2DEnabled", null),
       DWriteEnabled: getGfxField("DWriteEnabled", null),
       ContentBackend: getGfxField("ContentBackend", null),
@@ -1679,16 +1704,21 @@ EnvironmentCache.prototype = {
     };
 
     if (AppConstants.platform === "win") {
       data.isWow64 = getSysinfoProperty("isWow64", null);
     } else if (AppConstants.platform == "android") {
       data.device = this._getDeviceData();
     }
 
+    // Windows 8+
+    if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2")) {
+      data.sec = this._getSecurityAppData();
+    }
+
     return data;
   },
 
   _onEnvironmentChange(what, oldEnvironment) {
     this._log.trace("_onEnvironmentChange for " + what);
 
     // We are already skipping change events in _checkChanges if there is a pending change task running.
     if (this._shutdown) {
--- a/toolkit/components/telemetry/docs/data/environment.rst
+++ b/toolkit/components/telemetry/docs/data/environment.rst
@@ -197,16 +197,21 @@ Structure:
                 status: <string>, // "Available" means currently in use
               },
               advancedLayers: { // Advanced Layers compositing. Only present if D3D11 enabled.
                 status: <string>,    // See the status codes above.
               },
             },
           },
         appleModelId: <string>, // Mac only or null on failure
+        sec: { // This feature is Windows 8+ only
+          antivirus: [ <string>, ... ],    // null if unavailable on platform: Product name(s) of registered antivirus programs
+          antispyware: [ <string>, ... ],  // null if unavailable on platform: Product name(s) of registered antispyware programs
+          firewall: [ <string>, ... ],     // null if unavailable on platform: Product name(s) of registered firewall programs
+        },
       },
       addons: {
         activeAddons: { // the currently enabled add-ons
           <addon id>: {
             blocklisted: <bool>,
             description: <string>, // null if not available
             name: <string>,
             userDisabled: <bool>,
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -661,16 +661,35 @@ function checkSystemSection(data) {
     Assert.equal(features.webgl, gfxData.features.webgl);
   } catch (e) {}
 
   if (gIsMac) {
     Assert.ok(checkString(data.system.appleModelId));
   } else {
     Assert.ok(checkNullOrString(data.system.appleModelId));
   }
+
+  // This feature is only available on Windows 8+
+  if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2")) {
+    Assert.ok("sec" in data.system, "sec must be available under data.system");
+
+    let SEC_FIELDS = ["antivirus", "antispyware", "firewall"];
+    for (let f of SEC_FIELDS) {
+      Assert.ok(f in data.system.sec, f + " must be available under data.system.sec");
+
+      let value = data.system.sec[f];
+      // value is null on Windows Server
+      Assert.ok(value === null || Array.isArray(value), f + " must be either null or an array");
+      if (Array.isArray(value)) {
+        for (let product of value) {
+          Assert.equal(typeof product, "string", "Each element of " + f + " must be a string");
+        }
+      }
+    }
+  }
 }
 
 function checkActiveAddon(data, partialRecord) {
   let signedState = mozinfo.addon_signing ? "number" : "undefined";
   // system add-ons have an undefined signState
   if (data.isSystem)
     signedState = "undefined";