From 88771f23feae47007cb332285985fa833057240a Mon Sep 17 00:00:00 2001 From: "Adam Roach [:abr]" Date: Mon, 10 Aug 2020 23:02:15 +0000 Subject: [PATCH] Bug 1654388: Part 2: Record address and password usage r=zbraniecki Differential Revision: https://phabricator.services.mozilla.com/D86126 --- .../formautofill/FormAutofillStorage.jsm | 41 +++++++ .../test/mochitest/formautofill_common.js | 20 ++++ .../test_address_level_1_submission.html | 2 + .../test_basic_autocomplete_form.html | 2 + .../components/passwordmgr/storage-json.js | 17 ++- .../passwordmgr/test/mochitest/mochitest.ini | 3 + .../test/mochitest/test_usage_prefs.html | 111 ++++++++++++++++++ 7 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_usage_prefs.html diff --git a/browser/extensions/formautofill/FormAutofillStorage.jsm b/browser/extensions/formautofill/FormAutofillStorage.jsm index 1d153f2752e1c..c21749f68b7a5 100644 --- a/browser/extensions/formautofill/FormAutofillStorage.jsm +++ b/browser/extensions/formautofill/FormAutofillStorage.jsm @@ -307,6 +307,7 @@ class AutofillRecords { if (dataHasChanges) { this._store.saveSoon(); } + this._onDataLoaded(); }); } @@ -543,6 +544,8 @@ class AutofillRecords { * * @param {string} guid * Indicates which record to be notified. + * @returns {Object} + * Record corresponding to the guid that was used */ notifyUsed(guid) { this.log.debug("notifyUsed:", guid); @@ -568,6 +571,7 @@ class AutofillRecords { "formautofill-storage-changed", "notifyUsed" ); + return recordFound; } updateUseCountTelemetry() {} @@ -1439,6 +1443,9 @@ class AutofillRecords { // An interface to be inherited. async mergeIfPossible(guid, record, strict) {} + + // Called once initalization has completed + _onDataLoaded() {} } class Addresses extends AutofillRecords { @@ -1450,6 +1457,15 @@ class Addresses extends AutofillRecords { VALID_ADDRESS_COMPUTED_FIELDS, ADDRESS_SCHEMA_VERSION ); + Services.obs.addObserver(this, "formautofill-storage-changed"); + } + + observe(subject, topic, data) { + switch (topic) { + case "formautofill-storage-changed": + this._recordEntryPresent(); + break; + } } _recordReadProcessor(address) { @@ -1756,6 +1772,31 @@ class Addresses extends AutofillRecords { await this.update(guid, addressToMerge, true); return true; } + + _onDataLoaded() { + this._recordEntryPresent(); + } + + // Record in prefs whether the user has any address entries stored. + // This information is not uploaded as telemetry, and is used to target + // user surveys. See Bug 1654388 for details. + _recordEntryPresent() { + const records = this._data.filter(entry => !entry.deleted); + this.log.debug("Address records:", records); + Services.prefs.setBoolPref( + "extensions.formautofill.addresses.usage.hasEntry", + !!records.length + ); + } + + notifyUsed(guid) { + const record = super.notifyUsed(guid); + Services.prefs.setIntPref( + "extensions.formautofill.addresses.usage.lastUsed", + Math.floor(record.timeLastUsed / 1000) + ); + return record; + } } class CreditCards extends AutofillRecords { diff --git a/browser/extensions/formautofill/test/mochitest/formautofill_common.js b/browser/extensions/formautofill/test/mochitest/formautofill_common.js index d6635325bd369..28c6ff3ccf43a 100644 --- a/browser/extensions/formautofill/test/mochitest/formautofill_common.js +++ b/browser/extensions/formautofill/test/mochitest/formautofill_common.js @@ -439,4 +439,24 @@ function formAutoFillCommonSetup() { ); } +function checkUsagePrefs(hasEntry, lastUsed) { + lastUsed = Math.floor(lastUsed); + is( + SpecialPowers.getBoolPref( + "extensions.formautofill.addresses.usage.hasEntry", + false + ), + hasEntry, + "hasEntry usage pref is " + hasEntry + ); + const lastUsedPref = SpecialPowers.getIntPref( + "extensions.formautofill.addresses.usage.lastUsed", + 0 + ); + ok( + lastUsed - lastUsedPref < 10, + `lastUsed usage pref (${lastUsedPref}) is within 10 seconds of ${lastUsed}` + ); +} + formAutoFillCommonSetup(); diff --git a/browser/extensions/formautofill/test/mochitest/test_address_level_1_submission.html b/browser/extensions/formautofill/test/mochitest/test_address_level_1_submission.html index 0c16b91d3a663..cb361f9cc27d3 100644 --- a/browser/extensions/formautofill/test/mochitest/test_address_level_1_submission.html +++ b/browser/extensions/formautofill/test/mochitest/test_address_level_1_submission.html @@ -75,6 +75,8 @@ let matching = await checkAddresses(TEST_ADDRESSES); ok(matching, "Address saved as expected"); + checkUsagePrefs(true, Date.now()/1000); + await loadPromise; isnot(window.submit_frame.location.href, "about:blank", "Check form submitted"); }); diff --git a/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html b/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html index a642b2abca3bf..ef7589bc2f256 100644 --- a/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html +++ b/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html @@ -74,7 +74,9 @@ // Form with both history and address storage. add_task(async function check_menu_when_both_existed() { + checkUsagePrefs(false, 0); await setupAddressStorage(); + checkUsagePrefs(true, 0); await setInput("#organization", ""); await notExpectPopup(); diff --git a/toolkit/components/passwordmgr/storage-json.js b/toolkit/components/passwordmgr/storage-json.js index 8a7fba89da45b..07b28e21b42cd 100644 --- a/toolkit/components/passwordmgr/storage-json.js +++ b/toolkit/components/passwordmgr/storage-json.js @@ -105,6 +105,7 @@ class LoginManagerStorage_json { // Load the data asynchronously. this.log("Opening database at", this._store.path); await this._store.load(); + this._recordEntryPresent(); })().catch(Cu.reportError); } catch (e) { this.log("Initialization failed:", e); @@ -266,6 +267,7 @@ class LoginManagerStorage_json { // Send a notification that a login was added. LoginHelper.notifyStorageChanged("addLogin", loginClone); + this._recordEntryPresent(); return loginClone; } @@ -284,6 +286,7 @@ class LoginManagerStorage_json { } LoginHelper.notifyStorageChanged("removeLogin", storedLogin); + this._recordEntryPresent(); } modifyLogin(oldLogin, newLoginData) { @@ -349,9 +352,11 @@ class LoginManagerStorage_json { let propBag = Cc["@mozilla.org/hash-property-bag;1"].createInstance( Ci.nsIWritablePropertyBag ); - propBag.setProperty("timeLastUsed", Date.now()); + let now = Date.now(); + propBag.setProperty("timeLastUsed", now); propBag.setProperty("timesUsedIncrement", 1); this.modifyLogin(login, propBag); + Services.prefs.setIntPref("signon.usage.lastUsed", Math.floor(now / 1000)); } async recordBreachAlertDismissal(loginGUID) { @@ -828,6 +833,16 @@ class LoginManagerStorage_json { return result; } + + // Record in prefs whether the user has any password entries stored. + // This information is not uploaded as telemetry, and is used to target + // user surveys. See Bug 1654388 for details. + _recordEntryPresent() { + Services.prefs.setBoolPref( + "signon.usage.hasEntry", + !!this._store.data.logins.length + ); + } } XPCOMUtils.defineLazyGetter(LoginManagerStorage_json.prototype, "log", () => { diff --git a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini index e081cba0f50f8..c8eb70061eaf7 100644 --- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini +++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini @@ -236,6 +236,9 @@ skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts support-files = subtst_prefilled_form.html skip-if = (xorigin && fission) # Hangs +[test_usage_prefs.html] +scheme = https +skip-if = (xorigin && fission) # Hangs [test_username_focus.html] skip-if = toolkit == 'android' # android:autocomplete. || (xorigin && fission) # Hangs diff --git a/toolkit/components/passwordmgr/test/mochitest/test_usage_prefs.html b/toolkit/components/passwordmgr/test/mochitest/test_usage_prefs.html new file mode 100644 index 0000000000000..fb07df61c4638 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_usage_prefs.html @@ -0,0 +1,111 @@ + + + + + Test usage prefs + + + + + +Login Manager test: usage prefs collection + + + +

+ + + +

+
+
+