Files
cromite/build/patches/Enable-native-Android-autofill.patch

962 lines
49 KiB
Diff

From: uazo <uazo@users.noreply.github.com>
Date: Sun, 24 Oct 2021 16:54:04 +0000
Subject: Enable native Android autofill
There are 2 different types of autofill: one managed via GCM and the
native Android one that uses the provider assigned by the user
(which can be any user installed app like Bitwarden for example).
In chromium GCM is active while in the WebView the latter.
This patch uses WebView code to enable native Android autofill
along with browser-managed autofill.
A separate toggle is introduced to enable autofill in incognito mode.
See also: https://github.com/bromite/bromite/issues/547
Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
---
.../settings/PasswordSettings.java | 84 ++++++++++++++++-
.../chrome/browser/settings/MainSettings.java | 18 +---
.../chromium/chrome/browser/tab/TabImpl.java | 41 ++++++--
chrome/browser/android/tab_android.cc | 4 +-
.../actor/actor_form_filling_service_impl.cc | 8 --
chrome/browser/autofill/android/BUILD.gn | 2 +-
.../autofill/AutofillClientProviderUtils.java | 2 +-
...AutofillThirdPartyModeContentProvider.java | 1 +
.../chrome_password_manager_client.cc | 6 ++
.../chrome_password_manager_client.h | 2 +
.../strings/android_chrome_strings.grd | 6 ++
.../ui/autofill/autofill_client_provider.cc | 94 +------------------
.../ui/autofill/autofill_client_provider.h | 6 --
chrome/browser/ui/tab_helpers.cc | 4 +-
components/android_autofill/browser/BUILD.gn | 1 +
.../browser/android_autofill_manager.cc | 2 +
.../browser/android_autofill_manager.h | 2 +
.../autofill/AutofillManagerWrapper.java | 5 +-
.../components/autofill/AutofillProvider.java | 7 ++
.../BrowserSelectionActionMenuDelegate.java | 27 ++++++
.../browser/content_autofill_driver.cc | 11 +++
.../content/browser/content_autofill_driver.h | 10 ++
.../content_autofill_driver_factory.cc | 12 +++
.../content/renderer/autofill_agent.cc | 4 -
.../renderer/password_autofill_agent.cc | 5 +-
.../browser/foundations/autofill_driver.h | 2 +
.../foundations/autofill_driver_factory.cc | 4 +
.../browser/foundations/autofill_manager.h | 2 +
.../foundations/browser_autofill_manager.cc | 2 +
.../foundations/browser_autofill_manager.h | 2 +
.../autofill/core/common/autofill_prefs.cc | 4 +-
.../autofill/core/common/autofill_prefs.h | 5 +
.../core/browser/password_form_manager.cc | 4 +
.../core/browser/password_manager_client.cc | 2 +
.../core/browser/password_manager_client.h | 2 +
35 files changed, 249 insertions(+), 144 deletions(-)
create mode 100644 components/android_autofill/browser/java/src/org/chromium/components/autofill/BrowserSelectionActionMenuDelegate.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
@@ -27,6 +27,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
+import org.chromium.base.StrictModeContext;
import org.chromium.base.supplier.MonotonicObservableSupplier;
import org.chromium.base.supplier.ObservableSuppliers;
import org.chromium.base.supplier.SettableMonotonicObservableSupplier;
@@ -60,6 +61,12 @@ import org.chromium.ui.base.IntentRequestTracker;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Locale;
+import java.util.function.Supplier;
+
+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
+import org.chromium.chrome.browser.ui.messages.snackbar.INeedSnackbarManager;
+import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
+import org.chromium.chrome.browser.lifetime.ApplicationLifetime;
/**
* The "Passwords" screen in Settings, which allows the user to enable or disable password saving,
@@ -68,7 +75,7 @@ import java.util.Locale;
public class PasswordSettings extends ChromeBaseSettingsFragment
implements PasswordListObserver,
Preference.OnPreferenceClickListener, SearchViewProvider,
- SyncService.SyncStateChangedListener {
+ SyncService.SyncStateChangedListener, INeedSnackbarManager {
@IntDef({
TrustedVaultBannerState.NOT_SHOWN,
TrustedVaultBannerState.OFFER_OPT_IN,
@@ -98,6 +105,12 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
public static final String PREF_TRUSTED_VAULT_BANNER = "trusted_vault_banner";
public static final String PREF_KEY_MANAGE_ACCOUNT_LINK = "manage_account_link";
+ public static final String PREF_ANDROID_AUTOFILL_SWITCH = "android_autofill_switch";
+ public static final String PREF_ANDROID_AUTOFILL_INCOGNITO_SWITCH = "android_autofill_incognito_switch";
+
+ private Supplier<SnackbarManager> mSnackbarManagerSupplier;
+ private Snackbar mSnackbar;
+
private static final String PREF_KEY_CATEGORY_SAVED_PASSWORDS = "saved_passwords";
private static final String PREF_KEY_CATEGORY_EXCEPTIONS = "exceptions";
private static final String PREF_KEY_SAVED_PASSWORDS_NO_TEXT = "saved_passwords_no_text";
@@ -133,6 +146,9 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
private final SettableMonotonicObservableSupplier<String> mPageTitle =
ObservableSuppliers.createMonotonic();
+ private ChromeSwitchPreference mEnableAndroidAutofillSwitch;
+ private ChromeSwitchPreference mEnableAndroidAutofillIncognitoSwitch;
+
/** For controlling the UX flow of exporting passwords. */
private final ExportFlow mExportFlow = new ExportFlow();
private ActivityWindowAndroid mWindowAndroid;
@@ -317,6 +333,7 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
createSavePasswordsSwitch();
createAutoSignInCheckbox();
+ createEnableAndroidAutofillSwitch();
PasswordManagerHandlerProvider.getForProfile(getProfile())
.getPasswordManagerHandler()
@@ -579,6 +596,71 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE));
}
+ private void createEnableAndroidAutofillSwitch() {
+ if (mSnackbar == null) {
+ mSnackbar = Snackbar.make(getActivity().getString(R.string.ui_relaunch_notice),
+ new SnackbarManager.SnackbarController() {
+ @Override
+ public void onDismissNoAction(Object actionData) { }
+
+ @Override
+ public void onAction(Object actionData) {
+ ApplicationLifetime.terminate(true);
+ }
+ }, Snackbar.TYPE_NOTIFICATION, Snackbar.UMA_UNKNOWN)
+ .setDefaultLines(false)
+ .setAction(getActivity().getString(R.string.relaunch),
+ /*actionData*/null)
+ .setDuration(/*durationMs*/70000);
+ }
+
+ mEnableAndroidAutofillSwitch = new ChromeSwitchPreference(getStyledContext(), null);
+ mEnableAndroidAutofillSwitch.setKey(PREF_ANDROID_AUTOFILL_SWITCH);
+ mEnableAndroidAutofillSwitch.setTitle(R.string.enable_android_autofill);
+ mEnableAndroidAutofillSwitch.setOrder(ORDER_SWITCH);
+ mEnableAndroidAutofillSwitch.setSummaryOn(R.string.text_on);
+ mEnableAndroidAutofillSwitch.setSummaryOff(R.string.text_off);
+
+ try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
+ getPreferenceScreen().addPreference(mEnableAndroidAutofillSwitch);
+ }
+
+ mEnableAndroidAutofillSwitch.setChecked(
+ getPrefService().getBoolean(Pref.AUTOFILL_ANDROID_ENABLED));
+
+ mEnableAndroidAutofillSwitch.setOnPreferenceChangeListener((preference, newValue) -> {
+ getPrefService().setBoolean(Pref.AUTOFILL_ANDROID_ENABLED, (boolean) newValue);
+ if (!mSnackbarManagerSupplier.get().isShowing())
+ mSnackbarManagerSupplier.get().showSnackbar(mSnackbar);
+ return true;
+ });
+
+ mEnableAndroidAutofillIncognitoSwitch = new ChromeSwitchPreference(getStyledContext(), null);
+ mEnableAndroidAutofillIncognitoSwitch.setKey(PREF_ANDROID_AUTOFILL_INCOGNITO_SWITCH);
+ mEnableAndroidAutofillIncognitoSwitch.setTitle(R.string.enable_android_autofill_incognito);
+ mEnableAndroidAutofillIncognitoSwitch.setOrder(ORDER_SWITCH);
+ mEnableAndroidAutofillIncognitoSwitch.setSummaryOn(R.string.text_on);
+ mEnableAndroidAutofillIncognitoSwitch.setSummaryOff(R.string.text_off);
+
+ try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
+ getPreferenceScreen().addPreference(mEnableAndroidAutofillIncognitoSwitch);
+ }
+
+ mEnableAndroidAutofillIncognitoSwitch.setChecked(
+ getPrefService().getBoolean(Pref.AUTOFILL_ANDROID_INCOGNITO_ENABLED));
+
+ mEnableAndroidAutofillIncognitoSwitch.setOnPreferenceChangeListener((preference, newValue) -> {
+ getPrefService().setBoolean(Pref.AUTOFILL_ANDROID_INCOGNITO_ENABLED, (boolean) newValue);
+ if (!mSnackbarManagerSupplier.get().isShowing())
+ mSnackbarManagerSupplier.get().showSnackbar(mSnackbar);
+ return true;
+ });
+ }
+
+ public void setSnackbarManagerSupplier(Supplier<SnackbarManager> manager) {
+ mSnackbarManagerSupplier = manager;
+ }
+
private void createAutoSignInCheckbox() {
ChromeSwitchPreference autoSignInSwitch =
new ChromeSwitchPreference(getStyledContext(), null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -720,22 +720,8 @@ public class MainSettings extends ChromeBaseSettingsFragment
// TODO(crbug.com/482988366): Remove this method once the Autofill and passwords feature is launched.
private void updateAutofillPreferencesPreAutofillAndPasswords() {
- addPreferenceIfAbsent(PREF_AUTOFILL_SECTION);
- addPreferenceIfAbsent(PREF_AUTOFILL_OPTIONS);
- Preference autofillOptionsPreference = findPreference(PREF_AUTOFILL_OPTIONS);
- autofillOptionsPreference.setTitle(AutofillOptionsMediator.getFragmentTitle(getContext()));
- autofillOptionsPreference.setFragment(null);
- autofillOptionsPreference.setOnPreferenceClickListener(
- preference -> {
- onPreferenceSelected(preference);
- SettingsNavigationFactory.createSettingsNavigation()
- .startSettings(
- getContext(),
- AutofillOptionsFragment.class,
- AutofillOptionsFragment.createRequiredArgs(
- AutofillOptionsReferrer.SETTINGS));
- return true; // Means event is consumed.
- });
+ removePreferenceIfPresent(PREF_AUTOFILL_SECTION);
+ removePreferenceIfPresent(PREF_AUTOFILL_OPTIONS);
findPreference(PREF_AUTOFILL_PAYMENTS)
.setOnPreferenceClickListener(
preference -> {
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
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -121,6 +121,13 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import org.chromium.components.autofill.AutofillSelectionMenuItemHelper;
+import org.chromium.components.autofill.BrowserSelectionActionMenuDelegate;
+import org.chromium.content_public.browser.SelectionPopupController;
+import org.chromium.chrome.browser.preferences.Pref;
+import org.chromium.chrome.browser.profiles.ProfileManager;
+import org.chromium.components.user_prefs.UserPrefs;
+
/**
* Implementation of the interface {@link Tab}. Contains and manages a {@link ContentView}. This
* class is not intended to be extended.
@@ -1252,6 +1259,11 @@ class TabImpl implements Tab {
}
mObservers.clear();
+ if (mAutofillProvider != null) {
+ mAutofillProvider.destroy();
+ mAutofillProvider = null;
+ }
+
if (!abortNavigationsFromTabClosures) mUserDataHost.destroy();
mTabViewManager.destroy();
hideNativePage(false, null);
@@ -1641,6 +1653,7 @@ class TabImpl implements Tab {
* @return iff the AutofillProvider should provide a ViewStructure when prompted.
*/
boolean providesAutofillStructure() {
+ if ((true)) return true;
if (!mProfile.isNativeInitialized()) {
return false;
}
@@ -2440,16 +2453,21 @@ class TabImpl implements Tab {
* @return true if the the provider is available for the given WebContents.
*/
private boolean prepareAutofillProvider(WebContents newWebContents) {
- assert isInitialized();
- if (!providesAutofillStructure()) {
+ boolean autofillEnabled = false;
+ if (isIncognito()) {
+ autofillEnabled = UserPrefs.get(ProfileManager.getLastUsedRegularProfile())
+ .getBoolean(Pref.AUTOFILL_ANDROID_INCOGNITO_ENABLED);
+ } else {
+ autofillEnabled = UserPrefs.get(ProfileManager.getLastUsedRegularProfile())
+ .getBoolean(Pref.AUTOFILL_ANDROID_ENABLED);
+ }
+ if (!autofillEnabled) {
maybeLogAutofillProviderDoesntUseVirtualStructureMetric();
mAutofillProvider = null;
return false; // Autofill provider can't be prepared.
}
- if (mAutofillProvider != null) {
- // Provider already existed. Swapping contents suffices.
- mAutofillProvider.setWebContents(newWebContents);
- } else {
+ assert isInitialized();
+ if (mAutofillProvider == null) {
// TODO: crbug.com/432447902 — Provide only an activity context and push changes.
mAutofillProvider =
new AutofillProvider(
@@ -2459,7 +2477,16 @@ class TabImpl implements Tab {
getContext().getString(R.string.app_name));
TabImplJni.get().initializeAutofillIfNecessary(mNativeTabAndroid);
}
- addAutofillItemsToSelectionActionMenu(newWebContents);
+ SelectionPopupController selectionController =
+ SelectionPopupController.fromWebContents(newWebContents);
+ mAutofillProvider.setWebContents(newWebContents);
+ mContentView.setWebContents(newWebContents);
+ BrowserSelectionActionMenuDelegate selectionActionMenuDelegate =
+ new BrowserSelectionActionMenuDelegate();
+ selectionActionMenuDelegate.setAutofillSelectionMenuItemHelper(
+ new AutofillSelectionMenuItemHelper(mAutofillProvider));
+ selectionController.setSelectionActionMenuDelegate(selectionActionMenuDelegate);
+
return true;
}
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -40,6 +40,7 @@
#include "chrome/browser/sync/glue/synced_tab_delegate_android.h"
#include "chrome/browser/tab/web_contents_state.h"
#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
#include "chrome/browser/ui/android/context_menu_helper.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
@@ -431,8 +432,7 @@ void TabAndroid::InitializeAutofillIfNecessary() {
->MaybeInitKeyboardSuppressor();
return;
}
- android_autofill::AndroidAutofillClient::CreateForWebContents(
- web_contents_.get());
+ autofill::ChromeAutofillClient::CreateForWebContents(web_contents_.get());
// We need to initialize the keyboard suppressor before creating any
// AutofillManagers and after the autofill client is available.
diff --git a/chrome/browser/autofill/actor/actor_form_filling_service_impl.cc b/chrome/browser/autofill/actor/actor_form_filling_service_impl.cc
--- a/chrome/browser/autofill/actor/actor_form_filling_service_impl.cc
+++ b/chrome/browser/autofill/actor/actor_form_filling_service_impl.cc
@@ -427,14 +427,6 @@ GetAutofillManager(const tabs::TabInterface& tab) {
if (!profile) {
return base::unexpected(kAutofillNotAvailable);
}
- if (AutofillClientProviderFactory::GetForProfile(profile)
- .uses_platform_autofill()) {
- // This is currently only possible on Android platforms, but this check
- // guards against this becoming applicable for Desktop platforms as well.
- // It is a requirement for the cast to `BrowserAutofillManager` to be
- // safe.
- return base::unexpected(kAutofillNotAvailable);
- }
ContentAutofillClient* const client =
ContentAutofillClient::FromWebContents(tab.GetContents());
diff --git a/chrome/browser/autofill/android/BUILD.gn b/chrome/browser/autofill/android/BUILD.gn
--- a/chrome/browser/autofill/android/BUILD.gn
+++ b/chrome/browser/autofill/android/BUILD.gn
@@ -187,7 +187,7 @@ android_library("bottom_sheet_utils_java") {
generate_jni("jni_headers") {
sources = [
"java/src/org/chromium/chrome/browser/autofill/AddressNormalizerFactory.java",
- "java/src/org/chromium/chrome/browser/autofill/AutofillClientProviderUtils.java",
+ #"java/src/org/chromium/chrome/browser/autofill/AutofillClientProviderUtils.java",
"java/src/org/chromium/chrome/browser/autofill/AutofillImageFetcher.java",
"java/src/org/chromium/chrome/browser/autofill/AutofillImageFetcherFactory.java",
"java/src/org/chromium/chrome/browser/autofill/AutofillProfileBridge.java",
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillClientProviderUtils.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillClientProviderUtils.java
--- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillClientProviderUtils.java
+++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillClientProviderUtils.java
@@ -90,9 +90,9 @@ public class AutofillClientProviderUtils {
* @return {@link AndroidAutofillAvailabilityStatus.AVAILABLE} if Android Autofill can be used
* or a reason why it can't.
*/
- @CalledByNative
public static int getAndroidAutofillFrameworkAvailability(
@JniType("PrefService*") PrefService prefs) {
+ if ((true)) return AndroidAutofillAvailabilityStatus.AVAILABLE;
if (sAndroidAutofillFrameworkAvailabilityForTesting != null) {
return sAndroidAutofillFrameworkAvailabilityForTesting;
}
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillThirdPartyModeContentProvider.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillThirdPartyModeContentProvider.java
--- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillThirdPartyModeContentProvider.java
+++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/AutofillThirdPartyModeContentProvider.java
@@ -75,6 +75,7 @@ public final class AutofillThirdPartyModeContentProvider extends ContentProvider
@Nullable String selection,
String @Nullable [] selectionArgs,
@Nullable String sortOrder) {
+ if ((true)) return null;
if (createContentUri().equals(uri)) {
final String[] columns = {AUTOFILL_THIRD_PARTY_MODE_COLUMN};
MatrixCursor cursor = new MatrixCursor(columns, 1);
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -521,6 +521,12 @@ bool ChromePasswordManagerClient::PromptUserToChooseCredentials(
}
#if BUILDFLAG(IS_ANDROID)
+void ChromePasswordManagerClient::OnFillNow() {
+ if (touch_to_fill_controller_) {
+ touch_to_fill_controller_->Reset();
+ }
+}
+
void ChromePasswordManagerClient::ShowPasswordManagerErrorMessage(
password_manager::ErrorMessageFlowType flow_type,
password_manager::PasswordStoreBackendErrorType error_type) {
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -161,6 +161,8 @@ class ChromePasswordManagerClient
const url::Origin& origin,
CredentialsCallback callback) override;
#if BUILDFLAG(IS_ANDROID)
+ void OnFillNow() override;
+
void ShowPasswordManagerErrorMessage(
password_manager::ErrorMessageFlowType flow_type,
password_manager::PasswordStoreBackendErrorType error_type) override;
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -345,6 +345,12 @@ CHAR_LIMIT guidelines:
<message name="IDS_PREFS_SECTION_ACCOUNT_AND_GOOGLE_SERVICES" desc="Title for the group of account-related entries and google services in Settings. [CHAR_LIMIT=32]">
You and Google
</message>
+ <message name="IDS_ENABLE_ANDROID_AUTOFILL" desc="Title for the checkbox toggling whether enable Android native autofill or not. [CHAR_LIMIT=32]">
+ Enable native Android autofill
+ </message>
+ <message name="IDS_ENABLE_ANDROID_AUTOFILL_INCOGNITO" desc="Title for the checkbox toggling whether enable Android native autofill or not in incognito mode. [CHAR_LIMIT=32]">
+ Enable native Android autofill in incognito
+ </message>
<message name="IDS_SIGN_IN_TO_CHROME" meaning="Button" desc="Title for the button to sign in to Chrome using one's Google account. [CHAR_LIMIT=27]">
Sign in to Chrome
</message>
diff --git a/chrome/browser/ui/autofill/autofill_client_provider.cc b/chrome/browser/ui/autofill/autofill_client_provider.cc
--- a/chrome/browser/ui/autofill/autofill_client_provider.cc
+++ b/chrome/browser/ui/autofill/autofill_client_provider.cc
@@ -17,92 +17,14 @@
#include "chrome/browser/autofill/android/android_autofill_availability_status.h"
#include "components/android_autofill/browser/android_autofill_client.h"
#include "components/prefs/android/pref_service_android.h"
-
-// Must come after all headers that specialize FromJniType() / ToJniType().
-#include "chrome/browser/autofill/android/jni_headers/AutofillClientProviderUtils_jni.h"
#endif // BUILDFLAG(IS_ANDROID)
namespace autofill {
-namespace {
-
-#if BUILDFLAG(IS_ANDROID)
-void RecordAvailabilityStatus(AndroidAutofillAvailabilityStatus availability) {
- base::UmaHistogramEnumeration("Autofill.AndroidAutofillAvailabilityStatus",
- availability);
-}
-
-// Counts how often the Chrome pref is reset because an platform autofill
-// isn't allowed or doesn't fulfill all preconditions.
-void RecordWhetherAndroidPrefResets(PrefService& prefs,
- bool uses_platform_autofill) {
- const bool will_reset_pref =
- prefs.GetBoolean(prefs::kAutofillUsingPlatformAutofill) &&
- !uses_platform_autofill;
- base::UmaHistogramBoolean("Autofill.ResetAutofillPrefToChrome",
- will_reset_pref);
-}
-
-// Sets a ahread pref that allows to learn whether deep-links into Chrome's
-// settings are available to use.
-void SetSharedPrefForDeepLink() {
- Java_AutofillClientProviderUtils_setAutofillOptionsDeepLinkPref(
- base::android::AttachCurrentThread(),
-
- base::FeatureList::IsEnabled(
- autofill::features::kAutofillDeepLinkAutofillOptions));
-}
-
-// Sets a shared pref that allows external apps to use a ContentResolver to
-// figure out whether Chrome is using platform autofill over the default.
-void SetSharedPrefForSettingsContentProvider(bool uses_platform_autofill) {
- if (base::FeatureList::IsEnabled(
- autofill::features::kAutofillThirdPartyModeContentProvider)) {
- Java_AutofillClientProviderUtils_setThirdPartyModePref(
- base::android::AttachCurrentThread(), uses_platform_autofill);
- } else {
- Java_AutofillClientProviderUtils_unsetThirdPartyModePref(
- base::android::AttachCurrentThread());
- }
-}
-AndroidAutofillAvailabilityStatus GetAndroidAutofillAvailabilityStatus(
- PrefService& prefs) {
- return static_cast<AndroidAutofillAvailabilityStatus>(
- Java_AutofillClientProviderUtils_getAndroidAutofillFrameworkAvailability(
- base::android::AttachCurrentThread(), &prefs));
-}
-#endif // BUILDFLAG(IS_ANDROID)
-
-bool UsesVirtualViewStructureForAutofill(PrefService& prefs) {
+AutofillClientProvider::AutofillClientProvider(PrefService* prefs) {
#if BUILDFLAG(IS_ANDROID)
- const AndroidAutofillAvailabilityStatus availability =
- GetAndroidAutofillAvailabilityStatus(prefs);
- RecordAvailabilityStatus(availability);
- return availability == AndroidAutofillAvailabilityStatus::kAvailable;
-#else
- return false;
-#endif // BUILDFLAG(IS_ANDROID)
-}
-
-} // namespace
-
-AutofillClientProvider::AutofillClientProvider(PrefService* prefs)
- : uses_platform_autofill_(
- UsesVirtualViewStructureForAutofill(CHECK_DEREF(prefs))) {
-#if BUILDFLAG(IS_ANDROID)
- RecordWhetherAndroidPrefResets(*prefs, uses_platform_autofill_);
- // Ensure the pref is reset if platform autofill is restricted.
prefs->SetBoolean(prefs::kAutofillUsingPlatformAutofill,
- uses_platform_autofill_);
- if (uses_platform_autofill_) {
- // Update the package of the actively used Autofill Service while platform
- // autofill is used. This allows restoring platform autofill later if it's
- // temporarily unavailable. Calling this for AwG would reset the pref.
- Java_AutofillClientProviderUtils_updatePackageUsedForAutofill(
- base::android::AttachCurrentThread(), prefs, uses_platform_autofill_);
- }
- SetSharedPrefForSettingsContentProvider(uses_platform_autofill_);
- SetSharedPrefForDeepLink();
+ true);
#endif // BUILDFLAG(IS_ANDROID)
}
@@ -110,19 +32,7 @@ AutofillClientProvider::~AutofillClientProvider() = default;
void AutofillClientProvider::CreateClientForWebContents(
content::WebContents* web_contents) {
- if (uses_platform_autofill()) {
-#if BUILDFLAG(IS_ANDROID)
- android_autofill::AndroidAutofillClient::CreateForWebContents(web_contents);
-#else
- NOTREACHED();
-#endif
- } else {
ChromeAutofillClient::CreateForWebContents(web_contents);
- }
}
} // namespace autofill
-
-#if BUILDFLAG(IS_ANDROID)
-DEFINE_JNI(AutofillClientProviderUtils)
-#endif
diff --git a/chrome/browser/ui/autofill/autofill_client_provider.h b/chrome/browser/ui/autofill/autofill_client_provider.h
--- a/chrome/browser/ui/autofill/autofill_client_provider.h
+++ b/chrome/browser/ui/autofill/autofill_client_provider.h
@@ -33,13 +33,7 @@ class AutofillClientProvider : public KeyedService {
// given `web_contents`.
void CreateClientForWebContents(content::WebContents* web_contents);
- // The return value is constant once this provider has been created. The
- // method returns true iff platform autofill should be used instead of
- // built-in autofill.
- bool uses_platform_autofill() const { return uses_platform_autofill_; }
-
private:
- const bool uses_platform_autofill_;
};
} // namespace autofill
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -389,9 +389,7 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) {
web_contents);
ChainedBackNavigationTracker::CreateForWebContents(web_contents);
chrome_browser_net::NetErrorTabHelper::CreateForWebContents(web_contents);
- if (!autofill_client_provider.uses_platform_autofill()) {
- ChromePasswordManagerClient::CreateForWebContents(web_contents);
- }
+ ChromePasswordManagerClient::CreateForWebContents(web_contents);
#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
ChromePasswordReuseDetectionManagerClient::CreateForWebContents(web_contents);
#endif
diff --git a/components/android_autofill/browser/BUILD.gn b/components/android_autofill/browser/BUILD.gn
--- a/components/android_autofill/browser/BUILD.gn
+++ b/components/android_autofill/browser/BUILD.gn
@@ -42,6 +42,7 @@ android_library("java") {
"java/src/org/chromium/components/autofill/AutofillRequest.java",
"java/src/org/chromium/components/autofill/AutofillSelectionActionMenuDelegate.java",
"java/src/org/chromium/components/autofill/AutofillSelectionMenuItemHelper.java",
+ "java/src/org/chromium/components/autofill/BrowserSelectionActionMenuDelegate.java",
"java/src/org/chromium/components/autofill/FormData.java",
"java/src/org/chromium/components/autofill/FormFieldData.java",
"java/src/org/chromium/components/autofill/PrefillRequest.java",
diff --git a/components/android_autofill/browser/android_autofill_manager.cc b/components/android_autofill/browser/android_autofill_manager.cc
--- a/components/android_autofill/browser/android_autofill_manager.cc
+++ b/components/android_autofill/browser/android_autofill_manager.cc
@@ -36,6 +36,8 @@ AndroidAutofillManager::~AndroidAutofillManager() {
Reset();
}
+bool AndroidAutofillManager::IsAndroidAutofill() const { return true; }
+
base::WeakPtr<AutofillManager> AndroidAutofillManager::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
diff --git a/components/android_autofill/browser/android_autofill_manager.h b/components/android_autofill/browser/android_autofill_manager.h
--- a/components/android_autofill/browser/android_autofill_manager.h
+++ b/components/android_autofill/browser/android_autofill_manager.h
@@ -33,6 +33,8 @@ class AndroidAutofillManager : public AutofillManager,
~AndroidAutofillManager() override;
+ bool IsAndroidAutofill() const override;
+
base::WeakPtr<AndroidAutofillManager> GetWeakPtrToLeafClass() {
return weak_ptr_factory_.GetWeakPtr();
}
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
--- a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
+++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
@@ -59,6 +59,7 @@ public class AutofillManagerWrapper {
AutofillManagerWrapper manager = mManager.get();
if (manager == null) return;
manager.mIsAutofillInputUiShowing = (event == EVENT_INPUT_SHOWN);
+ if (manager.isLoggable()) manager.log("onAutofillEvent isAutofillInputUIShowing: " + manager.mIsAutofillInputUiShowing);
if (event == EVENT_INPUT_SHOWN) manager.notifyInputUiChange();
}
}
@@ -120,6 +121,7 @@ public class AutofillManagerWrapper {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ComponentName componentName = getAutofillServiceComponentName(mAutofillManager);
+ if (isLoggable()) log("componentName=" + componentName);
if (componentName != null) {
mPackageName = componentName.getPackageName();
mIsAwGCurrentAutofillService =
@@ -352,7 +354,7 @@ public class AutofillManagerWrapper {
/** Always check isLoggable() before call this method. */
public static void log(String log) {
// Log.i() instead of Log.d() is used here because Log.d() is stripped out in release build.
- Log.i(TAG, log);
+ Log.i(TAG, "---" + log);
}
public static boolean isLoggable() {
@@ -366,5 +368,6 @@ public class AutofillManagerWrapper {
// NOTE: See the comment on TAG above for why this is still AwAutofillManager.
// Check the system setting directly.
sIsLoggable = Log.isLoggable(TAG, Log.DEBUG);
+ // sIsLoggable = true; // to force enable the log
}
}
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
--- a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
+++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
@@ -252,6 +252,10 @@ public class AutofillProvider {
* @return whether query autofill suggestion.
*/
public boolean shouldQueryAutofillSuggestion() {
+ AutofillManagerWrapper.log("---shouldQueryAutofillSuggestion" +
+ " mRequest != null=" + (mRequest != null) +
+ " mRequest.getFocusField() != null=" + (mRequest != null && mRequest.getFocusField() != null) +
+ " !mAutofillManager.isAutofillInputUIShowing()=" + (!mAutofillManager.isAutofillInputUiShowing()));
return mRequest != null
&& mRequest.getFocusField() != null
&& !getAutofillManagerWrapper().isAutofillInputUiShowing();
@@ -260,6 +264,7 @@ public class AutofillProvider {
public boolean shouldOfferPasskeyEntry() {
if (!AndroidAutofillFeatures.ANDROID_AUTOFILL_VIRTUAL_VIEW_STRUCTURE_PASSKEY_LONG_PRESS
.isEnabled()) {
+ AutofillManagerWrapper.log("calling requestAutofill");
return false;
}
return AutofillProviderJni.get().hasPasskeyRequest(mNativeAutofillProvider);
@@ -272,6 +277,7 @@ public class AutofillProvider {
}
public void queryAutofillSuggestion() {
+ AutofillManagerWrapper.log("queryAutofillSuggestion start");
if (shouldQueryAutofillSuggestion()) {
FocusField focusField = mRequest.getFocusField();
getAutofillManagerWrapper()
@@ -334,6 +340,7 @@ public class AutofillProvider {
float width,
float height,
boolean hasServerPrediction) {
+ AutofillManagerWrapper.log("startAutofillSession");
Rect absBound = transformToWindowBounds(new RectF(x, y, x + width, y + height));
if (mRequest != null) notifyViewExitBeforeDestroyRequest();
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/BrowserSelectionActionMenuDelegate.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/BrowserSelectionActionMenuDelegate.java
new file mode 100644
--- /dev/null
+++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/BrowserSelectionActionMenuDelegate.java
@@ -0,0 +1,27 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.autofill;
+
+import android.content.pm.ResolveInfo;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.components.autofill.AutofillSelectionActionMenuDelegate;
+import org.chromium.content_public.browser.SelectionMenuItem;
+import org.chromium.content_public.browser.SelectionPopupController;
+import org.chromium.content_public.browser.selection.SelectionActionMenuDelegate;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.chromium.base.Log;
+
+/** Interface for customizing text selection menu items in {@link SelectionPopupController} */
+public class BrowserSelectionActionMenuDelegate extends AutofillSelectionActionMenuDelegate {
+}
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
--- a/components/autofill/content/browser/content_autofill_driver.cc
+++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -281,6 +281,13 @@ void RouteToManager(ContentAutofillDriver& source,
AutofillManager& manager = target.GetAutofillManager();
(manager.*
manager_fun)(WithNewVersion(std::forward<ManagerArgs>(args))...);
+
+ raw_ptr<AutofillManager> secondary_autofill_manager =
+ target.secondary_autofill_manager();
+ if (secondary_autofill_manager) {
+ (secondary_autofill_manager->*
+ manager_fun)(WithNewVersion(std::forward<ManagerArgs>(args))...);
+ }
},
source, Lift(source, std::forward<ActualArgs>(args))...);
}
@@ -701,6 +708,10 @@ ContentAutofillDriver::GetAutofillAgent() {
return autofill_agent_;
}
+raw_ptr<AutofillManager> ContentAutofillDriver::secondary_autofill_manager() {
+ return secondary_autofill_manager_.get();
+}
+
void ContentAutofillDriver::LiftForTest(FormData& form) {
form = Lift(*this, form);
}
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h
--- a/components/autofill/content/browser/content_autofill_driver.h
+++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -136,6 +136,12 @@ class ContentAutofillDriver : public AutofillDriver,
// AutofillDriverFactory. Called on certain types of navigations.
void Reset(ContentAutofillDriverFactoryPassKey pass_key);
+ void set_secondary_autofill_manager(
+ std::unique_ptr<AutofillManager> secondary_autofill_manager) {
+ secondary_autofill_manager_ = std::move(secondary_autofill_manager);
+ }
+ raw_ptr<AutofillManager> secondary_autofill_manager() override;
+
content::RenderFrameHost* render_frame_host() { return &*render_frame_host_; }
const content::RenderFrameHost* render_frame_host() const {
return &*render_frame_host_;
@@ -316,6 +322,10 @@ class ContentAutofillDriver : public AutofillDriver,
// The factory that created this driver. Outlives `this`.
const raw_ref<ContentAutofillDriverFactory> owner_;
+ // adds a reference for AndroidAutofillManager, since native autofill works in
+ // conjunction with browser autofill in Bromite
+ 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/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc
--- a/components/autofill/content/browser/content_autofill_driver_factory.cc
+++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -25,6 +25,12 @@
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/common/features.h"
+#if BUILDFLAG(IS_ANDROID)
+#include "components/android_autofill/browser/android_autofill_manager.h"
+#include "components/android_autofill/browser/autofill_provider.h"
+#include "components/android_autofill/browser/android_autofill_provider.h"
+#endif
+
namespace autofill {
class ScopedAutofillManagersObservation;
@@ -134,6 +140,12 @@ ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame(
return nullptr;
}
driver = std::make_unique<ContentAutofillDriver>(render_frame_host, this);
+#if BUILDFLAG(IS_ANDROID)
+ if (!driver->GetAutofillManager().IsAndroidAutofill()) {
+ driver->set_secondary_autofill_manager(
+ base::WrapUnique(new AndroidAutofillManager(driver.get())));
+ }
+#endif
DCHECK_EQ(driver->GetLifecycleState(), LifecycleState::kInactive);
for (auto& observer : observers()) {
observer.OnAutofillDriverCreated(*this, *driver);
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -1551,10 +1551,6 @@ void AutofillAgent::ShowSuggestions(
password_generation_agent_->ShowPasswordGenerationSuggestions(
input_element, form_cache)) {
is_popup_possibly_visible_ = true;
- if (!base::FeatureList::IsEnabled(
- features::kAutofillAndroidKeyboardAccessoryDynamicPositioning)) {
- return;
- }
}
}
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -851,7 +851,10 @@ void PasswordAutofillAgent::UpdatePasswordStateForTextChange(
void PasswordAutofillAgent::TrackAutofilledElement(
const WebFormControlElement& element) {
- autofill_agent_->TrackAutofilledElement(
+ // fix for https://github.com/bromite/bromite/issues/1570
+ AutofillAgent* agent = autofill_agent_.get();
+ if (agent)
+ agent->TrackAutofilledElement(
form_util::GetFieldRendererId(element));
}
diff --git a/components/autofill/core/browser/foundations/autofill_driver.h b/components/autofill/core/browser/foundations/autofill_driver.h
--- a/components/autofill/core/browser/foundations/autofill_driver.h
+++ b/components/autofill/core/browser/foundations/autofill_driver.h
@@ -172,6 +172,8 @@ class AutofillDriver {
// Returns the AutofillManager owned by the AutofillDriver.
virtual AutofillManager& GetAutofillManager() = 0;
+ virtual raw_ptr<AutofillManager> secondary_autofill_manager() = 0;
+
// Gets the UKM source ID associated with this driver's outermost main frame's
// document.
//
diff --git a/components/autofill/core/browser/foundations/autofill_driver_factory.cc b/components/autofill/core/browser/foundations/autofill_driver_factory.cc
--- a/components/autofill/core/browser/foundations/autofill_driver_factory.cc
+++ b/components/autofill/core/browser/foundations/autofill_driver_factory.cc
@@ -25,6 +25,10 @@ void AutofillDriverFactory::SetLifecycleStateAndNotifyObservers(
}
driver.GetAutofillManager().OnAutofillDriverLifecycleStateChanged(
old_state, new_state, /*pass_key=*/{});
+ if (auto secondary = driver.secondary_autofill_manager()) {
+ secondary->OnAutofillDriverLifecycleStateChanged(
+ old_state, new_state, /*pass_key=*/{});
+ }
}
} // namespace autofill
diff --git a/components/autofill/core/browser/foundations/autofill_manager.h b/components/autofill/core/browser/foundations/autofill_manager.h
--- a/components/autofill/core/browser/foundations/autofill_manager.h
+++ b/components/autofill/core/browser/foundations/autofill_manager.h
@@ -249,6 +249,8 @@ class AutofillManager
LifecycleState new_state,
base::PassKey<AutofillDriverFactory> pass_key);
+ virtual bool IsAndroidAutofill() const = 0;
+
AutofillClient& client() { return driver_->GetAutofillClient(); }
const AutofillClient& client() const { return driver_->GetAutofillClient(); }
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
--- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -912,6 +912,8 @@ base::WeakPtr<AutofillManager> BrowserAutofillManager::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
+bool BrowserAutofillManager::IsAndroidAutofill() const { return false; }
+
CreditCardAccessManager* BrowserAutofillManager::GetCreditCardAccessManager() {
if (!credit_card_access_manager_) {
credit_card_access_manager_ =
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.h b/components/autofill/core/browser/foundations/browser_autofill_manager.h
--- a/components/autofill/core/browser/foundations/browser_autofill_manager.h
+++ b/components/autofill/core/browser/foundations/browser_autofill_manager.h
@@ -452,6 +452,8 @@ class BrowserAutofillManager : public AutofillManager {
// latter check is needed because IPC messages can arrive out of order.
void UpdateInitialInteractionTimestamp(base::TimeTicks interaction_timestamp);
+ bool IsAndroidAutofill() const override;
+
// Checks whether JavaScript cleared an autofilled value within
// kLimitBeforeRefill after the filling and records metrics for this. This
// method should be called after we learned that JavaScript modified an
diff --git a/components/autofill/core/common/autofill_prefs.cc b/components/autofill/core/common/autofill_prefs.cc
--- a/components/autofill/core/common/autofill_prefs.cc
+++ b/components/autofill/core/common/autofill_prefs.cc
@@ -89,6 +89,8 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(kAutofillCreditCardFidoAuthOfferCheckboxState,
true);
#endif
+ registry->RegisterBooleanPref(prefs::kAutofillAndroidEnabled, true);
+ registry->RegisterBooleanPref(prefs::kAutofillAndroidIncognitoEnabled, false);
registry->RegisterIntegerPref(kAutocompleteLastVersionRetentionPolicy, 0);
registry->RegisterStringPref(kAutofillUploadEncodingSeed, "");
registry->RegisterDictionaryPref(kAutofillVoteUploadEvents);
@@ -117,7 +119,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
#endif
#if BUILDFLAG(IS_ANDROID)
- registry->RegisterBooleanPref(kAutofillUsingPlatformAutofill, false);
+ registry->RegisterBooleanPref(kAutofillUsingPlatformAutofill, true);
registry->RegisterBooleanPref(kAutofillThirdPartyPasswordManagersAllowed,
true);
registry->RegisterStringPref(
diff --git a/components/autofill/core/common/autofill_prefs.h b/components/autofill/core/common/autofill_prefs.h
--- a/components/autofill/core/common/autofill_prefs.h
+++ b/components/autofill/core/common/autofill_prefs.h
@@ -153,6 +153,11 @@ inline constexpr char kAutofillWasNameAndEmailProfileUsed[] =
// retention policy was run.
inline constexpr char kAutocompleteLastVersionRetentionPolicy[] =
"autocomplete.retention_policy_last_version";
+// Boolean that is true to enable native Android Autofill
+inline constexpr char kAutofillAndroidEnabled[] =
+ "autofill.android_autofill_enabled";
+inline constexpr char kAutofillAndroidIncognitoEnabled[] =
+ "autofill.android_autofill_incognito_enabled";
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \
BUILDFLAG(IS_IOS) || BUILDFLAG(IS_CHROMEOS)
// Boolean that is set when payment methods mandatory re-auth is enabled by the
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -1200,6 +1200,10 @@ void PasswordFormManager::FillNow() {
}
autofills_left_--;
+#if BUILDFLAG(IS_ANDROID)
+ client_->OnFillNow();
+#endif
+
// There are additional signals (server-side data) and parse results in
// filling and saving mode might be different so it is better not to cache
// parse result, but to parse each time again.
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc
--- a/components/password_manager/core/browser/password_manager_client.cc
+++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -39,6 +39,8 @@ bool PasswordManagerClient::IsAutoSignInEnabled() const {
}
#if BUILDFLAG(IS_ANDROID)
+void PasswordManagerClient::OnFillNow() {}
+
void PasswordManagerClient::ShowPasswordManagerErrorMessage(
ErrorMessageFlowType flow_type,
password_manager::PasswordStoreBackendErrorType error_type) {}
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -228,6 +228,8 @@ class PasswordManagerClient {
virtual void ShowKeyboardReplacingSurface(
PasswordManagerDriver* driver,
const autofill::PasswordSuggestionRequest& request);
+
+ virtual void OnFillNow();
#endif
// Checks whether user re-authentication should be triggered before password
--