Bug 1124465 - Add telemetry probe for usage of the password capture dialog. r=MattN draft
authorChenxia Liu <liuche@mozilla.com>
Fri, 06 Feb 2015 11:39:03 -0800
changeset 242752 0f61b46164d35bd2462738f0141bba41cf891084
parent 242123 b04123c901ac90b12dffe6ca25f8765126cca0cc
child 505333 cf790f7481258a7ba38e6b26f506cf0d89c1e505
push id686
push usercliu@mozilla.com
push dateFri, 13 Feb 2015 23:19:21 +0000
reviewersMattN
bugs1124465
milestone38.0a1
Bug 1124465 - Add telemetry probe for usage of the password capture dialog. r=MattN
mobile/android/components/LoginManagerPrompter.js
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/components/telemetry/Histograms.json
--- a/mobile/android/components/LoginManagerPrompter.js
+++ b/mobile/android/components/LoginManagerPrompter.js
@@ -4,16 +4,28 @@
 
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry",
+                                  "resource://gre/modules/UITelemetry.jsm");
+
+/* Constants for password prompt telemetry.
+ * Mirrored in nsLoginManagerPrompter.js */
+const PROMPT_RES_DISPLAYED = 1;
+
+const PROMPT_RES_ADD = 2;
+const PROMPT_RES_NOTNOW = 3;
+const PROMPT_RES_NEVER = 4;
+
+const PROMPT_RES_UPDATE = 2;
 
 /* ==================== LoginManagerPrompter ==================== */
 /*
  * LoginManagerPrompter
  *
  * Implements interfaces for prompting the user to enter/save/change auth info.
  *
  * nsILoginManagerPrompter: Used by Login Manager for saving/changing logins
@@ -113,16 +125,18 @@ LoginManagerPrompter.prototype = {
     },
 
     /*
      * promptToSavePassword
      *
      */
     promptToSavePassword : function (aLogin) {
         this._showSaveLoginNotification(aLogin);
+        Services.telemetry.getHistogramById("PWMGR_SAVE_SELECTION_STATE").add(PROMPT_RES_DISPLAYED);
+
     },
 
 
     /*
      * _showLoginNotification
      *
      * Displays a notification doorhanger.
      *
@@ -170,27 +184,32 @@ LoginManagerPrompter.prototype = {
         } else {
             notificationText  = this._getLocalizedString("savePasswordNoUser", [displayHost]);
         }
 
         // The callbacks in |buttons| have a closure to access the variables
         // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
         // without a getService() call.
         var pwmgr = this._pwmgr;
+        let promptHistogram = Services.telemetry.getHistogramById("PWMGR_PROMPT_SELECTION_STATE");
 
         var buttons = [
             {
                 label: this._getLocalizedString("saveButton"),
                 callback: function() {
                     pwmgr.addLogin(aLogin);
+                    promptHistogram.add(PROMPT_RES_ADD);
+                    UITelemetry.addEvent("action.1", "dialog", null, "login-add");
                 }
             },
             {
                 label: this._getLocalizedString("dontSaveButton"),
                 callback: function() {
+                    promptHistogram.add(PROMPT_RES_NOTNOW);
+                    UITelemetry.addEvent("action.1", "dialog", null, "login-notnow");
                     // Don't set a permanent exception
                 }
             }
         ];
 
         this._showLoginNotification("password-save", notificationText, buttons);
     },
 
@@ -199,16 +218,18 @@ LoginManagerPrompter.prototype = {
      *
      * Called when we think we detect a password change for an existing
      * login, when the form being submitted contains multiple password
      * fields.
      *
      */
     promptToChangePassword : function (aOldLogin, aNewLogin) {
         this._showChangeLoginNotification(aOldLogin, aNewLogin.password);
+        Services.telemetry.getHistogramById("PWMGR_UPDATE_SELECTION_STATE").add(PROMPT_RES_DISPLAYED);
+
     },
 
     /*
      * _showChangeLoginNotification
      *
      * Shows the Change Password notification doorhanger.
      *
      */
@@ -220,27 +241,32 @@ LoginManagerPrompter.prototype = {
         } else {
             notificationText  = this._getLocalizedString("updatePasswordNoUser");
         }
 
         // The callbacks in |buttons| have a closure to access the variables
         // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
         // without a getService() call.
         var self = this;
+        let promptHistogram = Services.telemetry.getHistogramById("PWMGR_UPDATE_SELECTION_STATE");
 
         var buttons = [
             {
                 label: this._getLocalizedString("updateButton"),
                 callback:  function() {
                     self._updateLogin(aOldLogin, aNewPassword);
+                    promptHistogram.add(PROMPT_RES_UPDATE);
+                    UITelemetry.addEvent("action.1", "dialog", null, "login-update");
                 }
             },
             {
                 label: this._getLocalizedString("dontUpdateButton"),
                 callback:  function() {
+                    promptHistogram.add(PROMPT_RES_NOTNOW);
+                    UITelemetry.addEvent("action.1", "dialog", null, "login-notnow");
                     // do nothing
                 }
             }
         ];
 
         this._showLoginNotification("password-change", notificationText, buttons);
     },
 
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -8,16 +8,26 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Components.utils.import("resource://gre/modules/SharedPromptUtils.jsm");
 
