Bug 1339515 - [Form Autofill] Add built-in debug logging to ease debugging. r=steveck

MozReview-Commit-ID: F4w2CzdWdrI

--HG--
extra : rebase_source : 33ea952b4d3d28013d9d9efaa1fc0efe57d3956f
This commit is contained in:
Matthew Noorenberghe 2017-02-15 16:22:38 +08:00
parent d29f094da0
commit 4f85765ea4
7 changed files with 73 additions and 11 deletions

View File

@ -1580,6 +1580,7 @@ pref("services.sync.validation.enabled", true);
// Preferences for the form autofill system extension
pref("browser.formautofill.experimental", false);
pref("browser.formautofill.enabled", false);
pref("browser.formautofill.loglevel", "Warn");
// Enable safebrowsing v4 tables (suffixed by "-proto") update.
#ifdef NIGHTLY_BUILD

View File

@ -16,6 +16,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr, manager: Cm} = Compo
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ProfileAutoCompleteResult",
"resource://formautofill/ProfileAutoCompleteResult.jsm");
@ -67,7 +68,7 @@ AutocompleteFactory.prototype = {
* @implements {nsIAutoCompleteSearch}
*/
function AutofillProfileAutoCompleteSearch() {
FormAutofillUtils.defineLazyLogGetter(this, "AutofillProfileAutoCompleteSearch");
}
AutofillProfileAutoCompleteSearch.prototype = {
classID: Components.ID("4f9f1e4c-7f2c-439e-9c9e-566b68bc187d"),
@ -87,6 +88,7 @@ AutofillProfileAutoCompleteSearch.prototype = {
* @param {Object} listener the listener to notify when the search is complete
*/
startSearch(searchString, searchParam, previousResult, listener) {
this.log.debug("startSearch: for", searchString, "with input", formFillController.focusedInput);
let focusedInput = formFillController.focusedInput;
this.forceStop = false;
let info = this._serializeInfo(FormAutofillContent.getInputDetails(focusedInput));
@ -130,6 +132,7 @@ AutofillProfileAutoCompleteSearch.prototype = {
* Promise that resolves when profiles returned from parent process.
*/
_getProfiles(data) {
this.log.debug("_getProfiles with data:", data);
return new Promise((resolve) => {
Services.cpmm.addMessageListener("FormAutofill:Profiles", function getResult(result) {
Services.cpmm.removeMessageListener("FormAutofill:Profiles", getResult);
@ -161,6 +164,8 @@ let ProfileAutocomplete = {
return;
}
FormAutofillUtils.defineLazyLogGetter(this, "ProfileAutocomplete");
this.log.debug("ensureRegistered");
this._factory = new AutocompleteFactory();
this._factory.register(AutofillProfileAutoCompleteSearch);
this._registered = true;
@ -173,6 +178,7 @@ let ProfileAutocomplete = {
return;
}
this.log.debug("ensureUnregistered");
this._factory.unregister();
this._factory = null;
this._registered = false;
@ -206,6 +212,7 @@ let ProfileAutocomplete = {
},
_fillFromAutocompleteRow(focusedInput) {
this.log.debug("_fillFromAutocompleteRow:", focusedInput);
let formDetails = FormAutofillContent.getFormDetails(focusedInput);
if (!formDetails) {
// The observer notification is for a different frame.
@ -250,11 +257,13 @@ let ProfileAutocomplete = {
*/
var FormAutofillContent = {
/**
* @type {WeakMap} mapping FormLike root HTML elements to form details.
* @type {WeakMap} mapping FormLike root HTML elements to FormAutofillHandler objects.
*/
_formsDetails: new WeakMap(),
init() {
FormAutofillUtils.defineLazyLogGetter(this, "FormAutofillContent");
Services.cpmm.addMessageListener("FormAutofill:enabledStatus", (result) => {
if (result.data) {
ProfileAutocomplete.ensureRegistered();
@ -306,6 +315,7 @@ var FormAutofillContent = {
},
_identifyAutofillFields(doc) {
this.log.debug("_identifyAutofillFields:", "" + doc.location);
let forms = [];
// Collects root forms from inputs.
@ -322,18 +332,22 @@ var FormAutofillContent = {
}
}
this.log.debug("Found", forms.length, "forms");
// Collects the fields that can be autofilled from each form and marks them
// as autofill fields if the amount is above the threshold.
forms.forEach(form => {
let formHandler = new FormAutofillHandler(form);
formHandler.collectFormFields();
if (formHandler.fieldDetails.length < AUTOFILL_FIELDS_THRESHOLD) {
this.log.debug("Ignoring form since it has only", formHandler.fieldDetails.length,
"field(s)");
return;
}
this._formsDetails.set(form.rootElement, formHandler);
formHandler.fieldDetails.forEach(
detail => this._markAsAutofillField(detail.element));
this.log.debug("Adding form handler to _formsDetails:", formHandler);
formHandler.fieldDetails.forEach(detail => this._markAsAutofillField(detail.element));
});
},

View File

@ -14,9 +14,14 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillHeuristics",
"resource://formautofill/FormAutofillHeuristics.jsm");
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
/**
* Handles profile autofill for a DOM Form element.
* @param {FormLike} form Form that need to be auto filled
@ -71,6 +76,7 @@ FormAutofillHandler.prototype = {
f.contactType == info.contactType &&
f.fieldName == info.fieldName)) {
// A field with the same identifier already exists.
log.debug("Not collecting a field matching another with the same info:", info);
return null;
}
@ -90,6 +96,8 @@ FormAutofillHandler.prototype = {
this.fieldDetails.push(formatWithElement);
}
log.debug("Collected details on", autofillData.length, "fields");
return autofillData;
},
@ -110,6 +118,7 @@ FormAutofillHandler.prototype = {
* }
*/
autofillFormFields(autofillResult) {
log.debug("autofillFormFields:", autofillResult);
for (let field of autofillResult) {
// TODO: Skip filling the value of focused input which is filled in
// FormFillController.

View File

@ -29,12 +29,16 @@
"use strict";
this.EXPORTED_SYMBOLS = ["FormAutofillParent"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ProfileStorage",
@ -42,6 +46,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "ProfileStorage",
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillPreferences",
"resource://formautofill/FormAutofillPreferences.jsm");
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
const PROFILE_JSON_FILE_NAME = "autofill-profiles.json";
const ENABLED_PREF = "browser.formautofill.enabled";
@ -63,6 +70,7 @@ FormAutofillParent.prototype = {
* Initializes ProfileStorage and registers the message handler.
*/
init() {
log.debug("init");
let storePath = OS.Path.join(OS.Constants.Path.profileDir, PROFILE_JSON_FILE_NAME);
this._profileStore = new ProfileStorage(storePath);
this._profileStore.initialize();
@ -79,6 +87,7 @@ FormAutofillParent.prototype = {
},
observe(subject, topic, data) {
log.debug("observe:", topic, "with data:", data);
switch (topic) {
case "advanced-pane-loaded": {
let formAutofillPreferences = new FormAutofillPreferences();
@ -111,6 +120,7 @@ FormAutofillParent.prototype = {
* form autofill status changed.
*/
_onStatusChanged() {
log.debug("_onStatusChanged: Status changed to", this._enabled);
if (this._enabled) {
Services.ppmm.addMessageListener("FormAutofill:GetProfiles", this);
} else {
@ -199,5 +209,3 @@ FormAutofillParent.prototype = {
target.sendAsyncMessage("FormAutofill:Profiles", profiles);
},
};
this.EXPORTED_SYMBOLS = ["FormAutofillParent"];

View File

@ -6,7 +6,21 @@
this.EXPORTED_SYMBOLS = ["FormAutofillUtils"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
this.FormAutofillUtils = {
defineLazyLogGetter(scope, logPrefix) {
XPCOMUtils.defineLazyGetter(scope, "log", () => {
let ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
return new ConsoleAPI({
maxLogLevelPref: "browser.formautofill.loglevel",
prefix: logPrefix,
});
});
},
generateFullName(firstName, lastName, middleName) {
// TODO: The implementation should depend on the L10N spec, but a simplified
// rule is used here.

View File

@ -9,15 +9,18 @@ this.EXPORTED_SYMBOLS = ["ProfileAutoCompleteResult"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillUtils",
"resource://formautofill/FormAutofillUtils.jsm");
this.ProfileAutoCompleteResult = function(searchString,
focusedFieldName,
allFieldNames,
matchingProfiles,
{resultCode = null}) {
log.debug("Constructing new ProfileAutoCompleteResult:", [...arguments]);
this.searchString = searchString;
this._focusedFieldName = focusedFieldName;
this._allFieldNames = allFieldNames;

View File

@ -39,12 +39,16 @@
"use strict";
this.EXPORTED_SYMBOLS = ["ProfileStorage"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "JSONFile",
"resource://gre/modules/JSONFile.jsm");
@ -52,6 +56,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
const SCHEMA_VERSION = 1;
// Name-related fields will be handled in follow-up bugs due to the complexity.
@ -107,6 +114,7 @@ ProfileStorage.prototype = {
* The new profile for saving.
*/
add(profile) {
log.debug("add:", profile);
this._store.ensureDataReady();
let profileToSave = this._normalizeProfile(profile);
@ -135,6 +143,7 @@ ProfileStorage.prototype = {
* The new profile used to overwrite the old one.
*/
update(guid, profile) {
log.debug("update:", guid, profile);
this._store.ensureDataReady();
let profileFound = this._findByGUID(guid);
@ -184,6 +193,7 @@ ProfileStorage.prototype = {
* Indicates which profile to remove.
*/
remove(guid) {
log.debug("remove:", guid);
this._store.ensureDataReady();
this._store.data.profiles =
@ -200,6 +210,7 @@ ProfileStorage.prototype = {
* A clone of the profile.
*/
get(guid) {
log.debug("get:", guid);
this._store.ensureDataReady();
let profileFound = this._findByGUID(guid);
@ -218,6 +229,7 @@ ProfileStorage.prototype = {
* An array containing clones of all profiles.
*/
getAll() {
log.debug("getAll");
this._store.ensureDataReady();
// Profiles are cloned to avoid accidental modifications from outside.
@ -231,10 +243,13 @@ ProfileStorage.prototype = {
* An array containing clones of matched profiles.
*/
getByFilter({info, searchString}) {
log.debug("getByFilter:", info, searchString);
this._store.ensureDataReady();
// Profiles are cloned to avoid accidental modifications from outside.
return this._findByFilter({info, searchString}).map(this._clone);
let result = this._findByFilter({info, searchString}).map(this._clone);
log.debug("getByFilter: Returning", result.length, "result(s)");
return result;
},
_clone(profile) {
@ -291,5 +306,3 @@ ProfileStorage.prototype = {
return this._store._save();
},
};
this.EXPORTED_SYMBOLS = ["ProfileStorage"];