Bug 1465685 - Add login_form probe for Savant Shield study; r=MattN, a=RyanVM
authorBianca Danforth <bdanforth@mozilla.com>
Thu, 07 Jun 2018 03:24:09 -0700
changeset 473714 63275d610ea3f9c82e2d88b923443beaa0fbc311
parent 473713 41f2ad70c0eaa3abc0d8935fe1ec19a7a5e967a5
child 473715 13af68f9e6d0b394945dfe041b4ef5108abfddb9
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN, RyanVM
bugs1465685, 1287202
milestone61.0
Bug 1465685 - Add login_form probe for Savant Shield study; r=MattN, a=RyanVM 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'. This value associates actions that occur in the same tab. 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. * Unlike 'load', the 'submit' event fires only when the Password Manager is enabled and the user is in a non-private window. 'Load' events will have a 'canRecordSubmit' key in the 'extra' field which will be true if a submit event for that form can be recorded. MozReview-Commit-ID: LOMDSN6tgRV
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
@@ -224,16 +224,17 @@ const listeners = {
     "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:LoginFillSuccessful": ["LoginManagerParent"],
+    "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
@@ -433,18 +433,24 @@ var LoginManagerContent = {
    * Fetch logins from the parent for a given form and then attempt to fill it.
    *
    * @param {FormLike} form to fetch the logins for then try autofill.
    * @param {Window} window
    */
   _fetchLoginsFromParentAndFillForm(form, window) {
     this._detectInsecureFormLikes(window);
 
+    const isPrivateWindow = PrivateBrowsingUtils.isContentWindowPrivate(window);
+
     let messageManager = messageManagerFromWindow(window);
-    messageManager.sendAsyncMessage("LoginStats:LoginEncountered");
+    messageManager.sendAsyncMessage("LoginStats:LoginEncountered",
+                                    {
+                                      isPrivateWindow,
+                                      isPwmgrEnabled: gEnabled,
+                                    });
 
     if (!gEnabled) {
       return;
     }
 
     this._getLoginDataFromParent(form, { showMasterPassword: true })
         .then(this.loginsFound.bind(this))
         .catch(Cu.reportError);
--- a/toolkit/components/passwordmgr/LoginManagerParent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ -88,16 +88,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 flow_id = msg.target.ownerGlobal.gBrowser.getTabForBrowser(msg.target).linkedPanel;
+        Services.telemetry.recordEvent("savant", "login_form", "submit", null,
+                                      {
+                                        subcategory: "encounter",
+                                        flow_id,
+                                      });
         break;
       }
 
       case "RemoteLogins:insecureLoginFormPresent": {
         this.setHasInsecureLoginForms(msg.target, data.hasInsecureLoginForms);
         break;
       }
 
@@ -116,16 +123,28 @@ var LoginManagerParent = {
         const flow_id = msg.target.ownerGlobal.gBrowser.getTabForBrowser(msg.target).linkedPanel;
         Services.telemetry.recordEvent("savant", "pwmgr_use", "use", null,
                                       {
                                         subcategory: "feature",
                                         flow_id,
                                       });
         break;
       }
+
+      case "LoginStats:LoginEncountered": {
+        const canRecordSubmit = (!data.isPrivateWindow && data.isPwmgrEnabled).toString();
+        const flow_id = msg.target.ownerGlobal.gBrowser.getTabForBrowser(msg.target).linkedPanel;
+        Services.telemetry.recordEvent("savant", "login_form", "load", null,
+                                      {
+                                        subcategory: "encounter",
+                                        flow_id,
+                                        canRecordSubmit,
+                                      });
+        break;
+      }
     }
 
     return undefined;
   },
 
   /**
    * Trigger a login form fill and send relevant data (e.g. logins and recipes)
    * to the child process (LoginManagerContent).
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -250,16 +250,32 @@ 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 tab identifier to associate events occuring in the same tab
+  login_form:
+    objects: ["load", "submit"]
+    release_channel_collection: opt-out
+    record_in_processes: ["main"]
+    description: >
+      A login form has been loaded or submitted. Login form submit events only
+      fire in non-private windows with Password Manager enabled.
+    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 tab identifier to associate events occuring in the same tab
+      canRecordSubmit: True if a login form loads in a non-private window with Password Manager enabled.
 
 # 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]