Backed out 9 changesets (bug 1548381) for XPCShell failures in toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_doAutocompleteSearch.js
authorDorel Luca <dluca@mozilla.com>
Tue, 21 May 2019 03:19:42 +0300
changeset 474646 2690e619a493a6730d6318589405aa2e229ba5c3
parent 474645 2e560a9e4bcffc8476086c1da25c7412cd9a1805
child 474647 4a3fcb8ad12cd7db72b7c805e4b07534760c95b4
push id36042
push userdvarga@mozilla.com
push dateTue, 21 May 2019 04:19:40 +0000
treeherdermozilla-central@ca560ff55451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1548381
milestone69.0a1
backs out0e7d8f96bf123f5d0f491fe7780223bde509e841
738ce5e88e05ae37464b0e94889a5156c5497435
38e35b6d8d80300cb306a782d1167ec5343acd36
cddbcd92ec10d62b501a42472f99152af909d26e
60ff6e363acf84e6c77e0f10fa47acced7b7968e
1e2300b95a59dfa70594e01e6b34716141e22105
e0cf735bdcf5235d4e2e7416d5a07956e7e74671
fde90ccfb57027a25127edd92eade0bc3e8c853f
426750b88fc2c221b005da3c4d8918216c7c0548
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 9 changesets (bug 1548381) for XPCShell failures in toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_doAutocompleteSearch.js Backed out changeset 0e7d8f96bf12 (bug 1548381) Backed out changeset 738ce5e88e05 (bug 1548381) Backed out changeset 38e35b6d8d80 (bug 1548381) Backed out changeset cddbcd92ec10 (bug 1548381) Backed out changeset 60ff6e363acf (bug 1548381) Backed out changeset 1e2300b95a59 (bug 1548381) Backed out changeset e0cf735bdcf5 (bug 1548381) Backed out changeset fde90ccfb570 (bug 1548381) Backed out changeset 426750b88fc2 (bug 1548381)
browser/base/content/test/static/browser_all_files_referenced.js
browser/themes/shared/autocomplete.inc.css
modules/libpref/init/all.js
toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/LoginManagerParent.jsm
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
toolkit/components/passwordmgr/test/mochitest/test_autocomplete_new_password.html
toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_doAutocompleteSearch.js
toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_getGeneratedPassword.js
toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
toolkit/components/passwordmgr/test/unit/xpcshell.ini
toolkit/content/widgets/autocomplete-popup.js
toolkit/content/widgets/autocomplete-richlistitem.js
toolkit/content/widgets/autocomplete.xml
toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -142,16 +142,18 @@ var whitelist = [
   {file: "chrome://mozapps/skin/downloads/downloadButtons.png", platforms: ["linux", "win"]},
   // Bug 1348558
   {file: "chrome://mozapps/skin/update/downloadButtons.png",
    platforms: ["linux"]},
   // Bug 1348559
   {file: "chrome://pippki/content/resetpassword.xul"},
   // Bug 1337345
   {file: "resource://gre/modules/Manifest.jsm"},
+  // Bug 1548381
+  {file: "resource://gre/modules/PasswordGenerator.jsm"},
   // Bug 1351097
   {file: "resource://gre/modules/accessibility/AccessFu.jsm"},
   // Bug 1356043
   {file: "resource://gre/modules/PerfMeasurement.jsm"},
   // Bug 1356045
   {file: "chrome://global/content/test-ipc.xul"},
   // Bug 1378173 (warning: still used by devtools)
   {file: "resource://gre/modules/Promise.jsm"},
--- a/browser/themes/shared/autocomplete.inc.css
+++ b/browser/themes/shared/autocomplete.inc.css
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 %endif
 
 /* General popup rules */
 
 #PopupAutoComplete > richlistbox > richlistitem {
+  height: 20px;
   min-height: 20px;
   border: 0;
   border-radius: 0;
   padding: 0px 1px 0px 1px;
 }
 
 #PopupAutoComplete > richlistbox > richlistitem > .ac-site-icon {
   margin-inline-start: 4px;
@@ -33,78 +34,67 @@
   background-color: var(--arrowpanel-dimmed);
 }
 
 .autocomplete-richlistitem[selected] {
   background-color: Highlight;
   color: HighlightText;
 }
 
-/* Autocomplete richlistitem support for a two-line label display */
+/* Login form autocompletion with and without origin showing */
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .login-wrapper > .ac-site-icon,
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon {
+  display: initial;
+  list-style-image: url(chrome://browser/skin/login.svg);
+  -moz-context-properties: fill;
+  fill: GrayText;
+}
 
-#PopupAutoComplete > richlistbox > richlistitem > .two-line-wrapper {
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"][selected] > .login-wrapper > .ac-site-icon,
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon[selected] {
+  fill: HighlightText;
+}
+
+/* Login form autocompletion with origin showing */
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] {
+  height: auto;
+  padding: 4px;
+}
+
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .login-wrapper {
   box-sizing: border-box;
   display: flex;
   flex-direction: row;
   margin: 0;
 }
 
-#PopupAutoComplete > richlistbox > richlistitem > .two-line-wrapper > .ac-site-icon {
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .login-wrapper > .ac-site-icon {
   margin-inline-start: auto;
   margin-inline-end: 4px;
 }
 
-#PopupAutoComplete > richlistbox > richlistitem > .two-line-wrapper > .labels-wrapper {
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .login-wrapper > .login-text {
   /* The text should flex while the icon should not */
   flex: 1;
   /* width/min-width are needed to get the text-overflow: ellipsis to work for the children */
   min-width: 0;
   width: 0;
 }
 
-#PopupAutoComplete > richlistbox > richlistitem > .two-line-wrapper > .labels-wrapper > .label-row {
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .login-wrapper > .login-text > .login-row {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
 }
 
-#PopupAutoComplete > richlistbox > richlistitem > .two-line-wrapper > .labels-wrapper > .line2-label {
+#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .login-wrapper > .login-text > .login-origin {
   padding-top: 2px !important;
   opacity: .6;
 }
 
-/* Login form autocompletion (with and without origin showing) and generated passwords */
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="generatedPassword"] > .two-line-wrapper > .ac-site-icon,
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .two-line-wrapper > .ac-site-icon,
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon {
-  display: initial;
-  list-style-image: url(chrome://browser/skin/login.svg);
-  -moz-context-properties: fill;
-  fill: GrayText;
-}
-
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="generatedPassword"][selected] > .two-line-wrapper > .ac-site-icon,
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"][selected] > .two-line-wrapper > .ac-site-icon,
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon[selected] {
-  fill: HighlightText;
-}
-
-/* Login form autocompletion with origin showing and generated passwords */
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="generatedPassword"],
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] {
-  padding: 4px;
-}
-
-
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] + richlistitem[originaltype="generatedPassword"],
-#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] + richlistitem[originaltype="generatedPassword"] {
-  /* Separator between logins and generated passwords */
-  border-top: 1px solid var(--panel-separator-color);
-}
-
 /* Insecure field warning */
 #PopupAutoComplete > richlistbox > richlistitem[originaltype="insecureWarning"] {
   background-color: var(--arrowpanel-dimmed);
   border-bottom: 1px solid var(--panel-separator-color);
   padding-bottom: 4px;
   padding-top: 4px;
 }
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4719,18 +4719,16 @@ pref("font.name-list.monospace.x-unicode
 // Login Manager prefs
 pref("signon.rememberSignons",              true);
 pref("signon.rememberSignons.visibilityToggle", true);
 pref("signon.autofillForms",                true);
 pref("signon.autofillForms.autocompleteOff", true);
 pref("signon.autofillForms.http",           false);
 pref("signon.autologin.proxy",              false);
 pref("signon.formlessCapture.enabled",      true);
-pref("signon.generation.available",         false);
-pref("signon.generation.enabled",           false);
 pref("signon.privateBrowsingCapture.enabled", false);
 pref("signon.storeWhenAutocompleteOff",     true);
 pref("signon.debug",                        false);
 pref("signon.recipes.path",                 "chrome://passwordmgr/content/recipes.json");
 pref("signon.schemeUpgrades",               false);
 // This temporarily prevents the master password to reprompt for autocomplete.
 pref("signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
 pref("signon.showAutoCompleteFooter", false);
--- a/toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
+++ b/toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
@@ -117,65 +117,49 @@ class LoginAutocompleteItem extends Auto
       return username;
     });
 
     XPCOMUtils.defineLazyGetter(this, "value", () => {
       return isPasswordField ? login.password : login.username;
     });
 
     XPCOMUtils.defineLazyGetter(this, "comment", () => {
-      try {
-        let uri = Services.io.newURI(login.hostname);
-        // Fallback to handle file: URIs
-        return uri.displayHostPort || login.hostname;
-      } catch (ex) {
-        // Fallback to origin below
-      }
-      return login.hostname;
+      return JSON.stringify({
+        loginOrigin: login.hostname,
+      });
     });
   }
 
   removeFromStorage() {
     if (this._messageManager) {
       let vanilla = LoginHelper.loginToVanillaObject(this._login);
       this._messageManager.sendAsyncMessage("PasswordManager:removeLogin",
                                             { login: vanilla });
     } else {
       Services.logins.removeLogin(this._login);
     }
   }
 }
 