+/* Constants for password prompt telemetry.
+ * Mirrored in mobile/android/components/LoginManagerPrompter.js */
+const PROMPT_RES_DISPLAYED = 1;
+
+const PROMPT_RES_ADD = 2;
+const PROMPT_RES_NOTNOW = 3;
+const PROMPT_RES_NEVER = 4;
+
+const PROMPT_RES_UPDATE = 2;
+
 /*
  * LoginManagerPromptFactory
  *
  * Implements nsIPromptFactory
  *
  * Invoked by [toolkit/components/prompts/src/nsPrompter.js]
  */
 function LoginManagerPromptFactory() {
@@ -727,16 +737,17 @@ LoginManagerPrompter.prototype = {
 
 
   /*
    * promptToSavePassword
    *
    */
   promptToSavePassword : function (aLogin) {
     var notifyObj = this._getPopupNote() || this._getNotifyBox();
+    Services.telemetry.getHistogramById("PWMGR_SAVE_SELECTION_STATE").add(PROMPT_RES_DISPLAYED);
 
     if (notifyObj)
       this._showSaveLoginNotification(notifyObj, aLogin);
     else
       this._showSaveLoginDialog(aLogin);
   },
 
 
@@ -767,29 +778,27 @@ LoginManagerPrompter.prototype = {
     newBar.timeout = Date.now() + 20000; // 20 seconds
 
     if (oldBar) {
       this.log("(...and removing old " + aName + " notification bar)");
       aNotifyBox.removeNotification(oldBar);
     }
   },
 
-
   /*
    * _showSaveLoginNotification
    *
    * Displays a notification bar or a popup notification, to allow the user
    * to save the specified login. This allows the user to see the results of
    * their login, and only save a login which they know worked.
    *
    * @param aNotifyObj
    *        A notification box or a popup notification.
    */
   _showSaveLoginNotification : function (aNotifyObj, aLogin) {
-
     // Ugh. We can't use the strings from the popup window, because they
     // have the access key marked in the string (eg "Mo&zilla"), along
     // with some weird rules for handling access keys that do not occur
     // in the string, for L10N. See commonDialog.js's setLabelForNode().
     var neverButtonText =
           this._getLocalizedString("notifyBarNeverRememberButtonText");
     var neverButtonAccessKey =
           this._getLocalizedString("notifyBarNeverRememberButtonAccessKey");
@@ -810,35 +819,38 @@ LoginManagerPrompter.prototype = {
                                   "rememberPasswordMsgNoUsername",
                                   [displayHost]);
     }
 
     // The callbacks in |buttons| have a closure to access the variables
     // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
     // without a getService() call.
     var pwmgr = this._pwmgr;
+    let promptHistogram = Services.telemetry.getHistogramById("PWMGR_SAVE_SELECTION_STATE");
 
     // Notification is a PopupNotification
     if (aNotifyObj == this._getPopupNote()) {
       // "Remember" button
       var mainAction = {
         label:     rememberButtonText,
         accessKey: rememberButtonAccessKey,
         callback: function(aNotifyObj, aButton) {
+          promptHistogram.add(PROMPT_RES_ADD);
           pwmgr.addLogin(aLogin);
           browser.focus();
         }
       };
 
       var secondaryActions = [
         // "Never for this site" button
         {
           label:     neverButtonText,
           accessKey: neverButtonAccessKey,
           callback: function(aNotifyObj, aButton) {
+            promptHistogram.add(PROMPT_RES_NEVER);
             pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
             browser.focus();
           }
         }
       ];
 
       var { browser } = this._getNotifyWindow();
 
@@ -979,16 +991,17 @@ LoginManagerPrompter.prototype = {
    *
    * Called when we think we detect a password change for an existing
    * login, when the form being submitted contains multiple password
    * fields.
    *
    */
   promptToChangePassword : function (aOldLogin, aNewLogin) {
     var notifyObj = this._getPopupNote() || this._getNotifyBox();
+    Services.telemetry.getHistogramById("PWMGR_UPDATE_SELECTION_STATE").add(PROMPT_RES_DISPLAYED);
 
     if (notifyObj)
       this._showChangeLoginNotification(notifyObj, aOldLogin,
                                         aNewLogin.password);
     else
       this._showChangeLoginDialog(aOldLogin, aNewLogin.password);
   },
 
@@ -1018,25 +1031,27 @@ LoginManagerPrompter.prototype = {
     var changeButtonAccessKey =
           this._getLocalizedString("notifyBarUpdateButtonAccessKey");
 
     // The callbacks in |buttons| have a closure to access the variables
     // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
     // without a getService() call.
     var self = this;
 
+    let promptHistogram = Services.telemetry.getHistogramById("PWMGR_UPDATE_SELECTION_STATE");
     // Notification is a PopupNotification
     if (aNotifyObj == this._getPopupNote()) {
       // "Yes" button
       var mainAction = {
         label:     changeButtonText,
         accessKey: changeButtonAccessKey,
         popup:     null,
         callback:  function(aNotifyObj, aButton) {
           self._updateLogin(aOldLogin, aNewPassword);
+          promptHistogram.add(PROMPT_RES_UPDATE);
         }
       };
 
       var { browser } = this._getNotifyWindow();
 
       aNotifyObj.show(browser, "password-change", notificationText,
                       "password-notification-icon", mainAction,
                       null, { timeout: Date.now() + 10000,
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7331,21 +7331,33 @@
   },
   "PWMGR_LOGIN_LAST_USED_DAYS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 750,
     "n_buckets" : 40,
     "description": "Time in days each saved login was last used"
   },
+  "PWMGR_SAVE_SELECTION_STATE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 5,
+    "description": "Selection made by user through prompt for creating a login"
+  },
   "PWMGR_SAVING_ENABLED": {
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Number of users who have password saving on globally"
   },
+  "PWMGR_UPDATE_SELECTION_STATE": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 5,
+    "description": "Selection made by user through prompt for modifying a login"
+  },
   "PWMGR_USERNAME_PRESENT": {
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Whether a saved login has a username"
   },
   "FENNEC_SYNC11_MIGRATION_SENTINELS_SEEN": {
     "expires_in_version": "45",
     "kind": "count",