Bug 1465685 - Add login_form probe for Savant Shield study; r=MattN draft
authorBianca Danforth <bdanforth@mozilla.com>
Fri, 01 Jun 2018 23:10:07 -0700
changeset 803328 24b7e5e9beb2a96ed139851feb8b7cd512da8387
parent 803327 1e94c2a11aaab6690317d41c62fd0382f03428bf
push id112071
push userbdanforth@mozilla.com
push dateSun, 03 Jun 2018 07:45:42 +0000
reviewersMattN
bugs1465685, 1287202, 1457226
milestone62.0a1
Bug 1465685 - Add login_form probe for Savant Shield study; r=MattN This probe will register and record (for the duration of the study only): * When a login form is loaded * When a login form is submitted (excluding the case from unresolved bug 1287202) The login_form 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. load -> submit). The value of flow_id should be the same for a given website. It should be noted that for several reasons, we should expect a higher than 1:1 ratio between 'load' and 'submit' events: * Some sites, like Google and Amazon, have a two-step login process, and each step fires its own 'load' event. Only the second step fires a 'submit' event. * Some sites, like Facebook and Twitter, fire multiple 'load' events on the same page. * A common pattern for unsuccessful logins is for the site to redirect to a page with a login form. This would be a 'load' --> 'submit' --> 'load' series. * While the 'load' event fires whether or not the Password Manager is enabled and in both private and non-private windows, the 'submit' event fires only when the Password Manager is enabled and the user is in a non-private window. This means for events that occur in a private window and/or when Password Manager is disabled, we would only capture the 'load' event. MozReview-Commit-ID: 2WnVwYTvmhp
browser/components/nsBrowserGlue.js
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/LoginManagerParent.jsm
toolkit/components/telemetry/Events.yaml
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -222,16 +222,18 @@ const listeners = {
     "Reader:UpdateReaderButton": ["ReaderParent"],
     // PLEASE KEEP THIS LIST IN SYNC WITH THE MOBILE LISTENERS IN BrowserCLH.js
     "RemoteLogins:findLogins": ["LoginManagerParent"],
     "RemoteLogins:findRecipes": ["LoginManagerParent"],
     "RemoteLogins:onFormSubmit": ["LoginManagerParent"],
     "RemoteLogins:autoCompleteLogins": ["LoginManagerParent"],
     "RemoteLogins:removeLogin": ["LoginManagerParent"],
     "RemoteLogins:insecureLoginFormPresent": ["LoginManagerParent"],
+    // For Savant Shield study, bug 1465685. Study on desktop only.
+    "LoginStats:LoginEncountered": ["LoginManagerParent"],
     // PLEASE KEEP THIS LIST IN SYNC WITH THE MOBILE LISTENERS IN BrowserCLH.js
     "WCCR:registerProtocolHandler": ["Feeds"],
     "WCCR:registerContentHandler": ["Feeds"],
     "rtcpeer:CancelRequest": ["webrtcUI"],
     "rtcpeer:Request": ["webrtcUI"],
     "webrtc:CancelRequest": ["webrtcUI"],
     "webrtc:Request": ["webrtcUI"],
     "webrtc:StopRecording": ["webrtcUI"],
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1637,9 +1637,9 @@ var LoginFormFactory = {
     state.loginFormRootElements.add(formLike.rootElement);
     log("adding", formLike.rootElement, "to loginFormRootElements for", formLike.ownerDocument);
 
 
     LoginManagerContent._formLikeByRootElement.set(formLike.rootElement, formLike);
 
     return formLike;
   },
-};
+};
\ No newline at end of file
--- a/toolkit/components/passwordmgr/LoginManagerParent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ -15,16 +15,19 @@ ChromeUtils.defineModuleGetter(this, "De
 ChromeUtils.defineModuleGetter(this, "LoginHelper",
                                "resource://gre/modules/LoginHelper.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   let logger = LoginHelper.createLogger("LoginManagerParent");
   return logger.log.bind(logger);
 });
 
+XPCOMUtils.defineLazyModuleGetter(this, "SavantShieldStudy",
+                                  "resource:///modules/SavantShieldStudy.jsm");
+
 var EXPORTED_SYMBOLS = [ "LoginManagerParent" ];
 
 var LoginManagerParent = {
   /**
    * Reference to the default LoginRecipesParent (instead of the initialization promise) for
    * synchronous access. This is a temporary hack and new consumers should yield on
    * recipeParentPromise instead.
    *
@@ -88,16 +91,23 @@ var LoginManagerParent = {
         // TODO Verify msg.target's principals against the formOrigin?
         this.onFormSubmit(data.hostname,
                           data.formSubmitURL,
                           data.usernameField,
                           data.newPasswordField,
                           data.oldPasswordField,
                           msg.objects.openerTopWindow,
                           msg.target);
+
+        const uriPrePath = Services.wm.getMostRecentWindow("navigator:browser")
+                          .gBrowser.currentURI.prePath;
+        SavantShieldStudy.getFlowID(uriPrePath).then((flow_id) => {
+          Services.telemetry.recordEvent("savant", "login_form", "submit", null,
+                                        { subcategory: "encounter", flow_id });
+        });
         break;
       }
 
       case "RemoteLogins:insecureLoginFormPresent": {
         this.setHasInsecureLoginForms(msg.target, data.hasInsecureLoginForms);
         break;
       }
 
@@ -106,16 +116,26 @@ var LoginManagerParent = {
         break;
       }
 
       case "RemoteLogins:removeLogin": {
         let login = LoginHelper.vanillaObjectToLogin(data.login);
         AutoCompletePopup.removeLogin(login);
         break;
       }
+
+      case "LoginStats:LoginEncountered": {
+        const uriPrePath = Services.wm.getMostRecentWindow("navigator:browser")
+                          .gBrowser.currentURI.prePath;
+        SavantShieldStudy.getFlowID(uriPrePath).then((flow_id) => {
+          Services.telemetry.recordEvent("savant", "login_form", "load", null,
+                                        { subcategory: "encounter", flow_id });
+        });
+        break;
+      }
     }
 
     return undefined;
   },
 
   /**
    * Trigger a login form fill and send relevant data (e.g. logins and recipes)
    * to the child process (LoginManagerContent).
@@ -479,9 +499,9 @@ XPCOMUtils.defineLazyGetter(LoginManager
   const { LoginRecipesParent } = ChromeUtils.import("resource://gre/modules/LoginRecipes.jsm", {});
   this._recipeManager = new LoginRecipesParent({
     defaults: Services.prefs.getStringPref("signon.recipes.path"),
   });
   return this._recipeManager.initializationPromise;
 });
 
 XPCOMUtils.defineLazyPreferenceGetter(LoginManagerParent, "_repromptTimeout",
-  "signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
+  "signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
\ No newline at end of file
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -142,16 +142,30 @@ savant:
     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
+  login_form:
+    objects: ["load", "submit"]
+    release_channel_collection: opt-out
+    record_in_processes: ["content"]
+    description: >
+      A login form has been loaded or submitted
+    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. load -> submit
 
 # 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]