Bug 1560590 - Add Telemetry event probes to determine if users tend to move or resize the Picture-in-Picture window after opening it. data-review=chutten, r=JSON_voorhees, a=RyanVM
authorMike Conley <mconley@mozilla.com>
Tue, 09 Jul 2019 21:37:26 +0000
changeset 544498 d2d91301a2a067f99f2f6c076d148535c100d0d1
parent 544497 f3bf02fa090afdc0dc3ff1e248deb2bb3cf036b7
child 544499 2feaf4d8ac53456dcb99457defc9689a0a12fb3e
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJSON_voorhees, RyanVM
bugs1560590
milestone69.0
Bug 1560590 - Add Telemetry event probes to determine if users tend to move or resize the Picture-in-Picture window after opening it. data-review=chutten, r=JSON_voorhees, a=RyanVM Depends on D36359 Differential Revision: https://phabricator.services.mozilla.com/D36360
toolkit/components/pictureinpicture/PictureInPicture.jsm
toolkit/components/pictureinpicture/content/player.js
toolkit/components/telemetry/Events.yaml
--- a/toolkit/components/pictureinpicture/PictureInPicture.jsm
+++ b/toolkit/components/pictureinpicture/PictureInPicture.jsm
@@ -16,16 +16,22 @@ const WINDOW_TYPE = "Toolkit:PictureInPi
  * If closing the Picture-in-Picture player window occurred for a reason that
  * we can easily detect (user clicked on the close button, originating tab unloaded,
  * user clicked on the unpip button), that will be stashed in gCloseReasons so that
  * we can note it in Telemetry when the window finally unloads.
  */
 let gCloseReasons = new WeakMap();
 
 /**
+ * To differentiate windows in the Telemetry Event Log, each Picture-in-Picture
+ * player window is given a unique ID.
+ */
+let gNextWindowID = 0;
+
+/**
  * This module is responsible for creating a Picture in Picture window to host
  * a clone of a video element running in web content.
  */
 
 var PictureInPicture = {
   // Listeners are added in nsBrowserGlue.js lazily
   receiveMessage(aMessage) {
     let browser = aMessage.target;
@@ -128,17 +134,19 @@ var PictureInPicture = {
     let controls = win.document.getElementById("controls");
     this.weakPipControls = Cu.getWeakReference(controls);
     if (videoData.playing) {
       controls.classList.add("playing");
     }
     // set attribute which shows pip icon in tab
     let tab = parentWin.gBrowser.getTabForBrowser(browser);
     tab.setAttribute("pictureinpicture", true);
-    win.setupPlayer(browser, videoData);
+
+    win.setupPlayer(gNextWindowID.toString(), browser, videoData);
+    gNextWindowID++;
   },
 
   /**
    * unload event has been called in player.js, cleanup our preserved
    * browser object.
    */
   unload(window) {
     TelemetryStopwatch.finish(
--- a/toolkit/components/pictureinpicture/content/player.js
+++ b/toolkit/components/pictureinpicture/content/player.js
@@ -1,20 +1,25 @@
 /* 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/. */
 
 const { PictureInPicture } = ChromeUtils.import(
   "resource://gre/modules/PictureInPicture.jsm"
 );
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { DeferredTask } = ChromeUtils.import(
+  "resource://gre/modules/DeferredTask.jsm"
+);
 
 // Time to fade the Picture-in-Picture video controls after first opening.
-const CONTROLS_FADE_TIMEOUT = 3000;
+const CONTROLS_FADE_TIMEOUT_MS = 3000;
+const RESIZE_DEBOUNCE_RATE_MS = 500;
 
-async function setupPlayer(originatingBrowser, videoData) {
+async function setupPlayer(id, originatingBrowser, videoData) {
   let holder = document.querySelector(".player-holder");
   let browser = document.getElementById("browser");
   browser.remove();
 
   browser.setAttribute("nodefaultsrc", "true");
   browser.sameProcessAsFrameLoader = originatingBrowser.frameLoader;
   holder.appendChild(browser);
 
@@ -38,22 +43,59 @@ async function setupPlayer(originatingBr
   });
 
   // If the content process hosting the video crashes, let's
   // just close the window for now.
   browser.addEventListener("oop-browser-crashed", () => {
     PictureInPicture.closePipWindow({ reason: "browser-crash" });
   });
 
-  window.addEventListener("unload", () => {
-    PictureInPicture.unload(window);
-  });
-
   let close = document.getElementById("close");
   close.addEventListener("click", () => {
     PictureInPicture.closePipWindow({ reason: "close-button" });
   });
 
   document.getElementById("controls").setAttribute("showing", true);
   setTimeout(() => {
     document.getElementById("controls").removeAttribute("showing");
-  }, CONTROLS_FADE_TIMEOUT);
+  }, CONTROLS_FADE_TIMEOUT_MS);
+
+  Services.telemetry.setEventRecordingEnabled("pictureinpicture", true);
+
+  let resizeDebouncer = new DeferredTask(() => {
+    Services.telemetry.recordEvent("pictureinpicture", "resize", "player", id, {
+      width: window.outerWidth.toString(),
+      height: window.outerHeight.toString(),
+    });
+  }, RESIZE_DEBOUNCE_RATE_MS);
+
+  addEventListener("resize", e => {
+    resizeDebouncer.disarm();
+    resizeDebouncer.arm();
+  });
+
+  let lastScreenX = window.screenX;
+  let lastScreenY = window.screenY;
+
+  addEventListener("mouseout", e => {
+    if (window.screenX != lastScreenX || window.screenY != lastScreenY) {
+      Services.telemetry.recordEvent("pictureinpicture", "move", "player", id, {
+        screenX: window.screenX.toString(),
+        screenY: window.screenY.toString(),
+      });
+    }
+
+    lastScreenX = window.screenX;
+    lastScreenY = window.screenY;
+  });
+
+  Services.telemetry.recordEvent("pictureinpicture", "create", "player", id, {
+    width: window.outerWidth.toString(),
+    height: window.outerHeight.toString(),
+    screenX: window.screenX.toString(),
+    screenY: window.screenY.toString(),
+  });
+
+  window.addEventListener("unload", () => {
+    resizeDebouncer.disarm();
+    PictureInPicture.unload(window);
+  });
 }
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -1301,8 +1301,60 @@ security.ui.permissionprompt:
       docHasUserInput: Whether the document has been interacted with (includes scrolling)
       lastInteraction: When the site was last interacted with (includes scrolling)
       allPermsDenied: How many permissions were denied by the user in total
       allPermsGranted: How many permissions were granted by the user in total
       thisPermDenied: How many permissions of the same kind were denied by the user in total
       thisPermGranted: How many permissions of the same kind were granted by the user in total
     products:
       - firefox
+
+pictureinpicture:
+  create:
+    objects: ["player"]
+    description: >
+      Recorded when the Picture-in-Picture player window is created.
+    extra_keys:
+      width: The width that the window was created at
+      height: The height that the window was created at
+      screenX: The screen X coordinate that the window was created at
+      screenY: The screen Y coordinate that the window was created at
+    notification_emails:
+      - mconley@mozilla.com
+      - astevenson@mozilla.com
+    record_in_processes:
+      - main
+    bug_numbers:
+      - 1560590
+    expiry_version: "74"
+    release_channel_collection: opt-in
+  resize:
+    objects: ["player"]
+    description: >
+      Recorded when the Picture-in-Picture player window is resized.
+    extra_keys:
+      width: The width that the window was resized to
+      height: The height that the window was resize to
+    notification_emails:
+      - mconley@mozilla.com
+      - astevenson@mozilla.com
+    record_in_processes:
+      - main
+    bug_numbers:
+      - 1560590
+    expiry_version: "74"
+    release_channel_collection: opt-in
+  move:
+    objects: ["player"]
+    description: >
+      Recorded when the Picture-in-Picture player window is moved.
+    extra_keys:
+      screenX: The screen X coordinate that the window was moved to
+      screenY: The screen Y coordinate that the window was moved to
+    notification_emails:
+      - mconley@mozilla.com
+      - astevenson@mozilla.com
+    record_in_processes:
+      - main
+    bug_numbers:
+      - 1560590
+    expiry_version: "74"
+    release_channel_collection: opt-in