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'. 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
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -225,16 +225,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
@@ -89,16 +89,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;
}
@@ -117,16 +124,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]