Bug 1540112 - Enable addonsManager telemetry event category before the AddonManager/XPIProvider have been started. r=aswan,chutten
authorLuca Greco <lgreco@mozilla.com>
Wed, 03 Apr 2019 17:56:52 +0000
changeset 467812 1e40ddd945d1f48c3461ea8ab7570d98a29cf95c
parent 467811 1e0d7f61ff5b278c911a255dba3d3daad830698e
child 467813 903c6563775ad6ec3185ba5743ba69d5a1650c2e
push id35810
push useraciure@mozilla.com
push dateThu, 04 Apr 2019 04:33:36 +0000
treeherdermozilla-central@b72c02e34261 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan, chutten
bugs1540112
milestone68.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 1540112 - Enable addonsManager telemetry event category before the AddonManager/XPIProvider have been started. r=aswan,chutten Differential Revision: https://phabricator.services.mozilla.com/D25380
browser/components/extensions/test/browser/browser_ext_browserAction_contextMenu.js
toolkit/components/extensions/test/xpcshell/test_ext_incognito.js
toolkit/mozapps/extensions/AddonManager.jsm
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_contextMenu.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_contextMenu.js
@@ -65,16 +65,21 @@ function assertTelemetryMatches(events) 
     .filter(([timestamp, category, method]) =>
       category == TELEMETRY_CATEGORY && TELEMETRY_METHODS.has(method))
     .map(relatedEvent => relatedEvent.slice(2, 6));
 
   // Events are now [method, object, value, extra] as expected.
   Assert.deepEqual(relatedEvents, events, "The events are recorded correctly");
 }
 
