scripts: build-chromium: Support native android autofill

Change-Id: I32a9fda1e0eac8e8d4c6d89a38aa13d6d918aa21
diff --git a/build-chromium/patches/0093-Add-missing-null-check-for-password-manager-autofill.patch b/build-chromium/patches/0093-Add-missing-null-check-for-password-manager-autofill.patch
new file mode 100644
index 0000000..8da6a87
--- /dev/null
+++ b/build-chromium/patches/0093-Add-missing-null-check-for-password-manager-autofill.patch
@@ -0,0 +1,24 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Mon, 20 Feb 2023 07:06:53 +0000
+Subject: [PATCH] Add missing null check for password manager autofill
+
+---
+ .../autofill/content/renderer/password_autofill_agent.cc      | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
+index 94d20221b0059..52b7c28a2a925 100644
+--- a/components/autofill/content/renderer/password_autofill_agent.cc
++++ b/components/autofill/content/renderer/password_autofill_agent.cc
+@@ -838,7 +838,9 @@ void PasswordAutofillAgent::UpdateStateForTextChange(
+ 
+ void PasswordAutofillAgent::TrackAutofilledElement(
+     const blink::WebFormControlElement& element) {
+-  autofill_agent_->TrackAutofilledElement(element);
++  if (autofill_agent_) {
++    autofill_agent_->TrackAutofilledElement(element);
++  }
+ }
+ 
+ void PasswordAutofillAgent::FillPasswordSuggestion(
diff --git a/build-chromium/patches/0094-Drop-workaround-with-android-autofill-in-compatibili.patch b/build-chromium/patches/0094-Drop-workaround-with-android-autofill-in-compatibili.patch
new file mode 100644
index 0000000..11affc3
--- /dev/null
+++ b/build-chromium/patches/0094-Drop-workaround-with-android-autofill-in-compatibili.patch
@@ -0,0 +1,25 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Fri, 24 Feb 2023 10:20:37 +0100
+Subject: [PATCH] Drop workaround with android autofill in compatibility mode
+
+This causes the autofill popup to show when url is tapped. Drop in favor
+of native android autofill support compatibility with other autofill
+implementations.
+---
+ .../java/src/org/chromium/chrome/browser/omnibox/UrlBar.java    | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
+index 7078b97461529..21742470dc9d9 100644
+--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
++++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
+@@ -392,7 +392,7 @@ public abstract class UrlBar extends AutocompleteEditText {
+             // the domain changes. We restore this behavior by mimicking the relevant part of
+             // TextView.notifyListeningManagersAfterTextChanged().
+             // https://cs.android.com/android/platform/superproject/+/5d123b67756dffcfdebdb936ab2de2b29c799321:frameworks/base/core/java/android/widget/TextView.java;l=10618;drc=master;bpv=0
+-            ApiHelperForO.notifyValueChangedForAutofill(this);
++            // ApiHelperForO.notifyValueChangedForAutofill(this);
+         }
+ 
+         limitDisplayableLength();
diff --git a/build-chromium/patches/0095-Enable-android-autofill-on-http-authentication-dialo.patch b/build-chromium/patches/0095-Enable-android-autofill-on-http-authentication-dialo.patch
new file mode 100644
index 0000000..10c543c
--- /dev/null
+++ b/build-chromium/patches/0095-Enable-android-autofill-on-http-authentication-dialo.patch
@@ -0,0 +1,22 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Mon, 20 Feb 2023 07:10:30 +0000
+Subject: [PATCH] Enable android autofill on http authentication dialog
+
+---
+ .../chromium/chrome/browser/login/ChromeHttpAuthHandler.java    | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/chrome/android/java/src/org/chromium/chrome/browser/login/ChromeHttpAuthHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/login/ChromeHttpAuthHandler.java
+index 3b87576c9ed6b..a97f7cff21c49 100644
+--- a/chrome/android/java/src/org/chromium/chrome/browser/login/ChromeHttpAuthHandler.java
++++ b/chrome/android/java/src/org/chromium/chrome/browser/login/ChromeHttpAuthHandler.java
+@@ -102,7 +102,7 @@ public class ChromeHttpAuthHandler extends EmptyTabObserver implements LoginProm
+         mTab.addObserver(this);
+         String messageBody = ChromeHttpAuthHandlerJni.get().getMessageBody(
+                 mNativeChromeHttpAuthHandler, ChromeHttpAuthHandler.this);
+-        mLoginPrompt = new LoginPrompt(activity, messageBody, null, this);
++        mLoginPrompt = new LoginPrompt(activity, messageBody, tab.getOriginalUrl(), this);
+         // In case the autofill data arrives before the prompt is created.
+         if (mAutofillUsername != null && mAutofillPassword != null) {
+             mLoginPrompt.onAutofillDataAvailable(mAutofillUsername, mAutofillPassword);
diff --git a/build-chromium/patches/0096-Support-both-password-manager-and-android-autofill-f.patch b/build-chromium/patches/0096-Support-both-password-manager-and-android-autofill-f.patch
new file mode 100644
index 0000000..1609207
--- /dev/null
+++ b/build-chromium/patches/0096-Support-both-password-manager-and-android-autofill-f.patch
@@ -0,0 +1,70 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Mon, 20 Feb 2023 07:06:53 +0000
+Subject: [PATCH] Support both password manager and android autofill
+ functionality
+
+---
+ .../autofill/content/renderer/autofill_agent.cc     |  1 -
+ .../content/renderer/password_autofill_agent.cc     | 11 -----------
+ .../core/browser/browser_autofill_manager.cc        | 13 +++++++++++++
+ 3 files changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
+index 193cdecccd425..2654381cae623 100644
+--- a/components/autofill/content/renderer/autofill_agent.cc
++++ b/components/autofill/content/renderer/autofill_agent.cc
+@@ -537,7 +537,6 @@ void AutofillAgent::OnTextFieldDidChange(const WebInputElement& element) {
+   if (password_autofill_agent_->TextDidChangeInTextField(element)) {
+     is_popup_possibly_visible_ = true;
+     last_queried_element_ = element;
+-    return;
+   }
+ 
+   ShowSuggestions(element,
+diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
+index 52b7c28a2a925..b039f5ee6441a 100644
+--- a/components/autofill/content/renderer/password_autofill_agent.cc
++++ b/components/autofill/content/renderer/password_autofill_agent.cc
+@@ -1155,17 +1155,6 @@ bool PasswordAutofillAgent::ShowSuggestions(const WebInputElement& element,
+   if (element.Value().length() > kMaximumTextSizeForAutocomplete)
+     return false;
+ 
+-#if BUILDFLAG(IS_ANDROID)
+-  // Don't call ShowSuggestionPopup if a keyboard replacing surface is currently
+-  // showing. Since a keyboard replacing surface in spirit is very similar to a
+-  // suggestion pop-up, return true so that the AutofillAgent does not try to
+-  // show other autofill suggestions instead.
+-  if (keyboard_replacing_surface_state_ ==
+-      KeyboardReplacingSurfaceState::kIsShowing) {
+-    return true;
+-  }
+-#endif
+-
+   if (!HasDocumentWithValidFrame(element))
+     return false;
+ 
+diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
+index a1bc6da4223f5..48d1c3133df48 100644
+--- a/components/autofill/core/browser/browser_autofill_manager.cc
++++ b/components/autofill/core/browser/browser_autofill_manager.cc
+@@ -1155,6 +1155,19 @@ void BrowserAutofillManager::OnAskForValuesToFillImpl(
+   if (base::FeatureList::IsEnabled(features::kAutofillDisableFilling)) {
+     return;
+   }
++ 
++  if (AutofillField* _autofill_field = GetAutofillField(form, field)) {
++    switch (_autofill_field->Type().group()) {
++      // Do not override password manager prompt on these fields
++      case FieldTypeGroup::kNoGroup:
++      case FieldTypeGroup::kPasswordField:
++      case FieldTypeGroup::kUsernameField:
++      case FieldTypeGroup::kEmail:
++        return;
++      default:
++        break;
++    }
++  }
+ 
+   SetDataList(field.datalist_values, field.datalist_labels);
+   external_delegate_->OnQuery(form, field, transformed_box);
diff --git a/build-chromium/patches/0097-Support-for-both-browser-and-android-autofill-functi.patch b/build-chromium/patches/0097-Support-for-both-browser-and-android-autofill-functi.patch
new file mode 100644
index 0000000..2ea0d6f
--- /dev/null
+++ b/build-chromium/patches/0097-Support-for-both-browser-and-android-autofill-functi.patch
@@ -0,0 +1,269 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Tue, 21 Feb 2023 01:48:15 +0000
+Subject: [PATCH] Support for both browser and android autofill functionality
+
+---
+ .../browser/android_autofill_manager.cc       | 15 ++++++
+ .../browser/android_autofill_manager.h        | 15 ++++++
+ .../browser/content_autofill_driver.cc        | 52 +++++++++++++++++++
+ .../content/browser/content_autofill_driver.h |  8 +++
+ .../autofill/core/browser/autofill_driver.h   |  6 +++
+ 5 files changed, 96 insertions(+)
+
+diff --git a/components/android_autofill/browser/android_autofill_manager.cc b/components/android_autofill/browser/android_autofill_manager.cc
+index ed7f0f073b734..df84f20ca4ffa 100644
+--- a/components/android_autofill/browser/android_autofill_manager.cc
++++ b/components/android_autofill/browser/android_autofill_manager.cc
+@@ -14,6 +14,7 @@
+ #include "components/android_autofill/browser/autofill_provider.h"
+ #include "components/android_autofill/browser/form_event_logger_weblayer_android.h"
+ #include "components/autofill/content/browser/content_autofill_driver.h"
++#include "components/autofill/core/browser/browser_autofill_manager.h"
+ #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
+ #include "content/public/browser/render_frame_host.h"
+ #include "content/public/browser/web_contents.h"
+@@ -32,6 +33,20 @@ void AndroidDriverInitHook(AutofillClient* client,
+   driver->GetAutofillAgent()->SetQueryPasswordSuggestion(true);
+ }
+ 
++void AndroidAndBrowserDriverInitHook(
++    AutofillClient* client,
++    const std::string& app_locale,
++    ContentAutofillDriver* driver) {
++  driver->set_autofill_manager(std::make_unique<BrowserAutofillManager>(
++      driver, client, app_locale));
++  driver->set_secondary_autofill_manager(base::WrapUnique(
++      new AndroidAutofillManager(driver, client)));
++  driver->GetAutofillAgent()->SetUserGestureRequired(false);
++  driver->GetAutofillAgent()->SetSecureContextRequired(true);
++  driver->GetAutofillAgent()->SetFocusRequiresScroll(false);
++  driver->GetAutofillAgent()->SetQueryPasswordSuggestion(true);
++}
++
+ AndroidAutofillManager::AndroidAutofillManager(AutofillDriver* driver,
+                                                AutofillClient* client)
+     : AutofillManager(driver, client) {
+diff --git a/components/android_autofill/browser/android_autofill_manager.h b/components/android_autofill/browser/android_autofill_manager.h
+index 3fd9a9c2cd46e..e610c101c52e0 100644
+--- a/components/android_autofill/browser/android_autofill_manager.h
++++ b/components/android_autofill/browser/android_autofill_manager.h
+@@ -21,6 +21,16 @@ class AutofillProvider;
+ class ContentAutofillDriver;
+ class FormEventLoggerWeblayerAndroid;
+ 
++// Creates an AndroidAutofillManager and attaches it to the `driver`.
++//
++// This hook is to be passed to CreateForWebContentsAndDelegate().
++// It is the glue between ContentAutofillDriver[Factory] and
++// AndroidAutofillManager, BrowserAutofillManager.
++void AndroidAndBrowserDriverInitHook(
++    AutofillClient* client,
++    const std::string& app_locale,
++    ContentAutofillDriver* driver);
++
+ // Creates an AndroidAutofillManager and attaches it to the `driver`.
+ //
+ // This hook is to be passed to CreateForWebContentsAndDelegate().
+@@ -96,6 +106,11 @@ class AndroidAutofillManager : public AutofillManager,
+                          const url::Origin& triggered_origin);
+ 
+  protected:
++  friend void AndroidAndBrowserDriverInitHook(
++      AutofillClient* client,
++      const std::string& app_locale,
++      ContentAutofillDriver* driver);
++
+   friend void AndroidDriverInitHook(AutofillClient* client,
+                                     ContentAutofillDriver* driver);
+ 
+diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
+index 83625554d4fd7..b66f3f3cb1f7f 100644
+--- a/components/autofill/content/browser/content_autofill_driver.cc
++++ b/components/autofill/content/browser/content_autofill_driver.cc
+@@ -145,6 +145,18 @@ AutofillManager& ContentAutofillDriver::GetAutofillManager() {
+   return *autofill_manager_;
+ }
+ 
++AutofillManager& ContentAutofillDriver::GetSecondaryAutofillManager() {
++  return *secondary_autofill_manager_;
++}
++
++bool ContentAutofillDriver::HasSecondaryAutofillManager() {
++  if (secondary_autofill_manager_) {
++    return true;
++  }
++
++  return false;
++}
++
+ absl::optional<LocalFrameToken> ContentAutofillDriver::Resolve(
+     FrameToken query) {
+   if (absl::holds_alternative<LocalFrameToken>(query)) {
+@@ -412,6 +424,10 @@ void ContentAutofillDriver::FormsSeen(
+                         const std::vector<FormGlobalId>& removed_forms) {
+                        target->GetAutofillManager().OnFormsSeen(
+                            WithNewVersion(updated_forms), removed_forms);
++                       if (target->HasSecondaryAutofillManager()) {
++                         target->GetSecondaryAutofillManager().OnFormsSeen(
++                             WithNewVersion(updated_forms), removed_forms);
++                       }
+                      });
+ }
+ 
+@@ -439,6 +455,10 @@ void ContentAutofillDriver::FormSubmitted(
+         }
+         target->GetAutofillManager().OnFormSubmitted(
+             WithNewVersion(form), known_success, submission_source);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnFormSubmitted(
++              WithNewVersion(form), known_success, submission_source);
++        }
+       });
+ }
+ 
+@@ -460,6 +480,10 @@ void ContentAutofillDriver::TextFieldDidChange(const FormData& raw_form,
+          base::TimeTicks timestamp) {
+         target->GetAutofillManager().OnTextFieldDidChange(
+             WithNewVersion(form), field, bounding_box, timestamp);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnTextFieldDidChange(
++            WithNewVersion(form), field, bounding_box, timestamp);
++        }
+       });
+ }
+ 
+@@ -479,6 +503,10 @@ void ContentAutofillDriver::TextFieldDidScroll(const FormData& raw_form,
+          const FormFieldData& field, const gfx::RectF& bounding_box) {
+         target->GetAutofillManager().OnTextFieldDidScroll(WithNewVersion(form),
+                                                           field, bounding_box);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnTextFieldDidScroll(WithNewVersion(form),
++                                                            field, bounding_box);
++        }
+       });
+ }
+ 
+@@ -499,6 +527,10 @@ void ContentAutofillDriver::SelectControlDidChange(
+          const FormFieldData& field, const gfx::RectF& bounding_box) {
+         target->GetAutofillManager().OnSelectControlDidChange(
+             WithNewVersion(form), field, bounding_box);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnSelectControlDidChange(
++            WithNewVersion(form), field, bounding_box);
++        }
+       });
+ }
+ 
+@@ -521,6 +553,10 @@ void ContentAutofillDriver::AskForValuesToFill(
+          AutofillSuggestionTriggerSource trigger_source) {
+         target->GetAutofillManager().OnAskForValuesToFill(
+             WithNewVersion(form), field, bounding_box, trigger_source);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnAskForValuesToFill(
++            WithNewVersion(form), field, bounding_box, trigger_source);
++        }
+       });
+ }
+ 
+@@ -532,6 +568,9 @@ void ContentAutofillDriver::HidePopup() {
+     DCHECK(!target->IsPrerendering())
+         << "We should never affect UI while prerendering";
+     target->GetAutofillManager().OnHidePopup();
++    if (target->HasSecondaryAutofillManager()) {
++      target->GetSecondaryAutofillManager().OnHidePopup();
++    }
+   });
+ }
+ 
+@@ -543,6 +582,9 @@ void ContentAutofillDriver::FocusNoLongerOnForm(bool had_interacted_form) {
+       this, had_interacted_form,
+       [](autofill::AutofillDriver* target, bool had_interacted_form) {
+         target->GetAutofillManager().OnFocusNoLongerOnForm(had_interacted_form);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnFocusNoLongerOnForm(had_interacted_form);
++        }
+       });
+ }
+ 
+@@ -565,6 +607,9 @@ void ContentAutofillDriver::FocusOnFormField(const FormData& raw_form,
+       },
+       [](autofill::AutofillDriver* target) {
+         target->GetAutofillManager().OnFocusNoLongerOnForm(true);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnFocusNoLongerOnForm(true);
++        }
+       });
+ }
+ 
+@@ -579,6 +624,10 @@ void ContentAutofillDriver::DidFillAutofillFormData(const FormData& raw_form,
+          base::TimeTicks timestamp) {
+         target->GetAutofillManager().OnDidFillAutofillFormData(
+             WithNewVersion(form), timestamp);
++        if (target->HasSecondaryAutofillManager()) {
++          target->GetSecondaryAutofillManager().OnDidFillAutofillFormData(
++            WithNewVersion(form), timestamp);
++        }
+       });
+ }
+ 
+@@ -643,6 +692,9 @@ void ContentAutofillDriver::Reset() {
+   owner_->router().UnregisterDriver(this,
+                                     /*driver_is_dying=*/false);
+   autofill_manager_->Reset();
++  if (secondary_autofill_manager_) {
++    secondary_autofill_manager_->Reset();
++  }
+ }
+ 
+ const mojo::AssociatedRemote<mojom::AutofillAgent>&
+diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h
+index 39c13f8e77500..ac7d4dba61a09 100644
+--- a/components/autofill/content/browser/content_autofill_driver.h
++++ b/components/autofill/content/browser/content_autofill_driver.h
+@@ -131,6 +131,10 @@ class ContentAutofillDriver : public AutofillDriver,
+     autofill_manager_ = std::move(autofill_manager);
+   }
+ 
++  void set_secondary_autofill_manager(std::unique_ptr<AutofillManager> secondary_autofill_manager) {
++    secondary_autofill_manager_ = std::move(secondary_autofill_manager);
++  }
++
+   content::RenderFrameHost* render_frame_host() { return &*render_frame_host_; }
+   const content::RenderFrameHost* render_frame_host() const {
+     return &*render_frame_host_;
+@@ -159,6 +163,8 @@ class ContentAutofillDriver : public AutofillDriver,
+   absl::optional<LocalFrameToken> Resolve(FrameToken query) override;
+   ContentAutofillDriver* GetParent() override;
+   AutofillManager& GetAutofillManager() override;
++  AutofillManager& GetSecondaryAutofillManager() override;
++  bool HasSecondaryAutofillManager() override;
+   bool IsInActiveFrame() const override;
+   bool IsInAnyMainFrame() const override;
+   bool IsPrerendering() const override;
+@@ -319,6 +325,8 @@ class ContentAutofillDriver : public AutofillDriver,
+ 
+   std::unique_ptr<AutofillManager> autofill_manager_ = nullptr;
+ 
++  std::unique_ptr<AutofillManager> secondary_autofill_manager_ = nullptr;
++
+   mojo::AssociatedReceiver<mojom::AutofillDriver> receiver_{this};
+ 
+   mojo::AssociatedRemote<mojom::AutofillAgent> autofill_agent_;
+diff --git a/components/autofill/core/browser/autofill_driver.h b/components/autofill/core/browser/autofill_driver.h
+index 9426b8cd4106f..d80e4a55b022a 100644
+--- a/components/autofill/core/browser/autofill_driver.h
++++ b/components/autofill/core/browser/autofill_driver.h
+@@ -69,6 +69,12 @@ class AutofillDriver {
+   // Returns the AutofillManager owned by the AutofillDriver.
+   virtual AutofillManager& GetAutofillManager() = 0;
+ 
++  // Returns the secondary AutofillManager owned by the AutofillDriver.
++  virtual AutofillManager& GetSecondaryAutofillManager() = 0;
++
++  // Returns if there is a secondary AutofillManager owned by the AutofillDriver.
++  virtual bool HasSecondaryAutofillManager() = 0;
++
+   // Returns whether the AutofillDriver instance is associated with an active
+   // frame in the MPArch sense.
+   virtual bool IsInActiveFrame() const = 0;
diff --git a/build-chromium/patches/0098-Support-native-Android-autofill-at-browser.patch b/build-chromium/patches/0098-Support-native-Android-autofill-at-browser.patch
new file mode 100644
index 0000000..614fbb0
--- /dev/null
+++ b/build-chromium/patches/0098-Support-native-Android-autofill-at-browser.patch
@@ -0,0 +1,379 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Mon, 20 Feb 2023 07:10:55 +0000
+Subject: [PATCH] Support native Android autofill at browser
+
+This enables support for Android Autofil on tabs showing fillable
+entries, reusing the codebase used for webview's android autofill
+support.
+---
+ android_webview/browser/aw_autofill_client.cc |  4 ++
+ chrome/android/BUILD.gn                       |  1 +
+ .../chromium/chrome/browser/tab/TabImpl.java  | 45 +++++++++++++++++
+ .../browser/tab/TabViewAndroidDelegate.java   | 13 +++++
+ chrome/browser/BUILD.gn                       |  7 +++
+ .../ui/autofill/chrome_autofill_client.cc     | 14 +++++-
+ .../embedder_support/view/ContentView.java    | 48 +++++++++++++++++++
+ .../chromium/ui/base/ViewAndroidDelegate.java |  8 ++++
+ 8 files changed, 139 insertions(+), 1 deletion(-)
+
+diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc
+index 449fe65d0bdda..6f0cf1553b07e 100644
+--- a/android_webview/browser/aw_autofill_client.cc
++++ b/android_webview/browser/aw_autofill_client.cc
+@@ -86,6 +86,7 @@ AwAutofillClient::GetURLLoaderFactory() {
+ }
+ 
+ autofill::AutofillDownloadManager* AwAutofillClient::GetDownloadManager() {
++#if defined(USE_BROWSER_AUTOFILL_ONLY)
+   if (autofill::AutofillProvider::is_download_manager_disabled_for_testing()) {
+     return nullptr;
+   }
+@@ -95,6 +96,9 @@ autofill::AutofillDownloadManager* AwAutofillClient::GetDownloadManager() {
+         this, GetChannel(), GetLogManager());
+   }
+   return download_manager_.get();
++#else
++  return nullptr;
++#endif // defined(USE_BROWSER_AUTOFILL_ONLY)
+ }
+ 
+ autofill::PersonalDataManager* AwAutofillClient::GetPersonalDataManager() {
+diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
+index 8728878809d86..e6b1e938d9a5a 100644
+--- a/chrome/android/BUILD.gn
++++ b/chrome/android/BUILD.gn
+@@ -453,6 +453,7 @@ if (current_toolchain == default_toolchain) {
+       "//chrome/browser/xsurface:java",
+       "//chrome/browser/xsurface_provider:dependency_provider_impl_java",
+       "//chrome/browser/xsurface_provider:java",
++      "//components/android_autofill/browser:java",
+       "//components/autofill/android:autofill_java",
+       "//components/background_task_scheduler:background_task_scheduler_java",
+       "//components/background_task_scheduler:background_task_scheduler_task_ids_java",
+diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+index d9f1d1008e623..18f23b198448e 100644
+--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
++++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+@@ -10,10 +10,14 @@ import android.annotation.SuppressLint;
+ import android.app.Activity;
+ import android.content.Context;
+ import android.graphics.Rect;
++import android.os.Build;
+ import android.text.TextUtils;
++import android.util.SparseArray;
+ import android.view.View;
+ import android.view.View.OnAttachStateChangeListener;
++import android.view.ViewStructure;
+ import android.view.accessibility.AccessibilityEvent;
++import android.view.autofill.AutofillValue;
+ 
+ import androidx.annotation.NonNull;
+ import androidx.annotation.Nullable;
+@@ -52,6 +56,8 @@ import org.chromium.chrome.browser.tab.TabUtils.LoadIfNeededCaller;
+ import org.chromium.chrome.browser.tab.TabUtils.UseDesktopUserAgentCaller;
+ import org.chromium.chrome.browser.ui.native_page.FrozenNativePage;
+ import org.chromium.chrome.browser.ui.native_page.NativePage;
++import org.chromium.components.autofill.AutofillProvider;
++import org.chromium.components.autofill.AutofillSelectionMenuItemProvider;
+ import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
+ import org.chromium.components.embedder_support.util.UrlConstants;
+ import org.chromium.components.embedder_support.view.ContentView;
+@@ -65,9 +71,11 @@ import org.chromium.content_public.browser.ChildProcessImportance;
+ import org.chromium.content_public.browser.ContentFeatureList;
+ import org.chromium.content_public.browser.ContentFeatureMap;
+ import org.chromium.content_public.browser.LoadUrlParams;
++import org.chromium.content_public.browser.SelectionPopupController;
+ import org.chromium.content_public.browser.WebContents;
+ import org.chromium.content_public.browser.WebContentsAccessibility;
+ import org.chromium.content_public.browser.navigation_controller.UserAgentOverrideOption;
++import org.chromium.ui.base.EventOffsetHandler;
+ import org.chromium.ui.base.PageTransition;
+ import org.chromium.ui.base.ViewAndroidDelegate;
+ import org.chromium.ui.base.WindowAndroid;
+@@ -209,6 +217,7 @@ public class TabImpl implements Tab {
+     private int mParentId = INVALID_TAB_ID;
+     private int mRootId;
+     private @TabUserAgent int mUserAgent = TabUserAgent.DEFAULT;
++    AutofillProvider mAutofillProvider;
+     /**
+      * Navigation state of the WebContents as returned by nativeGetContentsStateAsByteBuffer(),
+      * stored to be inflated on demand using unfreezeContents(). If this is not null, there is no
+@@ -271,12 +280,18 @@ public class TabImpl implements Tab {
+             public void onViewAttachedToWindow(View view) {
+                 mIsViewAttachedToWindow = true;
+                 updateInteractableState();
++                if (mAutofillProvider != null) {
++                    mAutofillProvider.onContainerViewChanged(mContentView);
++                }
+             }
+ 
+             @Override
+             public void onViewDetachedFromWindow(View view) {
+                 mIsViewAttachedToWindow = false;
+                 updateInteractableState();
++                if (mAutofillProvider != null) {
++                    mAutofillProvider.onContainerViewChanged(mContentView);
++                }
+             }
+         };
+         mTabViewManager = new TabViewManagerImpl(this);
+@@ -817,6 +832,11 @@ public class TabImpl implements Tab {
+         for (TabObserver observer : mObservers) observer.onDestroyed(this);
+         mObservers.clear();
+ 
++        if (mAutofillProvider != null) {
++            mAutofillProvider.destroy();
++            mAutofillProvider = null;
++        }
++
+         mUserDataHost.destroy();
+         mTabViewManager.destroy();
+         hideNativePage(false, null);
+@@ -1395,6 +1415,18 @@ public class TabImpl implements Tab {
+         return mWebContentsState == null ? -1 : mWebContentsState.version();
+     }
+ 
++    public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
++        if (mAutofillProvider != null) {
++            mAutofillProvider.onProvideAutoFillVirtualStructure(structure, flags);
++        }
++    }
++
++    public void autofill(final SparseArray<AutofillValue> values) {
++        if (mAutofillProvider != null) {
++            mAutofillProvider.autofill(values);
++        }
++    }
++
+     /**
+      * Initializes the {@link WebContents}. Completes the browser content components initialization
+      * around a native WebContents pointer.
+@@ -1438,10 +1470,23 @@ public class TabImpl implements Tab {
+             mWebContentsDelegate = createWebContentsDelegate();
+ 
+             assert mNativeTabAndroid != 0;
++            SelectionPopupController selectionController = null;
++            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
++                selectionController = SelectionPopupController.fromWebContents(mWebContents);
++                mAutofillProvider = new AutofillProvider(
++                        getContext(), cv, webContents, "NativeAutofillRenderer");
++            }
+             TabImplJni.get().initWebContents(mNativeTabAndroid, mIncognito,
+                     TabUtils.isDetached(this), webContents, mWebContentsDelegate,
+                     new TabContextMenuPopulatorFactory(
+                             mDelegateFactory.createContextMenuPopulatorFactory(this), this));
++            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && selectionController != null) {
++                mAutofillProvider.setWebContents(webContents);
++                cv.setWebContents(webContents);
++                selectionController.setNonSelectionAdditionalMenuItemProvider(
++                        new AutofillSelectionMenuItemProvider(
++                                mThemedApplicationContext, mAutofillProvider));
++            }
+ 
+             mWebContents.notifyRendererPreferenceUpdate();
+             TabHelpers.initWebContentsHelpers(this);
+diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java
+index 16c12477bbcb2..a5c9b7fffe05e 100644
+--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java
++++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java
+@@ -4,7 +4,10 @@
+ 
+ package org.chromium.chrome.browser.tab;
+ 
++import android.util.SparseArray;
+ import android.view.ViewGroup;
++import android.view.ViewStructure;
++import android.view.autofill.AutofillValue;
+ 
+ import androidx.annotation.Nullable;
+ 
+@@ -86,6 +89,16 @@ public class TabViewAndroidDelegate extends ViewAndroidDelegate {
+         mTab.onBackgroundColorChanged(color);
+     }
+ 
++    @Override
++    public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
++        mTab.onProvideAutofillVirtualStructure(structure, flags);
++    }
++
++    @Override
++    public void autofill(final SparseArray<AutofillValue> values) {
++        mTab.autofill(values);
++    }
++
+     @Override
+     public void onTopControlsChanged(
+             int topControlsOffsetY, int contentOffsetY, int topControlsMinHeightOffsetY) {
+diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
+index 7cb8d3fc03da2..3a15d9e907b60 100644
+--- a/chrome/browser/BUILD.gn
++++ b/chrome/browser/BUILD.gn
+@@ -2651,6 +2651,13 @@ static_library("browser") {
+     deps += [ "//chrome/browser/error_reporting" ]
+   }
+ 
++  if (is_android) {
++    deps += [
++      "//components/android_autofill/browser",
++      "//components/android_autofill/browser:android"
++    ]
++  }
++
+   if (use_ozone) {
+     deps += [
+       "//ui/events/ozone",
+diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
+index 9e4c108ec5bc5..afa1ade208467 100644
+--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
++++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
+@@ -58,6 +58,9 @@
+ #include "chrome/browser/web_data_service_factory.h"
+ #include "chrome/common/channel_info.h"
+ #include "chrome/common/url_constants.h"
++#if BUILDFLAG(IS_ANDROID)
++#include "components/android_autofill/browser/android_autofill_manager.h"
++#endif // BUILDFLAG(IS_ANDROID)
+ #include "components/autofill/content/browser/autofill_log_router_factory.h"
+ #include "components/autofill/content/browser/content_autofill_driver.h"
+ #include "components/autofill/content/browser/content_autofill_driver_factory.h"
+@@ -215,12 +218,16 @@ ChromeAutofillClient::GetURLLoaderFactory() {
+ }
+ 
+ AutofillDownloadManager* ChromeAutofillClient::GetDownloadManager() {
++#if defined(USE_BROWSER_AUTOFILL_ONLY)
+   if (!download_manager_) {
+     // Lazy initialization to avoid virtual function calls in the constructor.
+     download_manager_ = std::make_unique<AutofillDownloadManager>(
+         this, GetChannel(), GetLogManager());
+   }
+   return download_manager_.get();
++#else
++  return nullptr;
++#endif // defined(USE_BROWSER_AUTOFILL_ONLY)
+ }
+ 
+ AutofillOptimizationGuide* ChromeAutofillClient::GetAutofillOptimizationGuide()
+@@ -1323,7 +1330,12 @@ void ChromeAutofillClient::OnZoomChanged(
+ ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents)
+     : ContentAutofillClient(
+           web_contents,
+-          base::BindRepeating(&BrowserDriverInitHook,
++          base::BindRepeating(
++#if BUILDFLAG(IS_ANDROID)
++                              &AndroidAndBrowserDriverInitHook,
++#else
++                              &BrowserDriverInitHook,
++#endif // BUILDFLAG(IS_ANDROID)
+                               this,
+                               g_browser_process->GetApplicationLocale())),
+       content::WebContentsObserver(web_contents),
+diff --git a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java
+index aefde08a5b224..e08ce993314e2 100644
+--- a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java
++++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java
+@@ -9,6 +9,7 @@ import android.content.res.Configuration;
+ import android.graphics.Rect;
+ import android.os.Build;
+ import android.os.Handler;
++import android.util.SparseArray;
+ import android.view.DragEvent;
+ import android.view.KeyEvent;
+ import android.view.MotionEvent;
+@@ -19,6 +20,7 @@ import android.view.View.OnSystemUiVisibilityChangeListener;
+ import android.view.ViewGroup.OnHierarchyChangeListener;
+ import android.view.ViewStructure;
+ import android.view.accessibility.AccessibilityNodeProvider;
++import android.view.autofill.AutofillValue;
+ import android.view.inputmethod.EditorInfo;
+ import android.view.inputmethod.InputConnection;
+ import android.widget.FrameLayout;
+@@ -38,6 +40,7 @@ import org.chromium.ui.accessibility.AccessibilityState;
+ import org.chromium.ui.base.EventForwarder;
+ import org.chromium.ui.base.EventOffsetHandler;
+ import org.chromium.ui.dragdrop.DragEventDispatchHelper.DragEventDispatchDestination;
++import org.chromium.ui.base.ViewAndroidDelegate;
+ 
+ import java.util.function.Supplier;
+ 
+@@ -92,6 +95,9 @@ public class ContentView extends FrameLayout
+      */
+     public static ContentView createContentView(Context context,
+             @Nullable EventOffsetHandler eventOffsetHandler, @Nullable WebContents webContents) {
++        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
++            return new ContentViewWithAutofill(context, eventOffsetHandler, webContents);
++        }
+         return new ContentView(context, eventOffsetHandler, webContents);
+     }
+ 
+@@ -638,4 +644,46 @@ public class ContentView extends FrameLayout
+         mDragDropEventOffsetHandler.onPostDispatchDragEvent(event.getAction());
+         return ret;
+     }
++
++    /**
++     * API level 26 implementation that includes autofill.
++     */
++    private static class ContentViewWithAutofill extends ContentView {
++        private ViewAndroidDelegate viewAndroidDelegate;
++
++        private ContentViewWithAutofill(
++                Context context, EventOffsetHandler eventOffsetHandler, WebContents webContents) {
++            super(context, eventOffsetHandler, webContents);
++
++            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
++                // The Autofill system-level infrastructure has heuristics for which Views it
++                // considers important for autofill; only these Views will be queried for their
++                // autofill structure on notifications that a new (virtual) View was entered. By
++                // default, FrameLayout is not considered important for autofill. Thus, for
++                // ContentView to be queried for its autofill structure, we must explicitly inform
++                // the autofill system that this View is important for autofill.
++                setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES);
++            }
++        }
++
++        @Override
++        public void setWebContents(WebContents webContents) {
++            viewAndroidDelegate = webContents.getViewAndroidDelegate();
++            super.setWebContents(webContents);
++        }
++
++        @Override
++        public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
++            if (viewAndroidDelegate != null) {
++                viewAndroidDelegate.onProvideAutofillVirtualStructure(structure, flags);
++            }
++        }
++
++        @Override
++        public void autofill(final SparseArray<AutofillValue> values) {
++            if (viewAndroidDelegate != null) {
++                viewAndroidDelegate.autofill(values);
++            }
++        }
++    }
+ }
+diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
+index 1e1d4ea42cf90..595e6a703fff4 100644
+--- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
++++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
+@@ -31,6 +31,10 @@ import org.chromium.ui.dragdrop.DragStateTracker;
+ import org.chromium.ui.dragdrop.DropDataAndroid;
+ import org.chromium.ui.mojom.CursorType;
+ 
++import android.util.SparseArray;
++import android.view.autofill.AutofillValue;
++import android.view.ViewStructure;
++
+ /**
+  * Class to acquire, position, and remove anchor views from the implementing View.
+  */
+@@ -578,4 +582,8 @@ public class ViewAndroidDelegate {
+         sDragAndDropDelegateForTesting = testDelegate;
+         ResettersForTesting.register(() -> sDragAndDropDelegateForTesting = null);
+     }
++
++    public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {}
++
++    public void autofill(final SparseArray<AutofillValue> values) {}
+ }
diff --git a/build-chromium/patches/0099-Disable-Play-services-dependent-password-manager-fea.patch b/build-chromium/patches/0099-Disable-Play-services-dependent-password-manager-fea.patch
new file mode 100644
index 0000000..85b1bde
--- /dev/null
+++ b/build-chromium/patches/0099-Disable-Play-services-dependent-password-manager-fea.patch
@@ -0,0 +1,23 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Tue, 21 Feb 2023 02:02:40 +0000
+Subject: [PATCH] Disable Play services dependent password manager feature by
+ default
+
+---
+ .../password_manager/core/common/password_manager_features.cc   | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
+index 0d34f5a2cfb54..2b511913bcc70 100644
+--- a/components/password_manager/core/common/password_manager_features.cc
++++ b/components/password_manager/core/common/password_manager_features.cc
+@@ -128,7 +128,7 @@ BASE_FEATURE(kPasswordSuggestionBottomSheetV2,
+ // database will be unused but kept in sync for local passwords.
+ BASE_FEATURE(kUnifiedPasswordManagerAndroid,
+              "UnifiedPasswordManagerAndroid_LAUNCHED",
+-             base::FEATURE_ENABLED_BY_DEFAULT);
++             base::FEATURE_DISABLED_BY_DEFAULT);
+ 
+ // Enables use of Google Mobile services for non-synced password storage.
+ BASE_FEATURE(kUnifiedPasswordManagerLocalPasswordsAndroidWithMigration,
diff --git a/build-chromium/patches/0100-Disable-Play-services-dependent-password-manager-pre.patch b/build-chromium/patches/0100-Disable-Play-services-dependent-password-manager-pre.patch
new file mode 100644
index 0000000..342f026
--- /dev/null
+++ b/build-chromium/patches/0100-Disable-Play-services-dependent-password-manager-pre.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: fgei <fgei@gmail.com>
+Date: Tue, 21 Feb 2023 02:06:16 +0000
+Subject: [PATCH] Disable Play services dependent password manager prefs by
+ default
+
+---
+ components/password_manager/core/browser/password_manager.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
+index b2e6dc0c7ec86..72da942d0b20f 100644
+--- a/components/password_manager/core/browser/password_manager.cc
++++ b/components/password_manager/core/browser/password_manager.cc
+@@ -303,9 +303,9 @@ void PasswordManager::RegisterProfilePrefs(
+       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+   registry->RegisterBooleanPref(prefs::kPasswordsPrefWithNewLabelUsed, false);
+ #if BUILDFLAG(IS_ANDROID)
+-  registry->RegisterBooleanPref(prefs::kOfferToSavePasswordsEnabledGMS, true);
++  registry->RegisterBooleanPref(prefs::kOfferToSavePasswordsEnabledGMS, false);
+   registry->RegisterBooleanPref(prefs::kSavePasswordsSuspendedByError, false);
+-  registry->RegisterBooleanPref(prefs::kAutoSignInEnabledGMS, true);
++  registry->RegisterBooleanPref(prefs::kAutoSignInEnabledGMS, false);
+   registry->RegisterBooleanPref(prefs::kSettingsMigratedToUPMLocal, false);
+   registry->RegisterIntegerPref(
+       prefs::kCurrentMigrationVersionToGoogleMobileServices, 0);