bug 1232222 - provide telemetry environment data on which addons are system addons r=gfritzsche
MozReview-Commit-ID: 89M0HnzfIrd
--- 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"