Bug 1577005 - [1.6] Add autofill commit support. r=MattN
authorEugen Sawin <esawin@me73.com>
Fri, 15 Nov 2019 15:48:39 +0000
changeset 502189 741f4a9a2f642a96907b6a56a9dfc2936f7dea75
parent 502188 31a1b40b20084e96947cf3b660a5b5ef9c5612d0
child 502190 56bf24c7a31a61e9c339661963d0d7c8eab098bc
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1577005
milestone72.0a1
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
Bug 1577005 - [1.6] Add autofill commit support. r=MattN Differential Revision: https://phabricator.services.mozilla.com/D51185
mobile/android/chrome/geckoview/GeckoViewAutofillChild.js
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
mobile/android/modules/geckoview/GeckoViewAutofill.jsm
toolkit/components/passwordmgr/LoginManagerChild.jsm
--- a/mobile/android/chrome/geckoview/GeckoViewAutofillChild.js
+++ b/mobile/android/chrome/geckoview/GeckoViewAutofillChild.js
@@ -15,16 +15,25 @@ XPCOMUtils.defineLazyModuleGetters(this,
   FormLikeFactory: "resource://gre/modules/FormLikeFactory.jsm",
   GeckoViewAutofill: "resource://gre/modules/GeckoViewAutofill.jsm",
 });
 
 class GeckoViewAutofillChild extends GeckoViewChildModule {
   onInit() {
     debug`onInit`;
 
+    // Listen to Gecko's autofill commit events.
+    content.windowRoot.addEventListener(
+      "PasswordManager:onFormSubmit",
+      aEvent => {
+        const formLike = aEvent.detail.form;
+        this._autofill.commitAutofill(formLike);
+      }
+    );
+
     const options = {
       mozSystemGroup: true,
       capture: false,
     };
 
     addEventListener("DOMFormHasPassword", this, options);
     addEventListener("DOMInputPasswordAdded", this, options);
     addEventListener("pagehide", this, options);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java
@@ -965,21 +965,24 @@ public class Autofill {
                             final GeckoBundle message,
                             final EventCallback callback) {
                         if ("GeckoView:AddAutofill".equals(event)) {
                             addNode(message, callback);
                         } else if ("GeckoView:ClearAutofill".equals(event)) {
                             clear();
                         } else if ("GeckoView:OnAutofillFocus".equals(event)) {
                             onFocusChanged(message);
+                        } else if ("GeckoView:CommitAutofill".equals(event)) {
+                            commit(message);
                         }
                     }
                 },
                 "GeckoView:AddAutofill",
                 "GeckoView:ClearAutofill",
+                "GeckoView:CommitAutofill",
                 "GeckoView:OnAutofillFocus",
                 null);
 
             mAutofillSession = new Session(geckoSession);
         }
 
         /**
          * Perform auto-fill using the specified values.
@@ -1074,16 +1077,32 @@ public class Autofill {
                 final @AutofillNotify int notification, final Node node) {
             if (mDelegate == null) {
                 return;
             }
 
             mDelegate.onAutofill(mGeckoSession, notification, node);
         }
 
+        /* package */ void commit(@Nullable final GeckoBundle message) {
+            if (getAutofillSession().isEmpty()) {
+                return;
+            }
+
+            final int id = message.getInt("id");
+
+            if (DEBUG) {
+                Log.d(LOGTAG, "commit(" + id + ")");
+            }
+
+            maybeDispatch(
+                    Notify.SESSION_COMMITTED,
+                    getAutofillSession().getNode(id));
+        }
+
         /* package */ void clear() {
             if (getAutofillSession().isEmpty()) {
                 return;
             }
 
             if (DEBUG) {
                 Log.d(LOGTAG, "clear()");
             }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -30,16 +30,18 @@ exclude: true
   and [`BasicSelectionActionDelegate.onShowActionRequest`][72.7]
   ([bug 1581161]({{bugzilla}}1581161))
 - Added text selection action methods to [`SelectionActionDelegate.Selection`][72.8]
   ([bug 1581161]({{bugzilla}}1581161))
 - Added [`BasicSelectionActionDelegate.getSelection`][72.9]
   ([bug 1581161]({{bugzilla}}1581161))
 - Changed [`BasicSelectionActionDelegate.clearSelection`][72.10] to public.
   ([bug 1581161]({{bugzilla}}1581161))
+- Added `Autofill` commit support.
+  ([bug 1577005]({{bugzilla}1577005}))
 
 [72.1]: {{javadoc_uri}}/GeckoSession.NavigationDelegate.LoadRequest#hasUserGesture-
 [72.2]: {{javadoc_uri}}/Autofill.html
 [72.3]: {{javadoc_uri}}/WebResponse.html#body
 [72.4]: {{javadoc_uri}}/WebResponse.html#setReadTimeoutMillis-long-
 [72.5]: {{javadoc_uri}}/WebResponse.html#DEFAULT_READ_TIMEOUT_MS
 [72.6]: {{javadoc_uri}}/GeckoSession.SelectionActionDelegate.html#onShowActionRequest-org.mozilla.geckoview.GeckoSession-org.mozilla.geckoview.GeckoSession.SelectionActionDelegate.Selection-
 [72.7]: {{javadoc_uri}}/BasicSelectionActionDelegate.html#onShowActionRequest-org.mozilla.geckoview.GeckoSession-org.mozilla.geckoview.GeckoSession.SelectionActionDelegate.Selection-
--- a/mobile/android/modules/geckoview/GeckoViewAutofill.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewAutofill.jsm
@@ -226,16 +226,31 @@ class GeckoViewAutofill {
 
     const info =
       aTarget && this._autoFillInfos && this._autoFillInfos.get(aTarget);
     if (!aTarget || info) {
       this._eventDispatcher.dispatch("GeckoView:OnAutofillFocus", info);
     }
   }
 
+  commitAutofill(aFormLike) {
+    if (!aFormLike) {
+      throw new Error("null-form on autofill commit");
+    }
+    debug`Committing auto-fill for ${aFormLike.rootElement.tagName}`;
+
+    const info =
+      this._autoFillInfos && this._autoFillInfos.get(aFormLike.rootElement);
+
+    if (info) {
+      debug`Committing info ${info}`;
+      this._eventDispatcher.dispatch("GeckoView:CommitAutofill", info);
+    }
+  }
+
   /**
    * Clear all tracked auto-fill forms and notify Java.
    */
   clearElements() {
     debug`Clearing auto-fill`;
 
     this._autoFillTasks = undefined;
     this._autoFillInfos = undefined;
--- a/toolkit/components/passwordmgr/LoginManagerChild.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerChild.jsm
@@ -1538,25 +1538,32 @@ this.LoginManagerChild = class LoginMana
         "(form submission ignored -- already submitted with the same username and password)"
       );
       return;
     }
 
     let autoFilledLogin = this.stateForDocument(doc).fillsByRootElement.get(
       form.rootElement
     );
-    this.sendAsyncMessage("PasswordManager:onFormSubmit", {
+
+    let detail = {
       origin,
       formActionOrigin,
       autoFilledLoginGuid: autoFilledLogin && autoFilledLogin.guid,
       usernameField: mockUsername,
       newPasswordField: mockPassword,
       oldPasswordField: mockOldPassword,
       dismissedPrompt,
-    });
+    };
+
+    this.sendAsyncMessage("PasswordManager:onFormSubmit", detail);
+
+    detail.form = form;
+    const evt = new CustomEvent("PasswordManager:onFormSubmit", { detail });
+    win.windowRoot.dispatchEvent(evt);
   }
 
   _maybeStopTreatingAsGeneratedPasswordField(event) {
     let passwordField = event.target;
     let { value } = passwordField;
 
     // If the field is now empty or the inserted text replaced the whole value
     // then stop treating it as a generated password field.