Bug 1232222 - provide telemetry environment data on which addons are system addons r=gfritzsche
authorRobert Helmer <rhelmer@mozilla.com>
Sat, 13 Feb 2016 17:51:26 -0800
changeset 284198 516dc8aba9a54404ff581537b6a4e22aa56154df
parent 284197 45cc53e68f351ab049e00f068eb45c6f185b055a
child 284199 aac6e363269c48888ab5dde3a3f4611a73a895fc
push id29999
push usercbook@mozilla.com
push dateMon, 15 Feb 2016 11:11:49 +0000
treeherdermozilla-central@9e38b1048c07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfritzsche
bugs1232222
milestone47.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 1232222 - provide telemetry environment data on which addons are system addons r=gfritzsche MozReview-Commit-ID: 89M0HnzfIrd
toolkit/components/telemetry/TelemetryEnvironment.jsm
toolkit/components/telemetry/docs/environment.rst
toolkit/components/telemetry/tests/unit/head.js
toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
toolkit/components/telemetry/tests/unit/xpcshell.ini
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -535,16 +535,17 @@ EnvironmentAddonBuilder.prototype = {
           version: limitStringToLength(addon.version, MAX_ADDON_STRING_LENGTH),
           scope: addon.scope,
           type: addon.type,
           foreignInstall: addon.foreignInstall,
           hasBinaryComponents: addon.hasBinaryComponents,
           installDay: Utils.millisecondsToDays(installDate.getTime()),
           updateDay: Utils.millisecondsToDays(updateDate.getTime()),
           signedState: addon.signedState,
+          isSystem: addon.isSystem,
         };
 
         if (addon.signedState !== undefined)
           activeAddons[addon.id].signedState = addon.signedState;
 
       } catch (ex) {
         this._environment._log.error("_getActiveAddons - An addon was discarded due to an error", ex);
         continue;
--- a/toolkit/components/telemetry/docs/environment.rst
+++ b/toolkit/components/telemetry/docs/environment.rst
@@ -190,16 +190,17 @@ Structure::
             version: <string>,
             scope: <integer>,
             type: <string>, // "extension", "service", ...
             foreignInstall: <bool>,
             hasBinaryComponents: <bool>
             installDay: <number>, // days since UNIX epoch, 0 on failure
             updateDay: <number>, // days since UNIX epoch, 0 on failure
             signedState: <integer>, // whether the add-on is signed by AMO, only present for extensions
+            isSystem: <bool>, // true if this is a System Add-on
           },
           ...
         },
         theme: { // the active theme
           id: <string>,
           blocklisted: <bool>,
           description: <string>,
           name: <string>,
--- a/toolkit/components/telemetry/tests/unit/head.js
+++ b/toolkit/components/telemetry/tests/unit/head.js
@@ -161,16 +161,20 @@ function wrapWithExceptionHandler(f) {
 function loadAddonManager(id, name, version, platformVersion) {
   let ns = {};
   Cu.import("resource://gre/modules/Services.jsm", ns);
   let head = "../../../../mozapps/extensions/test/xpcshell/head_addons.js";
   let file = do_get_file(head);
   let uri = ns.Services.io.newFileURI(file);
   ns.Services.scriptloader.loadSubScript(uri.spec, gGlobalScope);
   createAppInfo(id, name, version, platformVersion);
+  // As we're not running in application, we need to setup the features directory
+  // used by system add-ons.
+  const distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "app0"], true);
+  registerDirectory("XREAppFeat", distroDir);
   startupManager();
 }
 
 function createAppInfo(id, name, version, platformVersion) {
   const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
   const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
   let gAppInfo;
   if (!gOldAppInfo) {
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -4,16 +4,17 @@
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/TelemetryEnvironment.jsm", this);
 Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/PromiseUtils.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://testing-common/AddonManagerTesting.jsm");
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://testing-common/MockRegistrar.jsm", this);
+Cu.import("resource://gre/modules/FileUtils.jsm");
 
 // Lazy load |LightweightThemeManager|, we won't be using it on Gonk.
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
                                   "resource://gre/modules/LightweightThemeManager.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ProfileAge",
                                   "resource://gre/modules/ProfileAge.jsm");
 
@@ -62,16 +63,19 @@ const PLUGIN2_VERSION = "2.3";
 const PERSONA_ID = "3785";
 // Defined by LightweightThemeManager, it is appended to the PERSONA_ID.
 const PERSONA_ID_SUFFIX = "@personas.mozilla.org";
 const PERSONA_NAME = "Test Theme";
 const PERSONA_DESCRIPTION = "A nice theme/persona description.";
 
 const PLUGIN_UPDATED_TOPIC     = "plugins-list-updated";
 
+// system add-ons are enabled at startup, so record date when the test starts
+const SYSTEM_ADDON_INSTALL_DATE = Date.now();
+
 /**
  * Used to mock plugin tags in our fake plugin host.
  */
 function PluginTag(aName, aDescription, aVersion, aEnabled) {
   this.name = aName;
   this.description = aDescription;
   this.version = aVersion;
   this.disabled = !aEnabled;
@@ -566,29 +570,35 @@ function checkSystemSection(data) {
 
     let features = gfxInfo.getFeatures();
     Assert.equal(features.compositor, gfxData.features.compositor);
   }
   catch (e) {}
 }
 
 function checkActiveAddon(data){
+  let signedState = mozinfo.addon_signing ? "number" : "undefined";
+  // system add-ons have an undefined signState
+  if (data.isSystem)
+    signedState = "undefined";
+
   const EXPECTED_ADDON_FIELDS_TYPES = {
     blocklisted: "boolean",
     name: "string",
     userDisabled: "boolean",
     appDisabled: "boolean",
     version: "string",
     scope: "number",
     type: "string",
     foreignInstall: "boolean",
     hasBinaryComponents: "boolean",
     installDay: "number",
     updateDay: "number",
-    signedState: mozinfo.addon_signing ? "number" : "undefined",
+    signedState: signedState,
+    isSystem: "boolean",
   };
 
   for (let f in EXPECTED_ADDON_FIELDS_TYPES) {
     Assert.ok(f in data, f + " must be available.");
     Assert.equal(typeof data[f], EXPECTED_ADDON_FIELDS_TYPES[f],
                  f + " must have the correct type.");
   }
 
@@ -710,16 +720,23 @@ function checkEnvironmentData(data, isIn
 }
 
 function run_test() {
   // Load a custom manifest to provide search engine loading from JAR files.
   do_load_manifest("chrome.manifest");
   do_test_pending();
   spoofGfxAdapter();
   do_get_profile();
+
+  // The system add-on must be installed before AddonManager is started.
+  const distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "app0"], true);
+  do_get_file("system.xpi").copyTo(distroDir, "tel-system-xpi@tests.mozilla.org.xpi");
+  let system_addon = FileUtils.File(distroDir.path);
+  system_addon.append("tel-system-xpi@tests.mozilla.org.xpi");
+  system_addon.lastModifiedTime = SYSTEM_ADDON_INSTALL_DATE;
   loadAddonManager(APP_ID, APP_NAME, APP_VERSION, PLATFORM_VERSION);
 
   // Spoof the persona ID, but not on Gonk.
   if (!gIsGonk) {
     LightweightThemeManager.currentTheme =
       spoofTheme(PERSONA_ID, PERSONA_NAME, PERSONA_DESCRIPTION);
   }
   // Register a fake plugin host for consistent flash version data.
@@ -1011,16 +1028,34 @@ add_task(function* test_addonsAndPlugins
     version: "1.0",
     scope: 1,
     type: "extension",
     foreignInstall: false,
     hasBinaryComponents: false,
     installDay: ADDON_INSTALL_DATE,
     updateDay: ADDON_INSTALL_DATE,
     signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_SIGNED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
+    isSystem: false,
+  };
+  const SYSTEM_ADDON_ID = "tel-system-xpi@tests.mozilla.org";
+  const EXPECTED_SYSTEM_ADDON_DATA = {
+    blocklisted: false,
+    description: "A system addon which is shipped with Firefox.",
+    name: "XPI Telemetry System Add-on Test",
+    userDisabled: false,
+    appDisabled: false,
+    version: "1.0",
+    scope: 1,
+    type: "extension",
+    foreignInstall: false,
+    hasBinaryComponents: false,
+    installDay: truncateToDays(SYSTEM_ADDON_INSTALL_DATE),
+    updateDay: truncateToDays(SYSTEM_ADDON_INSTALL_DATE),
+    signedState: undefined,
+    isSystem: true,
   };
 
   const EXPECTED_PLUGIN_DATA = {
     name: FLASH_PLUGIN_NAME,
     version: FLASH_PLUGIN_VERSION,
     description: FLASH_PLUGIN_DESC,
     blocklisted: false,
     disabled: false,
@@ -1035,16 +1070,23 @@ add_task(function* test_addonsAndPlugins
 
   // Check addon data.
   Assert.ok(ADDON_ID in data.addons.activeAddons, "We must have one active addon.");
   let targetAddon = data.addons.activeAddons[ADDON_ID];
   for (let f in EXPECTED_ADDON_DATA) {
     Assert.equal(targetAddon[f], EXPECTED_ADDON_DATA[f], f + " must have the correct value.");
   }
 
+  // Check system add-on data.
+  Assert.ok(SYSTEM_ADDON_ID in data.addons.activeAddons, "We must have one active system addon.");
+  let targetSystemAddon = data.addons.activeAddons[SYSTEM_ADDON_ID];
+  for (let f in EXPECTED_SYSTEM_ADDON_DATA) {
+    Assert.equal(targetSystemAddon[f], EXPECTED_SYSTEM_ADDON_DATA[f], f + " must have the correct value.");
+  }
+
   // Check theme data.
   let theme = data.addons.theme;
   Assert.equal(theme.id, (PERSONA_ID + PERSONA_ID_SUFFIX));
   Assert.equal(theme.name, PERSONA_NAME);
   Assert.equal(theme.description, PERSONA_DESCRIPTION);
 
   // Check plugin data.
   Assert.equal(data.addons.activePlugins.length, 1, "We must have only one active plugin.");
--- a/toolkit/components/telemetry/tests/unit/xpcshell.ini
+++ b/toolkit/components/telemetry/tests/unit/xpcshell.ini
@@ -7,23 +7,25 @@ skip-if = toolkit == 'gonk'
 # xpcshell fails to install tests if we move them under the test entry.
 support-files =
   ../search/chrome.manifest
   ../search/searchTest.jar
   dictionary.xpi
   experiment.xpi
   extension.xpi
   extension-2.xpi
+  system.xpi
   restartless.xpi
   theme.xpi
 generated-files =
   dictionary.xpi
   experiment.xpi
   extension.xpi
   extension-2.xpi
+  system.xpi
   restartless.xpi
   theme.xpi
 
 [test_nsITelemetry.js]
 [test_SubsessionChaining.js]
 tags = addons
 [test_TelemetryEnvironment.js]
 skip-if = os == "android"