Bug 1465685 - Add Password Manager probes for Savant Shield study; r=MattN draft
authorBianca Danforth <bdanforth@mozilla.com>
Fri, 01 Jun 2018 23:06:25 -0700
changeset 803327 1e94c2a11aaab6690317d41c62fd0382f03428bf
parent 803325 950900b42e9320b21a07f8e18cf3826796c4c1d7
child 803328 24b7e5e9beb2a96ed139851feb8b7cd512da8387
push id112071
push userbdanforth@mozilla.com
push dateSun, 03 Jun 2018 07:45:42 +0000
reviewersMattN
bugs1465685, 1457226
milestone62.0a1
Bug 1465685 - Add Password Manager probes for Savant Shield study; r=MattN These probes will register and record (for the duration of the study only): * When the user is prompted by the Password Manager * When the user saves their login information through the Password Manager prompt * When the user updates their login information through the Password Manager prompt * When the user uses login information stored by the Password Manager Note that 'pw_manager_use' takes place in the content process, whereas 'pw_manager' takes place in the parent process. The 'pw_manager' probe has an 'extra' field called 'flow_id' as defined in the probe spec (see PHD linked in bug 1457226). This value associates actions that occur in series (i.e. ask --> save or ask --> update). For this probe, the flow_id will be the same value for the same website. MozReview-Commit-ID: HsJQa8Q6eXM
browser/modules/SavantShieldStudy.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/components/telemetry/Events.yaml
--- a/browser/modules/SavantShieldStudy.jsm
+++ b/browser/modules/SavantShieldStudy.jsm
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/* eslint semi: error */
+
 "use strict";
 
 var EXPORTED_SYMBOLS = ["SavantShieldStudy"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1250,16 +1250,19 @@ var LoginManagerContent = {
       }
 
       log("_fillForm succeeded");
       autofillResult = AUTOFILL_RESULT.FILLED;
 
       let win = doc.defaultView;
       let messageManager = messageManagerFromWindow(win);
       messageManager.sendAsyncMessage("LoginStats:LoginFillSuccessful");
+
+      Services.telemetry.recordEvent("savant", "pw_manager_use", "use", null, { subcategory: "feature" });
+
     } finally {
       if (autofillResult == -1) {
         // eslint-disable-next-line no-unsafe-finally
         throw new Error("_fillForm: autofillResult must be specified");
       }
 
       if (!userTriggered) {
         // Ignore fills as a result of user action for this probe.
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -11,16 +11,19 @@ ChromeUtils.defineModuleGetter(this, "Lo
                                "resource://gre/modules/LoginHelper.jsm");
 
 const LoginInfo =
       Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
                              "nsILoginInfo", "init");
 
 const BRAND_BUNDLE = "chrome://branding/locale/brand.properties";
 
+XPCOMUtils.defineLazyModuleGetter(this, "SavantShieldStudy",
+                                  "resource:///modules/SavantShieldStudy.jsm");
+
 /**
  * Constants for password prompt telemetry.
  * Mirrored in mobile/android/components/LoginManagerPrompter.js */
 const PROMPT_DISPLAYED = 0;
 
 const PROMPT_ADD_OR_UPDATE = 1;
 const PROMPT_NOTNOW = 2;
 const PROMPT_NEVER = 3;
@@ -817,16 +820,23 @@ LoginManagerPrompter.prototype = {
     let promptMsg = type == "password-save" ? this._getLocalizedString(saveMsgNames.prompt, [brandShortName, host])
                                             : this._getLocalizedString(changeMsgNames.prompt);
 
     let histogramName = type == "password-save" ? "PWMGR_PROMPT_REMEMBER_ACTION"
                                                 : "PWMGR_PROMPT_UPDATE_ACTION";
     let histogram = Services.telemetry.getHistogramById(histogramName);
     histogram.add(PROMPT_DISPLAYED);
 
+    const uriPrePath = Services.wm.getMostRecentWindow("navigator:browser")
+                      .gBrowser.currentURI.prePath;
+    SavantShieldStudy.getFlowID(uriPrePath).then((flow_id) => {
+      Services.telemetry.recordEvent("savant", "pw_manager", "ask", null,
+                                    { subcategory: "prompt", flow_id });
+    });
+
     let chromeDoc = browser.ownerDocument;
 
     let currentNotification;
 
     let updateButtonStatus = (element) => {
       let mainActionButton = element.button;
       // Disable the main button inside the menu-button if the password field is empty.
       if (login.password.length == 0) {
@@ -946,16 +956,25 @@ LoginManagerPrompter.prototype = {
     // The main action is the "Save" or "Update" button.
     let mainAction = {
       label: this._getLocalizedString(initialMsgNames.buttonLabel),
       accessKey: this._getLocalizedString(initialMsgNames.buttonAccessKey),
       callback: () => {
         histogram.add(PROMPT_ADD_OR_UPDATE);
         if (histogramName == "PWMGR_PROMPT_REMEMBER_ACTION") {
           Services.obs.notifyObservers(null, "LoginStats:NewSavedPassword");
+          SavantShieldStudy.getFlowID(uriPrePath).then((flow_id) => {
+            Services.telemetry.recordEvent("savant", "pw_manager", "save", null,
+                                          { subcategory: "prompt", flow_id });
+          });
+        } else if (histogramName == "PWMGR_PROMPT_UPDATE_ACTION") {
+          SavantShieldStudy.getFlowID(uriPrePath).then((flow_id) => {
+            Services.telemetry.recordEvent("savant", "pw_manager", "update", null,
+                                          { subcategory: "prompt", flow_id });
+          });
         }
         readDataFromUI();
         persistData();
         browser.focus();
       }
     };
 
     let secondaryActions = [{
@@ -1701,9 +1720,9 @@ LoginManagerPrompter.prototype = {
 }; // end of LoginManagerPrompter implementation
 
 XPCOMUtils.defineLazyGetter(this.LoginManagerPrompter.prototype, "log", () => {
   let logger = LoginHelper.createLogger("LoginManagerPrompter");
   return logger.log.bind(logger);
 });
 
 var component = [LoginManagerPromptFactory, LoginManagerPrompter];
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);
\ No newline at end of file
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -115,16 +115,43 @@ savant:
       Shield study. The object field records the reason that caused the ending.
     bug_numbers: [1457226, 1462725]
     notification_emails:
       - "bdanforth@mozilla.com"
       - "shong@mozilla.com"
     expiry_version: "65"
     extra_keys:
       subcategory: The broad event category for this probe. E.g. navigation
+  pw_manager_use:
+    objects: ["use"]
+    release_channel_collection: opt-out
+    record_in_processes: ["content"]
+    description: >
+      Client uses saved login information from the Password Manager
+    bug_numbers: [1457226, 1465685]
+    notification_emails:
+      - "bdanforth@mozilla.com"
+      - "shong@mozilla.com"
+    expiry_version: "65"
+    extra_keys:
+      subcategory: The broad event category for this probe. E.g. navigation
+  pw_manager:
+    objects: ["ask", "save", "update"]
+    release_channel_collection: opt-out
+    record_in_processes: ["main"]
+    description: >
+      Password Manager asks the user to save or update login information
+    bug_numbers: [1457226, 1465685]
+    notification_emails:
+      - "bdanforth@mozilla.com"
+      - "shong@mozilla.com"
+    expiry_version: "65"
+    extra_keys:
+      subcategory: The broad event category for this probe. E.g. navigation
+      flow_id: A value that links two or more actions in a series. e.g. ask -> save
 
 # This category contains event entries used for Telemetry tests.
 # They will not be sent out with any pings.
 telemetry.test:
   test:
     methods: ["test1", "test2"]
     objects: ["object1", "object2"]
     bug_numbers: [1286606]