-class GeneratedPasswordAutocompleteItem extends AutocompleteItem {
-  constructor(generatedPassword) {
-    super("generatedPassword");
-    this.comment = generatedPassword;
-    this.value = generatedPassword;
-
-    XPCOMUtils.defineLazyGetter(this, "label", () => {
-      return getLocalizedString("useGeneratedPassword");
-    });
-  }
-}
-
 class LoginsFooterAutocompleteItem extends AutocompleteItem {
   constructor(hostname) {
     super("loginsFooter");
-    this.comment = hostname;
 
     XPCOMUtils.defineLazyGetter(this, "label", () => {
-      return getLocalizedString("viewSavedLogins.label");
+      return JSON.stringify({
+        label: getLocalizedString("viewSavedLogins.label"),
+        hostname,
+      });
     });
   }
 }
 
 
 // nsIAutoCompleteResult implementation
 function LoginAutoCompleteResult(aSearchString, matchingLogins, {
-  generatedPassword,
   isSecure,
   messageManager,
   isPasswordField,
   hostname,
 }) {
   let hidingFooterOnPWFieldAutoOpened = false;
   function isFooterEnabled() {
     // We need to check LoginHelper.enabled here since the insecure warning should
@@ -186,18 +170,17 @@ function LoginAutoCompleteResult(aSearch
 
     // Don't show the footer on non-empty password fields as it's not providing
     // value and only adding noise since a password was already filled.
     if (isPasswordField && aSearchString) {
       log.debug("Hiding footer: non-empty password field");
       return false;
     }
 
-    if (!matchingLogins.length && !generatedPassword && isPasswordField
-        && formFillController.passwordPopupAutomaticallyOpened) {
+    if (!matchingLogins.length && isPasswordField && formFillController.passwordPopupAutomaticallyOpened) {
       hidingFooterOnPWFieldAutoOpened = true;
       log.debug("Hiding footer: no logins and the popup was opened upon focus of the pw. field");
       return false;
     }
 
     return true;
   }
 
@@ -219,19 +202,16 @@ function LoginAutoCompleteResult(aSearch
   for (let login of logins) {
     let item = new LoginAutocompleteItem(login, isPasswordField, dateAndTimeFormatter,
                                          duplicateUsernames, messageManager);
     this._rows.push(item);
   }
 
   // The footer comes last if it's enabled
   if (isFooterEnabled()) {
-    if (generatedPassword) {
-      this._rows.push(new GeneratedPasswordAutocompleteItem(generatedPassword));
-    }
     this._rows.push(new LoginsFooterAutocompleteItem(hostname));
   }
 
   // Determine the result code and default index.
   if (this.matchCount > 0) {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
     this.defaultIndex = 0;
   } else if (hidingFooterOnPWFieldAutoOpened) {
@@ -359,30 +339,25 @@ LoginAutoComplete.prototype = {
     //   able to affect the identity icon in the address bar by adding a password field.
     if (isSecure) {
       let form = LoginFormFactory.createFromField(aElement);
       isSecure = InsecurePasswordUtils.isFormSecure(form);
     }
     let isPasswordField = aElement.type == "password";
     let hostname = aElement.ownerDocument.documentURIObject.host;
 
-    let completeSearch = (autoCompleteLookupPromise, {
-      generatedPassword,
-      logins,
-      messageManager,
-    }) => {
+    let completeSearch = (autoCompleteLookupPromise, { logins, messageManager }) => {
       // If the search was canceled before we got our
       // results, don't bother reporting them.
       if (this._autoCompleteLookupPromise !== autoCompleteLookupPromise) {
         return;
       }
 
       this._autoCompleteLookupPromise = null;
       let results = new LoginAutoCompleteResult(aSearchString, logins, {
-        generatedPassword,
         messageManager,
         isSecure,
         isPasswordField,
         hostname,
       });
       aCallback.onSearchCompletion(results);
     };
 
@@ -414,17 +389,19 @@ LoginAutoComplete.prototype = {
       previousResult = {
         searchString: aPreviousResult.searchString,
         logins: aPreviousResult.wrappedJSObject.logins,
       };
     } else {
       previousResult = null;
     }
 
+    let rect = BrowserUtils.getElementBoundingScreenRect(aElement);
     let acLookupPromise = this._autoCompleteLookupPromise =
-      LoginManagerContent._autoCompleteSearchAsync(aSearchString, previousResult, aElement);
+      LoginManagerContent._autoCompleteSearchAsync(aSearchString, previousResult,
+                                                   aElement, rect);
     acLookupPromise.then(completeSearch.bind(this, acLookupPromise)).catch(log.error);
   },
 
   stopSearch() {
     this._autoCompleteLookupPromise = null;
   },
 };
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -23,18 +23,16 @@ const {XPCOMUtils} = ChromeUtils.import(
 
 /**
  * Contains functions shared by different Login Manager components.
  */
 var LoginHelper = {
   debug: null,
   enabled: null,
   formlessCaptureEnabled: null,
-  generationAvailable: null,
-  generationEnabled: null,
   insecureAutofill: null,
   managementURI: null,
   privateBrowsingCaptureEnabled: null,
   schemeUpgrades: null,
   showAutoCompleteFooter: null,
 
   init() {
     // Watch for pref changes to update cached pref values.
@@ -44,18 +42,16 @@ var LoginHelper = {
   },
 
   updateSignonPrefs() {
     this.autofillForms = Services.prefs.getBoolPref("signon.autofillForms");
     this.autofillAutocompleteOff = Services.prefs.getBoolPref("signon.autofillForms.autocompleteOff");
     this.debug = Services.prefs.getBoolPref("signon.debug");
     this.enabled = Services.prefs.getBoolPref("signon.rememberSignons");
     this.formlessCaptureEnabled = Services.prefs.getBoolPref("signon.formlessCapture.enabled");
-    this.generationAvailable = Services.prefs.getBoolPref("signon.generation.available");
-    this.generationEnabled = Services.prefs.getBoolPref("signon.generation.enabled");
     this.insecureAutofill = Services.prefs.getBoolPref("signon.autofillForms.http");
     this.managementURI = Services.prefs.getStringPref("signon.management.overrideURI", null);
     this.privateBrowsingCaptureEnabled =
       Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled");
     this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
     this.showAutoCompleteFooter = Services.prefs.getBoolPref("signon.showAutoCompleteFooter");
     this.storeWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
   },
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -288,21 +288,17 @@ var LoginManagerContent = {
         });
         break;
       }
 
       case "PasswordManager:loginsAutoCompleted": {
         let loginsFound = LoginHelper.vanillaObjectsToLogins(msg.data.logins);
         let messageManager = msg.target;
         let request = this._takeRequest(msg);
-        request.promise.resolve({
-          generatedPassword: msg.data.generatedPassword,
-          logins: loginsFound,
-          messageManager,
-        });
+        request.promise.resolve({ logins: loginsFound, messageManager });
         break;
       }
 
       case "FormAutoComplete:PopupOpened": {
         let {chromeEventHandler} = msg.target.docShell;
         chromeEventHandler.addEventListener("keydown", this._onKeyDown,
                                             true);
         break;
@@ -344,42 +340,39 @@ var LoginManagerContent = {
                         options };
 
     return this._sendRequest(messageManager, requestData,
                              "PasswordManager:findLogins",
                              messageData);
   },
 
   _autoCompleteSearchAsync(aSearchString, aPreviousResult,
-                           aElement) {
+                           aElement, aRect) {
     let doc = aElement.ownerDocument;
     let form = LoginFormFactory.createFromField(aElement);
     let win = doc.defaultView;
 
     let formOrigin = LoginHelper.getLoginOrigin(doc.documentURI);
     let actionOrigin = LoginHelper.getFormActionOrigin(form);
-    let autocompleteInfo = aElement.getAutocompleteInfo();
 
     let messageManager = win.docShell.messageManager;
 
     let previousResult = aPreviousResult ?
                            { searchString: aPreviousResult.searchString,
                              logins: LoginHelper.loginsToVanillaObjects(aPreviousResult.logins) } :
                            null;
 
     let requestData = {};
-    let messageData = {
-      autocompleteInfo,
-      browsingContextId: win.docShell.browsingContext.id,
-      formOrigin,
-      actionOrigin,
-      searchString: aSearchString,
-      previousResult,
-      isSecure: InsecurePasswordUtils.isFormSecure(form),
-      isPasswordField: aElement.type == "password",
+    let messageData = { formOrigin,
+                        actionOrigin,
+                        searchString: aSearchString,
+                        previousResult,
+                        rect: aRect,
+                        isSecure: InsecurePasswordUtils.isFormSecure(form),
+                        isPasswordField: aElement.type == "password",
     };
 
     if (LoginHelper.showAutoCompleteFooter) {
       messageManager.addMessageListener("FormAutoComplete:PopupOpened", this);
       messageManager.addMessageListener("FormAutoComplete:PopupClosed", this);
     }
 
     return this._sendRequest(messageManager, requestData,
--- a/toolkit/components/passwordmgr/LoginManagerParent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ -10,39 +10,28 @@ const {Services} = ChromeUtils.import("r
 XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
 
 ChromeUtils.defineModuleGetter(this, "AutoCompletePopup",
                                "resource://gre/modules/AutoCompletePopup.jsm");
 ChromeUtils.defineModuleGetter(this, "DeferredTask",
                                "resource://gre/modules/DeferredTask.jsm");
 ChromeUtils.defineModuleGetter(this, "LoginHelper",
                                "resource://gre/modules/LoginHelper.jsm");
-ChromeUtils.defineModuleGetter(this, "PasswordGenerator",
-                               "resource://gre/modules/PasswordGenerator.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
                                "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   let logger = LoginHelper.createLogger("LoginManagerParent");
   return logger.log.bind(logger);
 });
 
 var EXPORTED_SYMBOLS = [ "LoginManagerParent" ];
 
 var LoginManagerParent = {
   /**
-   * A map of a principal's origin (including suffixes) to a generated password string so that we
-   * can offer the same password later (e.g. in a confirmation field).
-   *
-   * We don't currently evict from this cache so entries should last until the end of the browser
-   * session. That may change later but for now a typical session would max out at a few entries.
-   */
-  _generatedPasswordsByPrincipalOrigin: new Map(),
-
-  /**
    * Reference to the default LoginRecipesParent (instead of the initialization promise) for
    * synchronous access. This is a temporary hack and new consumers should yield on
    * recipeParentPromise instead.
    *
    * @type LoginRecipesParent
    * @deprecated
    */
   _recipeManager: null,
@@ -250,26 +239,19 @@ var LoginManagerParent = {
     var jsLogins = LoginHelper.loginsToVanillaObjects(logins);
     target.sendAsyncMessage("PasswordManager:loginsFound", {
       requestId,
       logins: jsLogins,
       recipes,
     });
   },
 
-  doAutocompleteSearch({
-    autocompleteInfo,
-    browsingContextId,
-    formOrigin,
-    actionOrigin,
-    searchString,
-    previousResult,
-    requestId,
-    isSecure,
-    isPasswordField,
+  doAutocompleteSearch({ formOrigin, actionOrigin,
+                         searchString, previousResult,
+                         rect, requestId, isSecure, isPasswordField,
   }, target) {
     // Note: previousResult is a regular object, not an
     // nsIAutoCompleteResult.
 
     // Cancel if we unsuccessfully prompted for the master password too recently.
     if (!Services.logins.isLoggedIn) {
       let timeDiff = Date.now() - this._lastMPLoginCancelled;
       if (timeDiff < this._repromptTimeout) {
@@ -301,66 +283,32 @@ var LoginManagerParent = {
       logins = this._searchAndDedupeLogins(formOrigin, actionOrigin, {looseActionOriginMatch: true});
     }
 
     let matchingLogins = logins.filter(function(fullMatch) {
       let match = fullMatch.username;
 
       // Remove results that are too short, or have different prefix.
       // Also don't offer empty usernames as possible results except
-      // for on password fields.
+      // for password field.
       if (isPasswordField) {
         return true;
       }
       return match && match.toLowerCase().startsWith(searchStringLower);
     });
 
-    let generatedPassword = null;
-    if (isPasswordField && autocompleteInfo.fieldName == "new-password") {
-      generatedPassword = this.getGeneratedPassword(browsingContextId);
-    }
-
     // Convert the array of nsILoginInfo to vanilla JS objects since nsILoginInfo
     // doesn't support structured cloning.
     var jsLogins = LoginHelper.loginsToVanillaObjects(matchingLogins);
     target.messageManager.sendAsyncMessage("PasswordManager:loginsAutoCompleted", {
       requestId,
-      generatedPassword,
       logins: jsLogins,
     });
   },
 
-  /**
-   * Expose `BrowsingContext` so we can stub it in tests.
-   */
-  get _browsingContextGlobal() {
-    return BrowsingContext;
-  },
-
-  getGeneratedPassword(browsingContextId) {
-    if (!LoginHelper.enabled || !LoginHelper.generationAvailable || !LoginHelper.generationEnabled) {
-      return null;
-    }
-
-    let browsingContext = BrowsingContext.get(browsingContextId);
-    if (!browsingContext) {
-      return null;
-    }
-    let framePrincipalOrigin = browsingContext.currentWindowGlobal.documentPrincipal.origin;
-    // Use the same password if we already generated one for this origin so that it doesn't change
-    // with each search/keystroke and the user can easily re-enter a password in a confirmation field.
-    let generatedPW = this._generatedPasswordsByPrincipalOrigin.get(framePrincipalOrigin);
-    if (generatedPW) {
-      return generatedPW;
-    }
-    generatedPW = PasswordGenerator.generatePassword();
-    this._generatedPasswordsByPrincipalOrigin.set(framePrincipalOrigin, generatedPW);
-    return generatedPW;
-  },
-
   onFormSubmit({hostname, formSubmitURL, autoFilledLoginGuid,
                 usernameField, newPasswordField,
                 oldPasswordField, openerTopWindowID,
                 dismissedPrompt, target}) {
     function getPrompter() {
       var prompterSvc = Cc["@mozilla.org/login-manager/prompter;1"].
                         createInstance(Ci.nsILoginManagerPrompter);
       prompterSvc.init(target.ownerGlobal);
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -27,19 +27,16 @@ skip-if = toolkit == 'android' && !is_fe
 [test_autocomplete_highlight.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_highlight_non_login.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_https_upgrade.html]
 skip-if = toolkit == 'android' # autocomplete
-[test_autocomplete_new_password.html]
-scheme = https
-skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_password_open.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_sandboxed.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
 [test_autofill_autocomplete_types.html]
 scheme = https
@@ -109,16 +106,19 @@ scheme = https
 skip-if = os != 'mac' # Tests desktop prompts and bug 1333264
 support-files =
   chrome_timeout.js
   subtst_master_pass.html
 [test_maxlength.html]
 [test_munged_username.html]
 scheme = https
 skip-if = toolkit == 'android' # bug 1527403
+[test_autocomplete_new_password.html]
+scheme = https
+skip-if = toolkit == 'android' # autocomplete
 [test_one_doorhanger_per_un_pw.html]
 scheme = https
 skip-if = toolkit == 'android' # bug 1535505
 [test_onsubmit_value_change.html]
 [test_passwords_in_type_password.html]
 [test_prompt.html]
 skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_prompt_async.html]
--- a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
+++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
@@ -1,16 +1,14 @@
 /**
  * Helpers for password manager mochitest-plain tests.
  */
 
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 
-const GENERATED_PASSWORD_LENGTH = 15;
-const GENERATED_PASSWORD_REGEX = /^[a-km-np-zA-HJ-NP-Z2-9]{15}$/;
 // Copied from LoginTestUtils.masterPassword.masterPassword to use from the content process.
 const MASTER_PASSWORD = "omgsecret!";
 const TESTS_DIR = "/tests/toolkit/components/passwordmgr/test/";
 
 /**
  * Returns the element with the specified |name| attribute.
  */
 function $_(formNum, name) {
@@ -37,25 +35,26 @@ function $_(formNum, name) {
     return null;
   }
 
   return element;
 }
 
 /**
  * Check autocomplete popup results to ensure that expected
- * *labels* are being shown correctly as items in the popup.
+ * values are being shown correctly as items in the popup.
  */
 function checkAutoCompleteResults(actualValues, expectedValues, hostname, msg) {
   if (hostname !== null) {
     isnot(actualValues.length, 0, "There should be items in the autocomplete popup: " + JSON.stringify(actualValues));
 
     // Check the footer first.
     let footerResult = actualValues[actualValues.length - 1];
-    is(footerResult, "View Saved Logins", "the footer text is shown correctly");
+    ok(footerResult.includes("View Saved Logins"), "the footer text is shown correctly");
+    ok(footerResult.includes(hostname), "the footer has the correct hostname attribute");
   }
 
   if (hostname === null) {
     checkArrayValues(actualValues, expectedValues, msg);
     return;
   }
 
   if (actualValues.length == 1) {
@@ -64,27 +63,16 @@ function checkAutoCompleteResults(actual
     return;
   }
 
   // Check the rest of the autocomplete item values.
   checkArrayValues(actualValues.slice(0, -1), expectedValues, msg);
 }
 
 /**
- * Check for expected username/password in form.
- * @see `checkForm` below for a similar function.
- */
-function checkLoginForm(usernameField, expectedUsername, passwordField, expectedPassword) {
-  let formID = usernameField.parentNode.id;
-  is(usernameField.value, expectedUsername, "Checking " + formID + " username is: " + expectedUsername);
-  is(passwordField.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword);
-}
-
-
-/**
  * Check a form for expected values. If an argument is null, a field's
  * expected value will be the default value.
  *
  * <form id="form#">
  * checkForm(#, "foo");
  */
 function checkForm(formNum, val1, val2, val3) {
   var e, form = document.getElementById("form" + formNum);
@@ -217,25 +205,24 @@ function isLoggedIn() {
 function logoutMasterPassword() {
   runInParent(function parent_logoutMasterPassword() {
     var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
     sdr.logoutAndTeardown();
   });
 }
 
 /**
- * Resolves when a specified number of forms have been processed for (potential) filling.
+ * Resolves when a specified number of forms have been processed.
  */
 function promiseFormsProcessed(expectedCount = 1) {
   var processedCount = 0;
   return new Promise((resolve, reject) => {
     function onProcessedForm(subject, topic, data) {
       processedCount++;
       if (processedCount == expectedCount) {
-        info(`${processedCount} form(s) processed`);
         SpecialPowers.removeObserver(onProcessedForm, "passwordmgr-processed-form");
         resolve(SpecialPowers.Cu.waiveXrays(subject), data);
       }
     }
     SpecialPowers.addObserver(onProcessedForm, "passwordmgr-processed-form");
   });
 }
 
@@ -404,8 +391,14 @@ this.LoginManager = new Proxy({}, {
         args: cloneableArgs,
         loginInfoIndices,
         methodName: prop,
       })[0][0];
     };
   },
 });
 
+// Check for expected username/password in form.
+function checkLoginForm(usernameField, expectedUsername, passwordField, expectedPassword) {
+  let formID = usernameField.parentNode.id;
+  is(usernameField.value, expectedUsername, "Checking " + formID + " username is: " + expectedUsername);
+  is(passwordField.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword);
+}
--- a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_new_password.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_new_password.html
@@ -1,18 +1,18 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
-  <title>Test autofill and autocomplete on autocomplete=new-password fields</title>
+  <title>Test autofill with autocomplete=new-password fields</title>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <script src="/tests/SimpleTest/EventUtils.js"></script>
-  <script src="pwmgr_common.js"></script>
-  <script src="../../../satchel/test/satchel_common.js"></script>
-  <link rel="stylesheet" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="pwmgr_common.js"></script>
+  <script type="text/javascript" src="../../../satchel/test/satchel_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Login Manager test: autofill with autocomplete=new-password fields
 
 <script>
 let chromeScript = runInParent(function initLogins() {
   const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
@@ -33,168 +33,74 @@ let readyPromise = registerRunTests();
 
   <!-- form1 is the reference, sanity-check -->
   <form id="form1" action="https://autofill" onsubmit="return false;">
     <input type="text" name="uname">
     <input type="password" name="p">
     <button type="submit">Submit</button>
   </form>
 
-  <!-- form2 uses a new-password type=password field -->
+  <!-- form2 uses the new-password field -->
   <form id="form2" action="https://autofill" onsubmit="return false;">
     <input type="text" name="uname">
-    <input type="password" name="pword" autocomplete="new-password">
+    <input type="password" autocomplete="new-password">
     <button type="submit">Submit</button>
   </form>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 const {ContentTaskUtils} =
   SpecialPowers.Cu.import("resource://testing-common/ContentTaskUtils.jsm", {});
 
+async function getAutocompleteResult(input, expectedValues) {
+  input.focus();
+
+  const shownPromise = promiseACShown();
+  synthesizeKey("KEY_ArrowDown");
+  await shownPromise;
+  synthesizeKey("KEY_ArrowDown");
+  await synthesizeKey("KEY_Enter");
+
+  let didAutocomplete;
+  try {
+    await ContentTaskUtils.waitForCondition(() => {
+      for (let [selector, expectedValue] of Object.entries(expectedValues)) {
+        if (document.querySelector(selector).value !== expectedValue) {
+          return false;
+        }
+      }
+      return true;
+    });
+    didAutocomplete = true;
+  } catch (ex) {
+    info("waitForCondition exception: " + ex.message);
+    didAutocomplete = false;
+  }
+  return didAutocomplete;
+}
+
 add_task(async function setup() {
   ok(readyPromise, "check promise is available");
   await readyPromise;
 });
 
-add_task(async function test_autofillAutocompleteUsername_noGeneration() {
+add_task(async function test_autofillAutocompleteNewPassword() {
   // reference form was filled as expected?
   checkForm(1, "user1", "pass1");
 
   // 2nd form should not be filled
   checkForm(2, "", "");
 
-  $_(2, "uname").focus();
-  const shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
-  let results = await shownPromise;
-  let expectedACLabels = ["user1"];
-  checkAutoCompleteResults(results, expectedACLabels, "example.com", "Check all rows are correct");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-  await promiseFormsProcessed();
-  checkForm(2, "user1", "pass1");
-
-  document.getElementById("form2").reset();
-});
-
-add_task(async function test_autofillAutocompletePassword_noGeneration() {
-  // 2nd form should not be filled
-  checkForm(2, "", "");
-
-  let pword = $_(2, "pword");
-  pword.focus();
-  const shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
-  let results = await shownPromise;
-  let expectedACLabels = ["user1"];
-  checkAutoCompleteResults(results, expectedACLabels, "example.com", "Check all rows are correct");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-  // Can't use promiseFormsProcessed() when autocomplete fills the field directly.
-  await SimpleTest.promiseWaitForCondition(() => pword.value == "pass1", "Check pw filled");
-  checkForm(2, "", "pass1");
+  let form = document.getElementById("form2");
+  let userInput = form.querySelector("[name='uname']");
 
-  // No autocomplete results should appear for non-empty pw fields.
-  synthesizeKey("KEY_ArrowDown");
-  await promiseNoUnexpectedPopupShown();
-
-  document.getElementById("form2").reset();
-});
-
-// All tests below this are with generation prefs enabled.
-
-add_task(async function test_autofillAutocompleteUsername_noGeneration() {
-  await SpecialPowers.pushPrefEnv({"set": [
-    ["signon.generation.available", true],
-    ["signon.generation.enabled", true],
-    ["signon.showAutoCompleteOrigins", true],
-  ]});
-
-  // 2nd form should not be filled
-  checkForm(2, "", "");
-
-  $_(2, "uname").focus();
-  const shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
-  let results = await shownPromise;
-  // No generation option on username fields.
-  let expectedACLabels = ["user1"];
-  checkAutoCompleteResults(results, expectedACLabels, "example.com", "Check all rows are correct");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-  await promiseFormsProcessed();
-  checkForm(2, "user1", "pass1");
-
-  document.getElementById("form2").reset();
+  const didAutocomplete = await getAutocompleteResult(userInput, {
+    "#form2 [name='uname']": "user1",
+    "#form2 [type='password']": "pass1",
+  });
+  ok(didAutocomplete, "Autocomplete of user and password fields should happen");
 });
 
-add_task(async function test_autofillAutocompletePassword_withGeneration() {
-  // 2nd form should not be filled
-  checkForm(2, "", "");
-
-  let pword = $_(2, "pword");
-  pword.focus();
-  let shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
-  let results = await shownPromise;
-  let expectedACLabels = [
-    "user1",
-    "Use Generated Password",
-  ];
-  checkAutoCompleteResults(results, expectedACLabels, "example.com", "Check all rows are correct");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-  // Can't use promiseFormsProcessed() when autocomplete fills the field directly.
-  await SimpleTest.promiseWaitForCondition(() => pword.value == "pass1", "Check pw filled");
-  checkForm(2, "", "pass1");
-
-  // No autocomplete results should appear for non-empty pw fields.
-  synthesizeKey("KEY_ArrowDown");
-  await promiseNoUnexpectedPopupShown();
-
-  while (pword.value) {
-    synthesizeKey("KEY_Backspace");
-  }
-
-  info("This time select the generated password");
-  shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
-  results = await shownPromise;
-  expectedACLabels = [
-    "user1",
-    "Use Generated Password",
-  ];
-  checkAutoCompleteResults(results, expectedACLabels, "example.com", "Check all rows are correct");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-  await SimpleTest.promiseWaitForCondition(() => !!pword.value, "Check generated pw filled");
-  let generatedPW = pword.value;
-  is(generatedPW.length, GENERATED_PASSWORD_LENGTH, "Check generated password length");
-  ok(generatedPW.match(GENERATED_PASSWORD_REGEX), "Check generated password format");
-
-  while (pword.value) {
-    synthesizeKey("KEY_Backspace");
-  }
-
-  shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
-  results = await shownPromise;
-  expectedACLabels = [
-    "user1",
-    "Use Generated Password",
-  ];
-  checkAutoCompleteResults(results, expectedACLabels, "example.com", "Check all rows are correct");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-  await SimpleTest.promiseWaitForCondition(() => !!pword.value, "Check generated pw filled");
-  // Same generated password should be used.
-  checkForm(2, "", generatedPW);
-
-  document.getElementById("form2").reset();
-});
 </script>
 </pre>
 </body>
 </html>
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_doAutocompleteSearch.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Test LoginManagerParent.doAutocompleteSearch()
- */
-
-"use strict";
-
-const {sinon} = ChromeUtils.import("resource://testing-common/Sinon.jsm");
-const {LoginManagerParent: LMP} = ChromeUtils.import("resource://gre/modules/LoginManagerParent.jsm");
-
-add_task(async function test_doAutocompleteSearch_generated_noLogins() {
-  Services.prefs.setBoolPref("signon.generation.available", true); // TODO: test both with false
-  Services.prefs.setBoolPref("signon.generation.enabled", true);
-
-  ok(LMP.doAutocompleteSearch, "doAutocompleteSearch exists");
-
-  // Default to the happy path
-  let arg1 = {
-    autocompleteInfo: {
-      section: "",
-      addressType: "",
-      contactType: "",
-      fieldName: "new-password",
-      canAutomaticallyPersist: false,
-    },
-    browsingContextId: 123,
-    formOrigin: "https://example.com",
-    actionOrigin: "https://mozilla.org",
-    searchString: "",
-    previousResult: null,
-    requestId: "foo",
-    isSecure: true,
-    isPasswordField: true,
-  };
-
-  let sendMessageStub = sinon.stub();
-  let fakeBrowser = {
-    messageManager: {
-      sendAsyncMessage: sendMessageStub,
-    },
-  };
-
-  sinon.stub(LMP._browsingContextGlobal, "get").withArgs(123).callsFake(() => {
-    return {
-      currentWindowGlobal: {
-        documentPrincipal: Services.scriptSecurityManager.createCodebasePrincipalFromOrigin("https://www.example.com^userContextId=1"),
-      },
-    };
-  });
-
-  LMP.doAutocompleteSearch(arg1, fakeBrowser);
-  ok(sendMessageStub.calledOnce, "sendAsyncMessage was called");
-  let msg1 = sendMessageStub.firstCall.args[1];
-  equal(msg1.requestId, arg1.requestId, "requestId matches");
-  equal(msg1.logins.length, 0, "no logins");
-  ok(msg1.generatedPassword, "has a generated password");
-  equal(msg1.generatedPassword.length, 15, "generated password length");
-  sendMessageStub.resetHistory();
-
-  info("repeat the search and ensure the same password was used");
-  LMP.doAutocompleteSearch(arg1, fakeBrowser);
-  ok(sendMessageStub.calledOnce, "sendAsyncMessage was called");
-  let msg2 = sendMessageStub.firstCall.args[1];
-  equal(msg2.requestId, arg1.requestId, "requestId matches");
-  equal(msg2.logins.length, 0, "no logins");
-  equal(msg2.generatedPassword, msg1.generatedPassword, "same generated password");
-  sendMessageStub.resetHistory();
-
-  info("Check cases where a password shouldn't be generated");
-
-  LMP.doAutocompleteSearch({...arg1, ...{isPasswordField: false}}, fakeBrowser);
-  ok(sendMessageStub.calledOnce, "sendAsyncMessage was called");
-  let msg = sendMessageStub.firstCall.args[1];
-  equal(msg.requestId, arg1.requestId, "requestId matches");
-  equal(msg.generatedPassword, null, "no generated password when not a pw. field");
-  sendMessageStub.resetHistory();
-
-  let arg1_2 = {...arg1};
-  arg1_2.autocompleteInfo.fieldName = "";
-  LMP.doAutocompleteSearch(arg1_2, fakeBrowser);
-  ok(sendMessageStub.calledOnce, "sendAsyncMessage was called");
-  msg = sendMessageStub.firstCall.args[1];
-  equal(msg.requestId, arg1.requestId, "requestId matches");
-  equal(msg.generatedPassword, null, "no generated password when not autocomplete=new-password");
-  sendMessageStub.resetHistory();
-
-  LMP.doAutocompleteSearch({...arg1, ...{browsingContextId: 999}}, fakeBrowser);
-  ok(sendMessageStub.calledOnce, "sendAsyncMessage was called");
-  msg = sendMessageStub.firstCall.args[1];
-  equal(msg.requestId, arg1.requestId, "requestId matches");
-  equal(msg.generatedPassword, null, "no generated password with a missing browsingContextId");
-  sendMessageStub.resetHistory();
-});
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_getGeneratedPassword.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Test LoginManagerParent.getGeneratedPassword()
- */
-
-"use strict";
-
-const {sinon} = ChromeUtils.import("resource://testing-common/Sinon.jsm");
-const {LoginManagerParent: LMP} = ChromeUtils.import("resource://gre/modules/LoginManagerParent.jsm");
-
-add_task(async function test_getGeneratedPassword() {
-  // Force the feature to be enabled.
-  Services.prefs.setBoolPref("signon.generation.available", true);
-  Services.prefs.setBoolPref("signon.generation.enabled", true);
-
-  ok(LMP.getGeneratedPassword, "LMP.getGeneratedPassword exists");
-  equal(LMP._generatedPasswordsByPrincipalOrigin.size, 0, "Empty cache to start");
-
-  equal(LMP.getGeneratedPassword(99), null, "Null with no BrowsingContext");
-
-  ok(LMP._browsingContextGlobal, "Check _browsingContextGlobal exists");
-  ok(!LMP._browsingContextGlobal.get(99), "BrowsingContext 99 shouldn't exist yet");
-  info("Stubbing BrowsingContext.get(99)");
-  sinon.stub(LMP._browsingContextGlobal, "get").withArgs(99).callsFake(() => {
-    return {
-      currentWindowGlobal: {
-        documentPrincipal: Services.scriptSecurityManager.createCodebasePrincipalFromOrigin("https://www.example.com^userContextId=6"),
-      },
-    };
-  });
-  ok(LMP._browsingContextGlobal.get(99), "Checking BrowsingContext.get(99) stub");
-
-  let password1 = LMP.getGeneratedPassword(99);
-  notEqual(password1, null, "Check password was returned");
-  equal(password1.length, 15, "Check password length");
-  equal(LMP._generatedPasswordsByPrincipalOrigin.size, 1, "1 added to cache");
-  equal(LMP._generatedPasswordsByPrincipalOrigin.get("https://www.example.com^userContextId=6"),
-        password1, "Cache key and value");
-  let password2 = LMP.getGeneratedPassword(99);
-  equal(password1, password2, "Same password should be returned for the same origin");
-
-  info("Changing the documentPrincipal to simulate a navigation in the frame");
-  LMP._browsingContextGlobal.get.restore();
-  sinon.stub(LMP._browsingContextGlobal, "get").withArgs(99).callsFake(() => {
-    return {
-      currentWindowGlobal: {
-        documentPrincipal: Services.scriptSecurityManager.createCodebasePrincipalFromOrigin("https://www.mozilla.org^userContextId=2"),
-      },
-    };
-  });
-  let password3 = LMP.getGeneratedPassword(99);
-  notEqual(password2, password3, "Different password for a different origin for the same BC");
-  equal(password3.length, 15, "Check password3 length");
-
-  info("Now checks cases where null should be returned");
-
-  Services.prefs.setBoolPref("signon.rememberSignons", false);
-  equal(LMP.getGeneratedPassword(99), null, "Prevented when pwmgr disabled");
-  Services.prefs.setBoolPref("signon.rememberSignons", true);
-
-  Services.prefs.setBoolPref("signon.generation.available", false);
-  equal(LMP.getGeneratedPassword(99), null, "Prevented when unavailable");
-  Services.prefs.setBoolPref("signon.generation.available", true);
-
-  Services.prefs.setBoolPref("signon.generation.enabled", false);
-  equal(LMP.getGeneratedPassword(99), null, "Prevented when disabled");
-  Services.prefs.setBoolPref("signon.generation.enabled", true);
-
-  equal(LMP.getGeneratedPassword(123), null, "Prevented when browsingContext is missing");
-});
--- a/toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
+++ b/toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
@@ -1,13 +1,14 @@
 const {LoginAutoCompleteResult} = ChromeUtils.import("resource://gre/modules/LoginAutoCompleteResult.jsm");
 var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
                                          Ci.nsILoginInfo, "init");
 
 const PREF_INSECURE_FIELD_WARNING_ENABLED = "security.insecure_field_warning.contextual.enabled";
+const PREF_INSECURE_AUTOFILLFORMS_ENABLED = "signon.autofillForms.http";
 
 let matchingLogins = [];
 matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                     "", "emptypass1", "uname", "pword"));
 
 matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                     "tempuser1", "temppass1", "uname", "pword"));
 
@@ -24,738 +25,457 @@ let meta = matchingLogins[0].QueryInterf
 let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
                                                             { dateStyle: "medium" });
 let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
 const LABEL_NO_USERNAME = "No username (" + time + ")";
 
 let expectedResults = [
   {
     insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: true,
     isSecure: true,
     isPasswordField: false,
     matchingLogins,
     items: [{
       value: "",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "tempuser1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzuser4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
     insecureFieldWarningEnabled: true,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: [],
-    items: [{
-      value: "",
-      label: "This connection is not secure. Logins entered here could be compromised. Learn More",
-      style: "insecureWarning",
-      comment: "",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: true,
     isSecure: false,
     isPasswordField: false,
     matchingLogins,
     items: [{
       value: "",
       label: "This connection is not secure. Logins entered here could be compromised. Learn More",
       style: "insecureWarning",
-      comment: "",
     }, {
       value: "",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "tempuser1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzuser4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
     insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: true,
     isSecure: true,
     isPasswordField: true,
     matchingLogins,
     items: [{
       value: "emptypass1",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "temppass1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzpass4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
     insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: true,
     isSecure: false,
     isPasswordField: true,
     matchingLogins,
     items: [{
       value: "",
       label: "This connection is not secure. Logins entered here could be compromised. Learn More",
       style: "insecureWarning",
-      comment: "",
     }, {
       value: "emptypass1",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "temppass1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzpass4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    isSecure: true,
-    isPasswordField: false,
-    matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
     insecureFieldWarningEnabled: false,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    isSecure: false,
-    isPasswordField: true,
-    matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: true,
     isSecure: true,
     isPasswordField: false,
     matchingLogins,
     items: [{
       value: "",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "tempuser1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzuser4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: true,
+    insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: true,
     isSecure: false,
     isPasswordField: false,
     matchingLogins,
     items: [{
       value: "",
-      label: "This connection is not secure. Logins entered here could be compromised. Learn More",
-      style: "insecureWarning",
-      comment: "",
-    }, {
-      value: "",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "tempuser1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzuser4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: true,
+    insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: true,
     isSecure: true,
     isPasswordField: true,
     matchingLogins,
     items: [{
       value: "emptypass1",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "temppass1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzpass4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: true,
+    insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: true,
     isSecure: false,
     isPasswordField: true,
     matchingLogins,
     items: [{
-      value: "",
-      label: "This connection is not secure. Logins entered here could be compromised. Learn More",
-      style: "insecureWarning",
-      comment: "",
-    }, {
       value: "emptypass1",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "temppass1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzpass4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: false,
+    insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: false,
     isSecure: true,
     isPasswordField: false,
     matchingLogins,
     items: [{
       value: "",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "tempuser1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzuser4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: false,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: [],
-    items: [{
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: [],
-    searchString: "foo",
-    items: [{
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: false,
+    insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: false,
     isSecure: false,
     isPasswordField: false,
     matchingLogins,
     items: [{
       value: "",
+      label: "This connection is not secure. Logins entered here could be compromised. Learn More",
+      style: "insecureWarning",
+    }, {
+      value: "",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "tempuser1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testuser3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzuser4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: false,
+    insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: false,
     isSecure: true,
     isPasswordField: true,
     matchingLogins,
     items: [{
       value: "emptypass1",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "temppass1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
+    }, {
+      value: "testpass3",
+      label: "testuser3",
+      style: "loginWithOrigin",
+    }, {
+      value: "zzzpass4",
+      label: "zzzuser4",
+      style: "loginWithOrigin",
+    }],
+  },
+  {
+    insecureFieldWarningEnabled: true,
+    insecureAutoFillFormsEnabled: false,
+    isSecure: false,
+    isPasswordField: true,
+    matchingLogins,
+    items: [{
+      value: "",
+      label: "This connection is not secure. Logins entered here could be compromised. Learn More",
+      style: "insecureWarning",
+    }, {
+      value: "emptypass1",
+      label: LABEL_NO_USERNAME,
+      style: "loginWithOrigin",
+    }, {
+      value: "temppass1",
+      label: "tempuser1",
+      style: "loginWithOrigin",
+    }, {
+      value: "testpass2",
+      label: "testuser2",
+      style: "loginWithOrigin",
     }, {
       value: "testpass3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzpass4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
     insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: false,
+    isSecure: true,
+    isPasswordField: false,
+    matchingLogins,
+    items: [{
+      value: "",
+      label: LABEL_NO_USERNAME,
+      style: "loginWithOrigin",
+    }, {
+      value: "tempuser1",
+      label: "tempuser1",
+      style: "loginWithOrigin",
+    }, {
+      value: "testuser2",
+      label: "testuser2",
+      style: "loginWithOrigin",
+    }, {
+      value: "testuser3",
+      label: "testuser3",
+      style: "loginWithOrigin",
+    }, {
+      value: "zzzuser4",
+      label: "zzzuser4",
+      style: "loginWithOrigin",
+    }],
+  },
+  {
+    insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: false,
     isSecure: false,
+    isPasswordField: false,
+    matchingLogins,
+    items: [],
+  },
+  {
+    insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: false,
+    isSecure: true,
     isPasswordField: true,
     matchingLogins,
     items: [{
       value: "emptypass1",
       label: LABEL_NO_USERNAME,
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "temppass1",
       label: "tempuser1",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass2",
       label: "testuser2",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "testpass3",
       label: "testuser3",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
     }, {
       value: "zzzpass4",
       label: "zzzuser4",
       style: "loginWithOrigin",
-      comment: "mochi.test:8888",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: [],
-    items: [{
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
     }],
   },
   {
-    insecureFieldWarningEnabled: true,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: [],
-    searchString: "foo",
-    items: [],
-  },
-  {
-    generatedPassword: "9ljgfd4shyktb45",
-    insecureFieldWarningEnabled: true,
-    isSecure: true,
+    insecureFieldWarningEnabled: false,
+    insecureAutoFillFormsEnabled: false,
+    isSecure: false,
     isPasswordField: true,
-    matchingLogins: [],
-    items: [{
-      value: "9ljgfd4shyktb45",
-      label: "Use Generated Password",
-      style: "generatedPassword",
-      comment: "9ljgfd4shyktb45",
-    }, {
-      value: "",
-      label: "View Saved Logins",
-      style: "loginsFooter",
-      comment: "mochi.test",
-    }],
-  },
-  {
-    generatedPassword: "9ljgfd4shyktb45",
-    insecureFieldWarningEnabled: true,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: [],
-    searchString: "9ljgfd4shyktb45",
+    matchingLogins,
     items: [],
   },
 ];
 
 add_task(async function test_all_patterns() {
   LoginHelper.createLogger("LoginAutoCompleteResult");
-  Services.prefs.setBoolPref("signon.showAutoCompleteFooter", true);
   Services.prefs.setBoolPref("signon.showAutoCompleteOrigins", true);
 
   expectedResults.forEach(pattern => {
-    info(JSON.stringify(pattern, null, 2));
     Services.prefs.setBoolPref(PREF_INSECURE_FIELD_WARNING_ENABLED,
                                pattern.insecureFieldWarningEnabled);
-    let actual = new LoginAutoCompleteResult(pattern.searchString || "", pattern.matchingLogins, {
-      hostname: "mochi.test",
-      generatedPassword: pattern.generatedPassword,
+    Services.prefs.setBoolPref(PREF_INSECURE_AUTOFILLFORMS_ENABLED,
+                               pattern.insecureAutoFillFormsEnabled);
+    let actual = new LoginAutoCompleteResult("", pattern.matchingLogins, {
       isSecure: pattern.isSecure,
       isPasswordField: pattern.isPasswordField,
     });
-    equal(actual.matchCount, pattern.items.length, "Check matching row count");
     pattern.items.forEach((item, index) => {
-      equal(actual.getValueAt(index), item.value, `Value ${index}`);
-      equal(actual.getLabelAt(index), item.label, `Label ${index}`);
-      equal(actual.getStyleAt(index), item.style, `Style ${index}`);
-      equal(actual.getCommentAt(index), item.comment, `Comment ${index}`);
+      equal(actual.getValueAt(index), item.value);
+      equal(actual.getLabelAt(index), item.label);
+      equal(actual.getStyleAt(index), item.style);
     });
 
     if (pattern.items.length != 0) {
       Assert.throws(() => actual.getValueAt(pattern.items.length),
                     /Index out of range\./);
 
       Assert.throws(() => actual.getLabelAt(pattern.items.length),
                     /Index out of range\./);
--- a/toolkit/components/passwordmgr/test/unit/xpcshell.ini
+++ b/toolkit/components/passwordmgr/test/unit/xpcshell.ini
@@ -22,18 +22,16 @@ run-if = buildapp == "browser"
 [test_doLoginsMatch.js]
 [test_getFormFields.js]
 [test_getPasswordFields.js]
 [test_getPasswordOrigin.js]
 [test_getUserNameAndPasswordFields.js]
 [test_isOriginMatching.js]
 [test_isUsernameFieldType.js]
 [test_legacy_empty_formSubmitURL.js]
-[test_LoginManagerParent_doAutocompleteSearch.js]
-[test_LoginManagerParent_getGeneratedPassword.js]
 [test_legacy_validation.js]
 [test_login_autocomplete_result.js]
 skip-if = os == "android"
 [test_logins_change.js]
 [test_logins_decrypt_failure.js]
 skip-if = os == "android" # Bug 1171687: Needs fixing on Android
 [test_logins_metainfo.js]
 [test_logins_search.js]
--- a/toolkit/content/widgets/autocomplete-popup.js
+++ b/toolkit/content/widgets/autocomplete-popup.js
@@ -372,17 +372,16 @@ MozElements.MozAutocompleteRichlistboxPo
 
         // The styles on the list which have different <content> structure and overrided
         // _adjustAcItem() are unreusable.
         const UNREUSEABLE_STYLES = [
           "autofill-profile",
           "autofill-footer",
           "autofill-clear-button",
           "autofill-insecureWarning",
-          "generatedPassword",
           "insecureWarning",
           "loginsFooter",
           "loginWithOrigin",
         ];
         // Reuse the item when its style is exactly equal to the previous style or
         // neither of their style are in the UNREUSEABLE_STYLES.
         reusable = originalType === style ||
           !(UNREUSEABLE_STYLES.includes(style) || UNREUSEABLE_STYLES.includes(originalType));
@@ -405,19 +404,18 @@ MozElements.MozAutocompleteRichlistboxPo
             options = { is: "autocomplete-creditcard-insecure-field" };
             break;
           case "insecureWarning":
             options = { is: "autocomplete-richlistitem-insecure-warning" };
             break;
           case "loginsFooter":
             options = { is: "autocomplete-richlistitem-logins-footer" };
             break;
-          case "generatedPassword":
           case "loginWithOrigin":
-            options = { is: "autocomplete-two-line-richlistitem" };
+            options = { is: "autocomplete-richlistitem-login-with-origin" };
             break;
           default:
             options = { is: "autocomplete-richlistitem" };
         }
         item = document.createXULElement("richlistitem", options);
         item.className = "autocomplete-richlistitem";
       }
 
--- a/toolkit/content/widgets/autocomplete-richlistitem.js
+++ b/toolkit/content/widgets/autocomplete-richlistitem.js
@@ -983,71 +983,83 @@ class MozAutocompleteRichlistitemLoginsF
   constructor() {
     super();
 
     function handleEvent(event) {
       if (event.button != 0) {
         return;
       }
 
-      // ac-label gets populated from getCommentAt despite the attribute name.
-      // The "comment" is used to populate additional visible text.
-      let formHostname = this.getAttribute("ac-label");
       LoginHelper.openPasswordManager(this.ownerGlobal, {
-        filterString: formHostname,
+        filterString: this._data.hostname,
         entryPoint: "autocomplete",
       });
     }
 
     this.addEventListener("click", handleEvent);
   }
+
+  get _data() {
+    return JSON.parse(this.getAttribute("ac-value"));
+  }
+
+  _adjustAcItem() {
+    this._titleText.textContent = this._data.label;
+  }
 }
 
-class MozAutocompleteTwoLineRichlistitem extends MozElements.MozRichlistitem {
+class MozAutocompleteRichlistitemLoginWithOrigin extends MozElements.MozRichlistitem {
   connectedCallback() {
     if (this.delayConnectedCallback()) {
       return;
     }
 
     this.textContent = "";
     this.appendChild(MozXULElement.parseXULToFragment(this._markup));
     this.initializeAttributeInheritance();
     this._adjustAcItem();
   }
 
 
   static get inheritedAttributes() {
     return {
-      // getLabelAt:
-      ".line1-label": "text=ac-value",
-      // getCommentAt:
-      ".line2-label": "text=ac-label",
+      ".login-username": "text=ac-value",
     };
   }
 
   get _markup() {
     return `
       <div xmlns="http://www.w3.org/1999/xhtml"
            xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-           class="two-line-wrapper">
+           class="login-wrapper">
         <xul:image class="ac-site-icon"></xul:image>
-        <div class="labels-wrapper">
-          <div class="label-row line1-label"></div>
-          <div class="label-row line2-label"></div>
+        <div class="login-text">
+          <div class="login-row login-username"></div>
+          <div class="login-row login-origin"></div>
         </div>
       </div>
     `;
   }
 
   _adjustAcItem() {
     let outerBoxRect = this.parentNode.getBoundingClientRect();
 
     // Make item fit in popup as XUL box could not constrain
     // item's width
     this.firstElementChild.style.width = outerBoxRect.width + "px";
+
+    let data = JSON.parse(this.getAttribute("ac-label"));
+    let originElement = this.querySelector(".login-origin");
+    try {
+      let uri = Services.io.newURI(data.loginOrigin);
+      // Fallback to handle file: URIs
+      originElement.textContent = uri.displayHostPort || data.loginOrigin;
+    } catch (ex) {
+      originElement.textContent = data.loginOrigin;
+    }
   }
 
   _onOverflow() {}
 
   _onUnderflow() {}
 
   handleOverUnderflow() {}
 }
@@ -1059,12 +1071,12 @@ customElements.define("autocomplete-rich
 customElements.define("autocomplete-richlistitem-insecure-warning", MozAutocompleteRichlistitemInsecureWarning, {
   extends: "richlistitem",
 });
 
 customElements.define("autocomplete-richlistitem-logins-footer", MozAutocompleteRichlistitemLoginsFooter, {
   extends: "richlistitem",
 });
 
-customElements.define("autocomplete-two-line-richlistitem", MozAutocompleteTwoLineRichlistitem, {
+customElements.define("autocomplete-richlistitem-login-with-origin", MozAutocompleteRichlistitemLoginWithOrigin, {
   extends: "richlistitem",
 });
 }
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -1010,17 +1010,16 @@
 
               // The styles on the list which have different <content> structure and overrided
               // _adjustAcItem() are unreusable.
               const UNREUSEABLE_STYLES = [
                 "autofill-profile",
                 "autofill-footer",
                 "autofill-clear-button",
                 "autofill-insecureWarning",
-                "generatedPassword",
                 "insecureWarning",
                 "loginsFooter",
                 "loginWithOrigin",
               ];
               // Reuse the item when its style is exactly equal to the previous style or
               // neither of their style are in the UNREUSEABLE_STYLES.
               reusable = originalType === style ||
                 !(UNREUSEABLE_STYLES.includes(style) || UNREUSEABLE_STYLES.includes(originalType));
@@ -1043,19 +1042,18 @@
                   options = { is: "autocomplete-creditcard-insecure-field" };
                   break;
                 case "insecureWarning":
                   options = { is: "autocomplete-richlistitem-insecure-warning" };
                   break;
                 case "loginsFooter":
                   options = { is: "autocomplete-richlistitem-logins-footer" };
                   break;
-                case "generatedPassword":
                 case "loginWithOrigin":
-                  options = { is: "autocomplete-two-line-richlistitem" };
+                  options = { is: "autocomplete-richlistitem-login-with-origin" };
                   break;
                 default:
                   options = { is: "autocomplete-richlistitem" };
               }
               item = document.createXULElement("richlistitem", options);
               item.className = "autocomplete-richlistitem";
             }
 
--- a/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties
+++ b/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties
@@ -40,28 +40,23 @@ passwordChangeTitle = Confirm Password C
 # LOCALIZATION NOTE (updatePasswordMsg):
 # String is the username for the login.
 updatePasswordMsg = Would you like to update the saved password for “%S”?
 updatePasswordMsgNoUser = Would you like to update the saved password?
 userSelectText2 = Select which login to update:
 removeLoginPrompt=Are you sure you wish to remove this login?
 removeLoginTitle=Remove login
 loginsDescriptionAll2=Logins for the following sites are stored on your computer
-
-# LOCALIZATION NOTE (useGeneratedPassword):
-# Shown in the autocomplete popup to allow filling a generated password into a password field.
-useGeneratedPassword=Use Generated Password
 # LOCALIZATION NOTE (loginHostAge):
 # This is used to show the context menu login items with their age.
 # 1st string is the username for the login, 2nd is the login's age.
 loginHostAge=%1$S (%2$S)
 # LOCALIZATION NOTE (noUsername):
 # String is used on the context menu when a login doesn't have a username.
 noUsername=No username
-
 duplicateLoginTitle=Login already exists
 duplicateLogin=A duplicate login already exists.
 
 # LOCALIZATION NOTE (insecureFieldWarningDescription2, insecureFieldWarningDescription3):
 # %1$S will contain insecureFieldWarningLearnMore and look like a link to indicate that clicking will open a tab with support information.
 insecureFieldWarningDescription2 = This connection is not secure. Logins entered here could be compromised. %1$S
 insecureFieldWarningDescription3 = Logins entered here could be compromised. %1$S
 insecureFieldWarningLearnMore = Learn More