+add_task(async function test_setup() {
+  // Clear any previosuly collected telemetry event.
+  Services.telemetry.snapshotEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true);
+});
+
 add_task(async function browseraction_popup_contextmenu() {
   let extension = ExtensionTestUtils.loadExtension(extData);
   await extension.startup();
 
   await clickBrowserAction(extension, window);
 
   let contentAreaContextMenu = await openContextMenuInPopup(extension);
   let item = contentAreaContextMenu.getElementsByAttribute("label", "Click me!");
--- a/toolkit/components/extensions/test/xpcshell/test_ext_incognito.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_incognito.js
@@ -3,23 +3,30 @@
 "use strict";
 
 const {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 
 AddonTestUtils.init(this);
 AddonTestUtils.overrideCertDB();
 AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
 AddonTestUtils.usePrivilegedSignatures = false;
-AddonTestUtils.hookAMTelemetryEvents();
 
 // Assert on the expected "addonsManager.action" telemetry events (and optional filter events to verify
 // by using a given actionType).
 function assertActionAMTelemetryEvent(expectedActionEvents, assertMessage, {actionType} = {}) {
-  const events = AddonTestUtils.getAMTelemetryEvents().filter(({method, extra}) => {
-    return method === "action" && (!actionType ? true : extra && extra.action === actionType);
+  const snapshot = Services.telemetry.snapshotEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true);
+
+  ok(snapshot.parent && snapshot.parent.length > 0, "Got parent telemetry events in the snapshot");
+
+  const events = snapshot.parent.filter(([timestamp, category, method, object, value, extra]) => {
+    return category === "addonsManager" && method === "action" && (
+      !actionType ? true : extra && extra.action === actionType
+    );
+  }).map(([timestamp, category, method, object, value, extra]) => {
+    return {method, object, value, extra};
   });
 
   Assert.deepEqual(events, expectedActionEvents, assertMessage);
 }
 
 async function runIncognitoTest(extensionData, privateBrowsingAllowed, allowPrivateBrowsingByDefault) {
   Services.prefs.setBoolPref("extensions.allowPrivateBrowsingByDefault", allowPrivateBrowsingByDefault);
 
@@ -67,92 +74,94 @@ add_task(async function test_extension_i
 // incognito type prior to feature being turned on.
 add_task(async function test_extension_incognito_spanning_grandfathered() {
   await AddonTestUtils.promiseStartupManager();
   Services.prefs.setBoolPref("extensions.allowPrivateBrowsingByDefault", true);
   Services.prefs.setBoolPref("extensions.incognito.migrated", false);
 
   // This extension gets disabled before the "upgrade", it should not
   // get grandfathered permissions.
+  const disabledAddonId = "disabled-ext@mozilla.com";
   let disabledWrapper = ExtensionTestUtils.loadExtension({
     manifest: {
-      applications: {gecko: {id: "@disabled"}},
+      applications: {gecko: {id: disabledAddonId}},
       incognito: "spanning",
     },
     useAddonManager: "permanent",
   });
   await disabledWrapper.startup();
-  let disabledPolicy = WebExtensionPolicy.getByID("@disabled");
+  let disabledPolicy = WebExtensionPolicy.getByID(disabledAddonId);
 
   // Verify policy settings.
   equal(disabledPolicy.permissions.includes("internal:privateBrowsingAllowed"), false,
         "privateBrowsingAllowed is not in permissions for disabled addon");
   equal(disabledPolicy.privateBrowsingAllowed, true,
         "privateBrowsingAllowed in disabled addon");
 
-  let disabledAddon = await AddonManager.getAddonByID("@disabled");
+  let disabledAddon = await AddonManager.getAddonByID(disabledAddonId);
   await disabledAddon.disable();
 
   // This extension gets grandfathered permissions for private browsing.
-  let id = "@grandfathered";
+  let addonId = "grandfathered@mozilla.com";
   let wrapper = ExtensionTestUtils.loadExtension({
     manifest: {
-      applications: {gecko: {id}},
+      applications: {gecko: {id: addonId}},
       incognito: "spanning",
     },
     useAddonManager: "permanent",
   });
   await wrapper.startup();
-  let policy = WebExtensionPolicy.getByID(id);
+  let policy = WebExtensionPolicy.getByID(addonId);
 
   // Verify policy settings.
   equal(policy.permissions.includes("internal:privateBrowsingAllowed"), false,
         "privateBrowsingAllowed is not in permissions");
   equal(policy.privateBrowsingAllowed, true,
         "privateBrowsingAllowed in extension");
 
   // Turn on incognito support and update the browser.
   Services.prefs.setBoolPref("extensions.allowPrivateBrowsingByDefault", false);
+  // Disable the addonsManager telemetry event category, to ensure that it will
+  // be enabled automatically during the AddonManager/XPIProvider startup and
+  // the telemetry event recorded (See Bug 1540112 for a rationale).
+  Services.telemetry.setEventRecordingEnabled("addonsManager", false);
   await AddonTestUtils.promiseRestartManager("2");
   await wrapper.awaitStartup();
 
   // Did it upgrade?
   ok(Services.prefs.getBoolPref("extensions.incognito.migrated", false),
      "pref marked as migrated");
 
   // Verify policy settings.
-  policy = WebExtensionPolicy.getByID(id);
+  policy = WebExtensionPolicy.getByID(addonId);
   ok(policy.permissions.includes("internal:privateBrowsingAllowed"),
      "privateBrowsingAllowed is in permissions");
   equal(policy.privateBrowsingAllowed, true,
         "privateBrowsingAllowed in extension");
 
   // Verify the disabled addon did not get permissions.
-  disabledAddon = await AddonManager.getAddonByID("@disabled");
+  disabledAddon = await AddonManager.getAddonByID(disabledAddonId);
   await disabledAddon.enable();
-  disabledPolicy = WebExtensionPolicy.getByID("@disabled");
+  disabledPolicy = WebExtensionPolicy.getByID(disabledAddonId);
 
   // Verify policy settings.
   equal(disabledPolicy.permissions.includes("internal:privateBrowsingAllowed"), false,
         "privateBrowsingAllowed is not in permissions for disabled addon");
   equal(disabledPolicy.privateBrowsingAllowed, false,
         "privateBrowsingAllowed in disabled addon");
 
   await wrapper.unload();
   await disabledWrapper.unload();
   Services.prefs.clearUserPref("extensions.allowPrivateBrowsingByDefault");
   Services.prefs.clearUserPref("extensions.incognito.migrated");
 
   const expectedEvents = [{
     method: "action",
     object: "appUpgrade",
     value: "on",
-    extra: {
-      addonId: "@grandfathered",
-      action: "privateBrowsingAllowed",
-    },
+    extra: {addonId, action: "privateBrowsingAllowed"},
   }];
 
   assertActionAMTelemetryEvent(
     expectedEvents,
     "Got the expected telemetry events for the grandfathered extensions",
     {actionType: "privateBrowsingAllowed"});
 });
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -524,16 +524,18 @@ var gUpdateEnabled = true;
 var gAutoUpdateDefault = true;
 var gWebExtensionsMinPlatformVersion = "";
 var gShutdownBarrier = null;
 var gRepoShutdownState = "";
 var gShutdownInProgress = false;
 var gPluginPageListener = null;
 var gBrowserUpdated = null;
 
+var AMTelemetry;
+
 /**
  * This is the real manager, kept here rather than in AddonManager to keep its
  * contents hidden from API users.
  * @class
  * @lends AddonManager
  */
 var AddonManagerInternal = {
   managerListeners: new Set(),
@@ -692,16 +694,19 @@ var AddonManagerInternal = {
    */
   startup() {
     try {
       if (gStarted)
         return;
 
       this.recordTimestamp("AMI_startup_begin");
 
+      // Enable the addonsManager telemetry event category.
+      AMTelemetry.init();
+
       // clear this for xpcshell test restarts
       for (let provider in this.telemetryDetails)
         delete this.telemetryDetails[provider];
 
       let appChanged = undefined;
 
       let oldAppVersion = null;
       try {
@@ -3501,31 +3506,37 @@ var AddonManager = {
   get shutdown() {
     return gShutdownBarrier.client;
   },
 };
 
 /**
  * Listens to the AddonManager install and addon events and send telemetry events.
  */
-var AMTelemetry = {
+AMTelemetry = {
   telemetrySetupDone: false,
 
+  init() {
+    // Enable the addonsManager telemetry event category before the AddonManager
+    // has completed its startup, otherwise telemetry events recorded during the
+    // AddonManager/XPIProvider startup will not be recorded (e.g. the telemetry
+    // events for the extension migrated to the private browsing permission).
+    Services.telemetry.setEventRecordingEnabled("addonsManager", true);
+  },
+
   // This method is called by the AddonManager, once it has been started, so that we can
   // init the telemetry event category and start listening for the events related to the
   // addons installation and management.
   onStartup() {
     if (this.telemetrySetupDone) {
       return;
     }
 
     this.telemetrySetupDone = true;
 
-    Services.telemetry.setEventRecordingEnabled("addonsManager", true);
-
     Services.obs.addObserver(this, "addon-install-origin-blocked");
     Services.obs.addObserver(this, "addon-install-disabled");
     Services.obs.addObserver(this, "addon-install-blocked");
 
     AddonManager.addInstallListener(this);
     AddonManager.addAddonListener(this);
   },