Bug 1458770 - Use the toolbox's Telemetry instance in the Inspector. r=jdescottes draft
authorGabriel Luong <gabriel.luong@gmail.com>
Wed, 02 May 2018 23:15:28 -0400
changeset 790912 934167e414d6c77e5160b58f3e41ac11ba21ecd8
parent 790900 cb245b9a8b2ce1dbe877f85566cf16613d8d9b44
push id108637
push userbmo:gl@mozilla.com
push dateThu, 03 May 2018 03:17:02 +0000
reviewersjdescottes
bugs1458770
milestone61.0a1
Bug 1458770 - Use the toolbox's Telemetry instance in the Inspector. r=jdescottes MozReview-Commit-ID: DXAAV3Ix3GD
devtools/client/framework/toolbox.js
devtools/client/inspector/inspector.js
devtools/client/inspector/toolsidebar.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -104,24 +104,24 @@ loader.lazyGetter(this, "registerHarOver
  * @param {string} frameId
  *        A unique identifier to differentiate toolbox documents from the
  *        chrome codebase when passing DOM messages
  */
 function Toolbox(target, selectedTool, hostType, contentWindow, frameId) {
   this._target = target;
   this._win = contentWindow;
   this.frameId = frameId;
+  this.telemetry = new Telemetry();
 
   // Map of the available DevTools WebExtensions:
   //   Map<extensionUUID, extensionName>
   this._webExtensions = new Map();
 
   this._toolPanels = new Map();
   this._inspectorExtensionSidebars = new Map();
-  this._telemetry = new Telemetry();
 
   this._initInspector = null;
   this._inspector = null;
   this._styleSheets = null;
   this._netMonitorAPI = null;
 
   // Map of frames (id => frame-info) and currently selected frame id.
   this.frameMap = new Map();
@@ -540,20 +540,20 @@ Toolbox.prototype = {
 
       await this.selectTool(this._defaultToolId, "initial_panel");
 
       // Wait until the original tool is selected so that the split
       // console input will receive focus.
       let splitConsolePromise = promise.resolve();
       if (Services.prefs.getBoolPref(SPLITCONSOLE_ENABLED_PREF)) {
         splitConsolePromise = this.openSplitConsole();
-        this._telemetry.addEventProperty(
+        this.telemetry.addEventProperty(
           "devtools.main", "open", "tools", null, "splitconsole", true);
       } else {
-        this._telemetry.addEventProperty(
+        this.telemetry.addEventProperty(
           "devtools.main", "open", "tools", null, "splitconsole", false);
       }
 
       await promise.all([
         splitConsolePromise,
         framesPromise
       ]);
 
@@ -711,32 +711,32 @@ Toolbox.prototype = {
       case Toolbox.HostType.SIDE: return "side";
       case Toolbox.HostType.WINDOW: return "window";
       case Toolbox.HostType.CUSTOM: return "other";
       default: return "bottom";
     }
   },
 
   _pingTelemetry: function() {
-    this._telemetry.toolOpened("toolbox");
-
-    this._telemetry.logOncePerBrowserVersion(SCREENSIZE_HISTOGRAM,
+    this.telemetry.toolOpened("toolbox");
+
+    this.telemetry.logOncePerBrowserVersion(SCREENSIZE_HISTOGRAM,
                                              system.getScreenDimensions());
-    this._telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
+    this.telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
 
     // Log current theme. The question we want to answer is:
     // "What proportion of users use which themes?"
     let currentTheme = Services.prefs.getCharPref("devtools.theme");
-    this._telemetry.logKeyedScalar(CURRENT_THEME_SCALAR, currentTheme, 1);
-
-    this._telemetry.preparePendingEvent(
+    this.telemetry.logKeyedScalar(CURRENT_THEME_SCALAR, currentTheme, 1);
+
+    this.telemetry.preparePendingEvent(
       "devtools.main", "open", "tools", null,
       ["entrypoint", "first_panel", "host", "splitconsole", "width"]
     );
-    this._telemetry.addEventProperty(
+    this.telemetry.addEventProperty(
       "devtools.main", "open", "tools", null, "host", this._getTelemetryHostString()
     );
   },
 
   /**
    * Create a simple object to store the state of a toolbox button. The checked state of
    * a button can be updated arbitrarily outside of the scope of the toolbar and its
    * controllers. In order to simplify this interaction this object emits an
@@ -1844,17 +1844,17 @@ Toolbox.prototype = {
       throw new Error("Can't select tool, wait for toolbox 'ready' event");
     }
 
     // Check if the tool exists.
     if (this.panelDefinitions.find((definition) => definition.id === id) ||
         id === "options" ||
         this.additionalToolDefinitions.get(id)) {
       if (this.currentToolId) {
-        this._telemetry.toolClosed(this.currentToolId);
+        this.telemetry.toolClosed(this.currentToolId);
       }
 
       this._pingTelemetrySelectTool(id, reason);
     } else {
       throw new Error("No tool found");
     }
 
     // and select the right iframe
@@ -1879,50 +1879,50 @@ Toolbox.prototype = {
   },
 
   _pingTelemetrySelectTool(id, reason) {
     const width = Math.ceil(this.win.outerWidth / 50) * 50;
     const panelName = this.getTelemetryPanelName(id);
     const prevPanelName = this.getTelemetryPanelName(this.currentToolId);
     const cold = !this.getPanel(id);
 
-    this._telemetry.addEventProperties("devtools.main", "enter", panelName, null, {
+    this.telemetry.addEventProperties("devtools.main", "enter", panelName, null, {
       "host": this._hostType,
       "width": width,
       "start_state": reason,
       "panel_name": panelName,
       "cold": cold
     });
 
     // On first load this.currentToolId === undefined so we need to skip sending
     // a devtools.main.exit telemetry event.
     if (this.currentToolId) {
-      this._telemetry.recordEvent("devtools.main", "exit", prevPanelName, null, {
+      this.telemetry.recordEvent("devtools.main", "exit", prevPanelName, null, {
         "host": this._hostType,
         "width": width,
         "panel_name": prevPanelName,
         "next_panel": panelName,
         "reason": reason
       });
     }
 
     const pending = ["host", "width", "start_state", "panel_name", "cold"];
     if (id === "webconsole") {
       pending.push("message_count");
 
       // Cold webconsole event message_count is handled in
       // devtools/client/webconsole/new-console-output-wrapper.js
       if (!cold) {
-        this._telemetry.addEventProperty(
+        this.telemetry.addEventProperty(
           "devtools.main", "enter", "webconsole", null, "message_count", 0);
       }
     }
-    this._telemetry.preparePendingEvent(
+    this.telemetry.preparePendingEvent(
       "devtools.main", "enter", panelName, null, pending);
-    this._telemetry.toolOpened(id);
+    this.telemetry.toolOpened(id);
   },
 
   /**
    * Focus a tool's panel by id
    * @param  {string} id
    *         The id of tool to focus
    */
   focusTool: function(id, state = true) {
@@ -1980,17 +1980,17 @@ Toolbox.prototype = {
     // Ensure split console is visible if console was already loaded in background
     let iframe = this.webconsolePanel.querySelector(".toolbox-panel-iframe");
     if (iframe) {
       this.setIframeVisible(iframe, true);
     }
 
     return this.loadTool("webconsole").then(() => {
       this.component.setIsSplitConsoleActive(true);
-      this._telemetry.recordEvent("devtools.main", "activate", "split_console", null, {
+      this.telemetry.recordEvent("devtools.main", "activate", "split_console", null, {
         "host": this._getTelemetryHostString(),
         "width": Math.ceil(this.win.outerWidth / 50) * 50
       });
       this.emit("split-console");
       this.focusConsoleInput();
     });
   },
 
@@ -2001,17 +2001,17 @@ Toolbox.prototype = {
    *          closed.
    */
   closeSplitConsole: function() {
     this._splitConsole = false;
     Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, false);
     this._refreshConsoleDisplay();
     this.component.setIsSplitConsoleActive(false);
 
-    this._telemetry.recordEvent("devtools.main", "deactivate", "split_console", null, {
+    this.telemetry.recordEvent("devtools.main", "deactivate", "split_console", null, {
       "host": this._getTelemetryHostString(),
       "width": Math.ceil(this.win.outerWidth / 50) * 50
     });
 
     this.emit("split-console");
 
     if (this._lastFocusedElement) {
       this._lastFocusedElement.focus();
@@ -2453,17 +2453,17 @@ Toolbox.prototype = {
     this._buildDockOptions();
     this._addKeysToWindow();
 
     // We blurred the tools at start of switchHost, but also when clicking on
     // host switching button. We now have to restore the focus.
     this.focusTool(this.currentToolId, true);
 
     this.emit("host-changed");
-    this._telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
+    this.telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
 
     this.component.setCurrentHostType(hostType);
   },
 
   /**
    * Test the availability of a tool (both globally registered tools and
    * additional tools registered to this toolbox) by tool id.
    *
@@ -2837,29 +2837,29 @@ Toolbox.prototype = {
     });
 
     // We need to grab a reference to win before this._host is destroyed.
     const win = this.win;
     const host = this._getTelemetryHostString();
     const width = Math.ceil(win.outerWidth / 50) * 50;
     const prevPanelName = this.getTelemetryPanelName(this.currentToolId);
 
-    this._telemetry.toolClosed("toolbox");
-    this._telemetry.recordEvent("devtools.main", "close", "tools", null, {
+    this.telemetry.toolClosed("toolbox");
+    this.telemetry.recordEvent("devtools.main", "close", "tools", null, {
       host: host,
       width: width
     });
-    this._telemetry.recordEvent("devtools.main", "exit", prevPanelName, null, {
+    this.telemetry.recordEvent("devtools.main", "exit", prevPanelName, null, {
       "host": host,
       "width": width,
       "panel_name": this.getTelemetryPanelName(this.currentToolId),
       "next_panel": "none",
       "reason": "toolbox_close"
     });
-    this._telemetry.destroy();
+    this.telemetry.destroy();
 
     // Finish all outstanding tasks (which means finish destroying panels and
     // then destroying the host, successfully or not) before destroying the
     // target.
     deferred.resolve(settleAll(outstanding)
         .catch(console.error)
         .then(() => {
           let api = this._netMonitorAPI;
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -9,17 +9,16 @@
 "use strict";
 
 const Services = require("Services");
 const promise = require("promise");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {executeSoon} = require("devtools/shared/DevToolsUtils");
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const {PrefObserver} = require("devtools/client/shared/prefs");
-const Telemetry = require("devtools/client/shared/telemetry");
 const HighlightersOverlay = require("devtools/client/inspector/shared/highlighters-overlay");
 const ReflowTracker = require("devtools/client/inspector/shared/reflow-tracker");
 const Store = require("devtools/client/inspector/store");
 const InspectorStyleChangeTracker = require("devtools/client/inspector/shared/style-change-tracker");
 
 // Use privileged promise in panel documents to prevent having them to freeze
 // during toolbox destruction. See bug 1402779.
 const Promise = require("Promise");
@@ -98,28 +97,28 @@ const THREE_PANE_ENABLED_SCALAR = "devto
 function Inspector(toolbox) {
   EventEmitter.decorate(this);
 
   this._toolbox = toolbox;
   this._target = toolbox.target;
   this.panelDoc = window.document;
   this.panelWin = window;
   this.panelWin.inspector = this;
+  this.telemetry = toolbox.telemetry;
 
   this.store = Store();
 
   // Map [panel id => panel instance]
   // Stores all the instances of sidebar panels like rule view, computed view, ...
   this._panels = new Map();
 
   this.highlighters = new HighlightersOverlay(this);
   this.prefsObserver = new PrefObserver("devtools.");
   this.reflowTracker = new ReflowTracker(this._target);
   this.styleChangeTracker = new InspectorStyleChangeTracker(this);
-  this.telemetry = new Telemetry();
 
   // Store the URL of the target page prior to navigation in order to ensure
   // telemetry counts in the Grid Inspector are not double counted on reload.
   this.previousURL = this.target.url;
 
   this.show3PaneToggle = Services.prefs.getBoolPref(SHOW_THREE_PANE_TOGGLE_PREF);
   this.is3PaneModeEnabled = Services.prefs.getBoolPref(THREE_PANE_ENABLED_PREF);
 
--- a/devtools/client/inspector/toolsidebar.js
+++ b/devtools/client/inspector/toolsidebar.js
@@ -1,18 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 "use strict";
 
-var EventEmitter = require("devtools/shared/event-emitter");
-var Telemetry = require("devtools/client/shared/telemetry");
+const EventEmitter = require("devtools/shared/event-emitter");
 
 /**
  * This object represents replacement for ToolSidebar
  * implemented in devtools/client/framework/sidebar.js module
  *
  * This new component is part of devtools.html aimed at
  * removing XUL and use HTML for entire DevTools UI.
  * There are currently two implementation of the side bar since
@@ -26,17 +25,17 @@ function ToolSidebar(tabbox, panel, uid,
 
   this._tabbox = tabbox;
   this._uid = uid;
   this._panelDoc = this._tabbox.ownerDocument;
   this._toolPanel = panel;
   this._options = options;
 
   if (!options.disableTelemetry) {
-    this._telemetry = new Telemetry();
+    this._telemetry = this._toolPanel.telemetry;
   }
 
   this._tabs = [];
 
   if (this._options.hideTabstripe) {
     this._tabbox.setAttribute("hidetabs", "true");
   }
 
@@ -341,12 +340,13 @@ ToolSidebar.prototype = {
     if (this._currentTool && this._telemetry) {
       this._telemetry.toolClosed(this._currentTool);
     }
 
     this._toolPanel.emit("sidebar-destroyed", this);
 
     this._tabs = null;
     this._tabbox = null;
+    this._telemetry = null;
     this._panelDoc = null;
     this._toolPanel = null;
   }
 };