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);