853 lines
42 KiB
Diff
853 lines
42 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
|
|
---
|
|
android_webview/browser/aw_contents.cc | 1 +
|
|
chrome/android/BUILD.gn | 1 +
|
|
.../settings/PasswordSettings.java | 81 ++++++++++++++++++-
|
|
.../chromium/chrome/browser/tab/TabImpl.java | 50 ++++++++++++
|
|
.../browser/tab/TabViewAndroidDelegate.java | 14 ++++
|
|
chrome/browser/BUILD.gn | 8 ++
|
|
chrome/browser/android/tab_android.cc | 27 +++++++
|
|
chrome/browser/android/tab_android.h | 2 +
|
|
.../tab_web_contents_delegate_android.cc | 3 +-
|
|
.../strings/android_chrome_strings.grd | 6 ++
|
|
chrome/browser/ui/tab_helpers.cc | 8 +-
|
|
.../browser/content_autofill_driver.cc | 50 ++++++++++--
|
|
.../content/browser/content_autofill_driver.h | 8 +-
|
|
.../content_autofill_driver_factory.cc | 9 ++-
|
|
.../browser/content_autofill_driver_factory.h | 4 +
|
|
.../renderer/password_autofill_agent.cc | 5 +-
|
|
.../autofill/core/common/autofill_prefs.cc | 8 ++
|
|
.../autofill/core/common/autofill_prefs.h | 2 +
|
|
.../embedder_support/view/ContentView.java | 46 +++++++++++
|
|
.../chromium/ui/base/ViewAndroidDelegate.java | 8 ++
|
|
weblayer/browser/tab_impl.cc | 3 +-
|
|
21 files changed, 329 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
|
|
--- a/android_webview/browser/aw_contents.cc
|
|
+++ b/android_webview/browser/aw_contents.cc
|
|
@@ -336,6 +336,7 @@ void AwContents::InitAutofillIfNecessary(bool autocomplete_enabled) {
|
|
autofill::AutofillProvider::is_download_manager_disabled_for_testing()
|
|
? autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER
|
|
: autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER,
|
|
+ /*enable_browser_autofill_manager*/ false,
|
|
autofill_provider
|
|
? base::BindRepeating(&autofill::AndroidAutofillManager::Create)
|
|
: autofill::AutofillManager::AutofillManagerFactoryCallback());
|
|
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
|
|
--- a/chrome/android/BUILD.gn
|
|
+++ b/chrome/android/BUILD.gn
|
|
@@ -450,6 +450,7 @@ android_library("chrome_java") {
|
|
"//chrome/browser/xsurface:java",
|
|
"//components/autofill/android:autofill_java",
|
|
"//components/autofill_assistant/browser:proto_java",
|
|
+ "//components/android_autofill/browser:java",
|
|
"//components/background_task_scheduler:background_task_scheduler_java",
|
|
"//components/background_task_scheduler:background_task_scheduler_task_ids_java",
|
|
"//components/bookmarks/common/android:bookmarks_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
|
|
@@ -54,13 +54,18 @@ import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.Locale;
|
|
|
|
+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.ApplicationLifetime;
|
|
+
|
|
/**
|
|
* The "Passwords" screen in Settings, which allows the user to enable or disable password saving,
|
|
* to view saved passwords (just the username and URL), and to delete saved passwords.
|
|
*/
|
|
public class PasswordSettings extends PreferenceFragmentCompat
|
|
implements PasswordManagerHandler.PasswordListObserver,
|
|
- Preference.OnPreferenceClickListener {
|
|
+ Preference.OnPreferenceClickListener, INeedSnackbarManager {
|
|
@IntDef({TrustedVaultBannerState.NOT_SHOWN, TrustedVaultBannerState.OFFER_OPT_IN,
|
|
TrustedVaultBannerState.OPTED_IN})
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@@ -87,6 +92,12 @@ public class PasswordSettings extends PreferenceFragmentCompat
|
|
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 SnackbarManager mSnackbarManager;
|
|
+ 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";
|
|
@@ -116,6 +127,8 @@ public class PasswordSettings extends PreferenceFragmentCompat
|
|
private String mSearchQuery;
|
|
private Preference mLinkPref;
|
|
private ChromeSwitchPreference mSavePasswordsSwitch;
|
|
+ private ChromeSwitchPreference mEnableAndroidAutofillSwitch;
|
|
+ private ChromeSwitchPreference mEnableAndroidAutofillIncognitoSwitch;
|
|
private ChromeSwitchPreference mAutoSignInSwitch;
|
|
private ChromeBasePreference mCheckPasswords;
|
|
private ChromeBasePreference mTrustedVaultBanner;
|
|
@@ -287,6 +300,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
|
|
}
|
|
|
|
createSavePasswordsSwitch();
|
|
+ createEnableAndroidAutofillSwitch();
|
|
createAutoSignInCheckbox();
|
|
if (mPasswordCheck != null) {
|
|
createCheckPasswords();
|
|
@@ -522,6 +536,71 @@ public class PasswordSettings extends PreferenceFragmentCompat
|
|
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)
|
|
+ .setSingleLine(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 (!mSnackbarManager.isShowing())
|
|
+ mSnackbarManager.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 (!mSnackbarManager.isShowing())
|
|
+ mSnackbarManager.showSnackbar(mSnackbar);
|
|
+ return true;
|
|
+ });
|
|
+ }
|
|
+
|
|
+ public void setSnackbarManager(SnackbarManager manager) {
|
|
+ mSnackbarManager = manager;
|
|
+ }
|
|
+
|
|
private void createAutoSignInCheckbox() {
|
|
mAutoSignInSwitch = new ChromeSwitchPreference(getStyledContext(), null);
|
|
mAutoSignInSwitch.setKey(PREF_AUTOSIGNIN_SWITCH);
|
|
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
|
|
@@ -74,6 +74,17 @@ import org.chromium.ui.base.WindowAndroid;
|
|
import org.chromium.ui.util.ColorUtils;
|
|
import org.chromium.url.GURL;
|
|
|
|
+import android.os.Build;
|
|
+import android.util.SparseArray;
|
|
+import org.chromium.ui.base.EventOffsetHandler;
|
|
+import android.view.ViewStructure;
|
|
+import android.view.autofill.AutofillValue;
|
|
+import org.chromium.components.autofill.AutofillProvider;
|
|
+import org.chromium.components.autofill.AutofillActionModeCallback;
|
|
+import org.chromium.content_public.browser.SelectionPopupController;
|
|
+import org.chromium.chrome.browser.preferences.Pref;
|
|
+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.
|
|
@@ -211,6 +222,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
|
|
private int mThemeColor;
|
|
private boolean mUsedCriticalPersistedTabData;
|
|
|
|
+ AutofillProvider mAutofillProvider;
|
|
+
|
|
/**
|
|
* Creates an instance of a {@link TabImpl}.
|
|
*
|
|
@@ -765,6 +778,11 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
|
|
for (TabObserver observer : mObservers) observer.onDestroyed(this);
|
|
mObservers.clear();
|
|
|
|
+ if (mAutofillProvider != null) {
|
|
+ mAutofillProvider.destroy();
|
|
+ mAutofillProvider = null;
|
|
+ }
|
|
+
|
|
mUserDataHost.destroy();
|
|
mTabViewManager.destroy();
|
|
hideNativePage(false, null);
|
|
@@ -1342,6 +1360,16 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
|
|
return tabsPtrArray;
|
|
}
|
|
|
|
+ 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.
|
|
@@ -1391,6 +1419,27 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
|
|
mDelegateFactory.createContextMenuPopulatorFactory(this), this));
|
|
|
|
mWebContents.notifyRendererPreferenceUpdate();
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
+ boolean autofillEnabled = false;
|
|
+ if (isIncognito()) {
|
|
+ autofillEnabled = UserPrefs.get(Profile.getLastUsedRegularProfile())
|
|
+ .getBoolean(Pref.AUTOFILL_ANDROID_INCOGNITO_ENABLED);
|
|
+ } else {
|
|
+ autofillEnabled = UserPrefs.get(Profile.getLastUsedRegularProfile())
|
|
+ .getBoolean(Pref.AUTOFILL_ANDROID_ENABLED);
|
|
+ }
|
|
+
|
|
+ if (autofillEnabled) {
|
|
+ SelectionPopupController selectionController =
|
|
+ SelectionPopupController.fromWebContents(mWebContents);
|
|
+ mAutofillProvider = new AutofillProvider(getContext(), cv, webContents, "bromite");
|
|
+ TabImplJni.get().initializeAutofillIfNecessary(mNativeTabAndroid);
|
|
+ mAutofillProvider.setWebContents(webContents);
|
|
+ cv.setWebContents(webContents);
|
|
+ selectionController.setNonSelectionActionModeCallback(
|
|
+ new AutofillActionModeCallback(mThemedApplicationContext, mAutofillProvider));
|
|
+ }
|
|
+ }
|
|
TabHelpers.initWebContentsHelpers(this);
|
|
notifyContentChanged();
|
|
} finally {
|
|
@@ -1775,5 +1824,6 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
|
|
void setActiveNavigationEntryTitleForUrl(long nativeTabAndroid, String url, String title);
|
|
void loadOriginalImage(long nativeTabAndroid);
|
|
boolean handleNonNavigationAboutURL(GURL url);
|
|
+ void initializeAutofillIfNecessary(long nativeTabAndroid);
|
|
}
|
|
}
|
|
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
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java
|
|
@@ -19,6 +19,10 @@ import org.chromium.ui.base.DropDataContentProvider;
|
|
import org.chromium.ui.base.ViewAndroidDelegate;
|
|
import org.chromium.ui.base.WindowAndroid;
|
|
|
|
+import android.util.SparseArray;
|
|
+import android.view.autofill.AutofillValue;
|
|
+import android.view.ViewStructure;
|
|
+
|
|
/**
|
|
* Implementation of the abstract class {@link ViewAndroidDelegate} for Chrome.
|
|
*/
|
|
@@ -149,4 +153,14 @@ public class TabViewAndroidDelegate extends ViewAndroidDelegate {
|
|
getContentView().removeOnDragListener(getDragStateTrackerInternal());
|
|
}
|
|
}
|
|
+
|
|
+ @Override
|
|
+ public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
|
|
+ mTab.onProvideAutofillVirtualStructure(structure, flags);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void autofill(final SparseArray<AutofillValue> values) {
|
|
+ mTab.autofill(values);
|
|
+ }
|
|
}
|
|
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
|
--- a/chrome/browser/BUILD.gn
|
|
+++ b/chrome/browser/BUILD.gn
|
|
@@ -2373,6 +2373,14 @@ static_library("browser") {
|
|
"//ui/webui/resources/cr_components/most_visited:mojom",
|
|
"//ui/webui/resources/js/browser_command:mojo_bindings",
|
|
]
|
|
+
|
|
+ if (is_android) {
|
|
+ deps += [
|
|
+ "//components/android_autofill/browser",
|
|
+ "//components/android_autofill/browser:android"
|
|
+ ]
|
|
+ }
|
|
+
|
|
if (is_chromeos_ash) {
|
|
sources += [
|
|
"apps/digital_goods/digital_goods_factory_impl.cc",
|
|
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
|
|
@@ -66,6 +66,13 @@
|
|
#include "url/android/gurl_android.h"
|
|
#include "url/gurl.h"
|
|
|
|
+#include "components/android_autofill/browser/android_autofill_manager.h"
|
|
+#include "components/android_autofill/browser/autofill_provider.h"
|
|
+#include "components/android_autofill/browser/autofill_provider_android.h"
|
|
+#include "components/autofill/content/browser/content_autofill_driver_factory.h"
|
|
+#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
|
|
+#include "chrome/browser/browser_process.h"
|
|
+
|
|
using base::android::AttachCurrentThread;
|
|
using base::android::ConvertUTF8ToJavaString;
|
|
using base::android::JavaParamRef;
|
|
@@ -444,3 +451,23 @@ static void JNI_TabImpl_Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
|
|
// This will automatically bind to the Java object and pass ownership there.
|
|
new TabAndroid(env, obj);
|
|
}
|
|
+
|
|
+void TabAndroid::InitializeAutofillIfNecessary(JNIEnv* env) {
|
|
+ if (!autofill::ContentAutofillDriverFactory::FromWebContents(
|
|
+ web_contents_.get())) {
|
|
+ content::WebContents* web_contents = web_contents_.get();
|
|
+ DCHECK(
|
|
+ !autofill::ContentAutofillDriverFactory::FromWebContents(web_contents));
|
|
+ DCHECK(autofill::AutofillProvider::FromWebContents(web_contents));
|
|
+
|
|
+ autofill::ChromeAutofillClient::CreateForWebContents(web_contents);
|
|
+
|
|
+ autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
|
|
+ web_contents,
|
|
+ autofill::ChromeAutofillClient::FromWebContents(web_contents),
|
|
+ g_browser_process->GetApplicationLocale(),
|
|
+ autofill::BrowserAutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER,
|
|
+ /*enable_browser_autofill_manager*/ true,
|
|
+ base::BindRepeating(&autofill::AndroidAutofillManager::Create));
|
|
+ }
|
|
+}
|
|
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
|
|
--- a/chrome/browser/android/tab_android.h
|
|
+++ b/chrome/browser/android/tab_android.h
|
|
@@ -154,6 +154,8 @@ class TabAndroid : public base::SupportsUserData {
|
|
|
|
void SetDevToolsAgentHost(scoped_refptr<content::DevToolsAgentHost> host);
|
|
|
|
+ void InitializeAutofillIfNecessary(JNIEnv* env);
|
|
+
|
|
private:
|
|
JavaObjectWeakGlobalRef weak_java_tab_;
|
|
|
|
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc
|
|
--- a/chrome/browser/android/tab_web_contents_delegate_android.cc
|
|
+++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
|
|
@@ -174,7 +174,8 @@ void TabWebContentsDelegateAndroid::PortalWebContentsCreated(
|
|
portal_contents,
|
|
autofill::ChromeAutofillClient::FromWebContents(portal_contents),
|
|
g_browser_process->GetApplicationLocale(),
|
|
- autofill::BrowserAutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER);
|
|
+ autofill::BrowserAutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER,
|
|
+ /*enable_browser_autofill_manager*/ true);
|
|
ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
|
|
portal_contents,
|
|
autofill::ChromeAutofillClient::FromWebContents(portal_contents));
|
|
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
|
|
@@ -639,6 +639,12 @@ CHAR_LIMIT guidelines:
|
|
<message name="IDS_PASSWORD_SETTINGS_SAVE_PASSWORDS" desc="Title for the checkbox toggling whether passwords are saved or not. [CHAR_LIMIT=32]">
|
|
Save passwords
|
|
</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_PASSWORDS_AUTO_SIGNIN_TITLE" desc="Title for checkbox to enable automatically signing the user in to websites">
|
|
Auto Sign-in
|
|
</message>
|
|
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
|
|
@@ -153,6 +153,9 @@
|
|
#include "chrome/browser/ui/javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_android.h"
|
|
#include "chrome/browser/video_tutorials/video_tutorial_tab_helper.h"
|
|
#include "content/public/common/content_features.h"
|
|
+#include "components/android_autofill/browser/android_autofill_manager.h"
|
|
+#include "components/android_autofill/browser/autofill_provider.h"
|
|
+#include "components/android_autofill/browser/autofill_provider_android.h"
|
|
#else
|
|
#include "chrome/browser/accuracy_tips/accuracy_service_factory.h"
|
|
#include "chrome/browser/banners/app_banner_manager_desktop.h"
|
|
@@ -291,7 +294,10 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) {
|
|
web_contents,
|
|
autofill::ChromeAutofillClient::FromWebContents(web_contents),
|
|
g_browser_process->GetApplicationLocale(),
|
|
- autofill::BrowserAutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER);
|
|
+ autofill::BrowserAutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER,
|
|
+ /*enable_browser_autofill_manager*/ true,
|
|
+ base::BindRepeating(&autofill::AndroidAutofillManager::Create));
|
|
+
|
|
if (BreadcrumbsStatus::IsEnabled())
|
|
BreadcrumbManagerTabHelper::CreateForWebContents(web_contents);
|
|
chrome_browser_net::NetErrorTabHelper::CreateForWebContents(web_contents);
|
|
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
|
|
@@ -68,6 +68,7 @@ ContentAutofillDriver::ContentAutofillDriver(
|
|
const std::string& app_locale,
|
|
ContentAutofillRouter* autofill_router,
|
|
AutofillManager::AutofillDownloadManagerState enable_download_manager,
|
|
+ bool enable_browser_autofill_manager,
|
|
AutofillManager::AutofillManagerFactoryCallback
|
|
autofill_manager_factory_callback)
|
|
: render_frame_host_(render_frame_host),
|
|
@@ -83,9 +84,11 @@ ContentAutofillDriver::ContentAutofillDriver(
|
|
GetAutofillAgent()->SetSecureContextRequired(true);
|
|
GetAutofillAgent()->SetFocusRequiresScroll(false);
|
|
GetAutofillAgent()->SetQueryPasswordSuggestion(true);
|
|
- } else {
|
|
+ }
|
|
+ if (!autofill_manager_factory_callback || enable_browser_autofill_manager) {
|
|
SetBrowserAutofillManager(std::make_unique<BrowserAutofillManager>(
|
|
- this, client, app_locale, enable_download_manager));
|
|
+ this, client, app_locale, enable_download_manager),
|
|
+ enable_browser_autofill_manager);
|
|
}
|
|
if (client && ShouldEnableHeavyFormDataScraping(client->GetChannel())) {
|
|
GetAutofillAgent()->EnableHeavyFormDataScraping();
|
|
@@ -344,6 +347,8 @@ void ContentAutofillDriver::FormsSeenImpl(
|
|
const std::vector<FormData>& updated_forms,
|
|
const std::vector<FormGlobalId>& removed_forms) {
|
|
autofill_manager_->OnFormsSeen(updated_forms, removed_forms);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnFormsSeen(updated_forms, removed_forms);
|
|
}
|
|
|
|
void ContentAutofillDriver::SetFormToBeProbablySubmittedImpl(
|
|
@@ -366,6 +371,8 @@ void ContentAutofillDriver::FormSubmittedImpl(const FormData& form,
|
|
}
|
|
|
|
autofill_manager_->OnFormSubmitted(form, known_success, source);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnFormSubmitted(form, known_success, source);
|
|
}
|
|
|
|
void ContentAutofillDriver::TextFieldDidChangeImpl(
|
|
@@ -374,6 +381,8 @@ void ContentAutofillDriver::TextFieldDidChangeImpl(
|
|
const gfx::RectF& bounding_box,
|
|
base::TimeTicks timestamp) {
|
|
autofill_manager_->OnTextFieldDidChange(form, field, bounding_box, timestamp);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnTextFieldDidChange(form, field, bounding_box, timestamp);
|
|
}
|
|
|
|
void ContentAutofillDriver::TextFieldDidScrollImpl(
|
|
@@ -381,6 +390,8 @@ void ContentAutofillDriver::TextFieldDidScrollImpl(
|
|
const FormFieldData& field,
|
|
const gfx::RectF& bounding_box) {
|
|
autofill_manager_->OnTextFieldDidScroll(form, field, bounding_box);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnTextFieldDidScroll(form, field, bounding_box);
|
|
}
|
|
|
|
void ContentAutofillDriver::SelectControlDidChangeImpl(
|
|
@@ -388,6 +399,8 @@ void ContentAutofillDriver::SelectControlDidChangeImpl(
|
|
const FormFieldData& field,
|
|
const gfx::RectF& bounding_box) {
|
|
autofill_manager_->OnSelectControlDidChange(form, field, bounding_box);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnSelectControlDidChange(form, field, bounding_box);
|
|
}
|
|
|
|
void ContentAutofillDriver::AskForValuesToFillImpl(
|
|
@@ -398,15 +411,22 @@ void ContentAutofillDriver::AskForValuesToFillImpl(
|
|
bool autoselect_first_suggestion) {
|
|
autofill_manager_->OnAskForValuesToFill(id, form, field, bounding_box,
|
|
autoselect_first_suggestion);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnAskForValuesToFill(id, form, field, bounding_box,
|
|
+ autoselect_first_suggestion);
|
|
}
|
|
|
|
void ContentAutofillDriver::HidePopupImpl() {
|
|
DCHECK(!IsPrerendering()) << "We should never affect UI while prerendering";
|
|
autofill_manager_->OnHidePopup();
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnHidePopup();
|
|
}
|
|
|
|
void ContentAutofillDriver::FocusNoLongerOnFormImpl(bool had_interacted_form) {
|
|
autofill_manager_->OnFocusNoLongerOnForm(had_interacted_form);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnFocusNoLongerOnForm(had_interacted_form);
|
|
}
|
|
|
|
void ContentAutofillDriver::FocusOnFormFieldImpl(
|
|
@@ -414,25 +434,35 @@ void ContentAutofillDriver::FocusOnFormFieldImpl(
|
|
const FormFieldData& field,
|
|
const gfx::RectF& bounding_box) {
|
|
autofill_manager_->OnFocusOnFormField(form, field, bounding_box);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnFocusOnFormField(form, field, bounding_box);
|
|
}
|
|
|
|
void ContentAutofillDriver::DidFillAutofillFormDataImpl(
|
|
const FormData& form,
|
|
base::TimeTicks timestamp) {
|
|
autofill_manager_->OnDidFillAutofillFormData(form, timestamp);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnDidFillAutofillFormData(form, timestamp);
|
|
}
|
|
|
|
void ContentAutofillDriver::DidPreviewAutofillFormDataImpl() {
|
|
autofill_manager_->OnDidPreviewAutofillFormData();
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnDidPreviewAutofillFormData();
|
|
}
|
|
|
|
void ContentAutofillDriver::DidEndTextFieldEditingImpl() {
|
|
autofill_manager_->OnDidEndTextFieldEditing();
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->OnDidEndTextFieldEditing();
|
|
}
|
|
|
|
void ContentAutofillDriver::SelectFieldOptionsDidChangeImpl(
|
|
const FormData& form) {
|
|
autofill_manager_->SelectFieldOptionsDidChange(form);
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->SelectFieldOptionsDidChange(form);
|
|
}
|
|
|
|
void ContentAutofillDriver::FillFormForAssistantImpl(
|
|
@@ -653,13 +683,21 @@ void ContentAutofillDriver::DidNavigateFrame(
|
|
if (autofill_router_) // Can be nullptr only in tests.
|
|
autofill_router_->UnregisterDriver(this);
|
|
autofill_manager_->Reset();
|
|
+ if (browser_autofill_manager_ptr_)
|
|
+ browser_autofill_manager_->Reset();
|
|
}
|
|
|
|
void ContentAutofillDriver::SetBrowserAutofillManager(
|
|
- std::unique_ptr<BrowserAutofillManager> manager) {
|
|
- autofill_manager_ = std::move(manager);
|
|
- browser_autofill_manager_ =
|
|
- static_cast<BrowserAutofillManager*>(autofill_manager_.get());
|
|
+ std::unique_ptr<BrowserAutofillManager> manager,
|
|
+ bool enable_browser_autofill_manager) {
|
|
+ if (enable_browser_autofill_manager) {
|
|
+ browser_autofill_manager_ptr_ = std::move(manager);
|
|
+ browser_autofill_manager_ = browser_autofill_manager_ptr_.get();
|
|
+ } else {
|
|
+ autofill_manager_ = std::move(manager);
|
|
+ browser_autofill_manager_ =
|
|
+ static_cast<BrowserAutofillManager*>(autofill_manager_.get());
|
|
+ }
|
|
}
|
|
|
|
ContentAutofillDriver::ContentAutofillDriver(content::RenderFrameHost* rfh)
|
|
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
|
|
@@ -138,6 +138,7 @@ class ContentAutofillDriver : public AutofillDriver,
|
|
const std::string& app_locale,
|
|
ContentAutofillRouter* autofill_router,
|
|
AutofillManager::AutofillDownloadManagerState enable_download_manager,
|
|
+ bool enable_browser_autofill_manager,
|
|
AutofillManager::AutofillManagerFactoryCallback
|
|
autofill_manager_factory_callback);
|
|
ContentAutofillDriver(const ContentAutofillDriver&) = delete;
|
|
@@ -361,7 +362,8 @@ class ContentAutofillDriver : public AutofillDriver,
|
|
|
|
// Sets the manager to |manager|. Takes ownership of |manager|.
|
|
void SetBrowserAutofillManager(
|
|
- std::unique_ptr<BrowserAutofillManager> manager);
|
|
+ std::unique_ptr<BrowserAutofillManager> manager,
|
|
+ bool enable_browser_autofill_manager);
|
|
|
|
// Reports whether a document collects phone numbers, uses one time code, uses
|
|
// WebOTP. There are cases that the reporting is not expected:
|
|
@@ -426,6 +428,10 @@ class ContentAutofillDriver : public AutofillDriver,
|
|
// pointer to a common root.
|
|
raw_ptr<BrowserAutofillManager> browser_autofill_manager_;
|
|
|
|
+ // adds a reference for BrowserAutofillManager, since native autofill works in
|
|
+ // conjunction with browser autofill in Bromite
|
|
+ std::unique_ptr<BrowserAutofillManager> browser_autofill_manager_ptr_;
|
|
+
|
|
// Pointer to an implementation of InternalAuthenticator.
|
|
std::unique_ptr<webauthn::InternalAuthenticator> authenticator_impl_;
|
|
|
|
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
|
|
@@ -32,6 +32,7 @@ void ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
|
|
const std::string& app_locale,
|
|
BrowserAutofillManager::AutofillDownloadManagerState
|
|
enable_download_manager,
|
|
+ bool enable_browser_autofill_manager,
|
|
AutofillManager::AutofillManagerFactoryCallback
|
|
autofill_manager_factory_callback) {
|
|
if (FromWebContents(contents))
|
|
@@ -40,7 +41,7 @@ void ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
|
|
contents->SetUserData(
|
|
kContentAutofillDriverFactoryWebContentsUserDataKey,
|
|
base::WrapUnique(new ContentAutofillDriverFactory(
|
|
- contents, client, app_locale, enable_download_manager,
|
|
+ contents, client, app_locale, enable_download_manager, enable_browser_autofill_manager,
|
|
std::move(autofill_manager_factory_callback))));
|
|
}
|
|
|
|
@@ -78,6 +79,7 @@ ContentAutofillDriverFactory::ContentAutofillDriverFactory(
|
|
const std::string& app_locale,
|
|
BrowserAutofillManager::AutofillDownloadManagerState
|
|
enable_download_manager,
|
|
+ bool enable_browser_autofill_manager,
|
|
AutofillManager::AutofillManagerFactoryCallback
|
|
autofill_manager_factory_callback)
|
|
: content::WebContentsObserver(web_contents),
|
|
@@ -85,7 +87,8 @@ ContentAutofillDriverFactory::ContentAutofillDriverFactory(
|
|
app_locale_(app_locale),
|
|
enable_download_manager_(enable_download_manager),
|
|
autofill_manager_factory_callback_(
|
|
- std::move(autofill_manager_factory_callback)) {}
|
|
+ std::move(autofill_manager_factory_callback)),
|
|
+ enable_browser_autofill_manager_(enable_browser_autofill_manager) {}
|
|
|
|
ContentAutofillDriverFactory::~ContentAutofillDriverFactory() = default;
|
|
|
|
@@ -111,7 +114,7 @@ ContentAutofillDriver* ContentAutofillDriverFactory::DriverForFrame(
|
|
if (render_frame_host->IsRenderFrameCreated()) {
|
|
driver = std::make_unique<ContentAutofillDriver>(
|
|
render_frame_host, client(), app_locale_, &router_,
|
|
- enable_download_manager_, autofill_manager_factory_callback_);
|
|
+ enable_download_manager_, enable_browser_autofill_manager_, autofill_manager_factory_callback_);
|
|
DCHECK_EQ(driver_map_.find(render_frame_host)->second.get(),
|
|
driver.get());
|
|
} else {
|
|
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.h b/components/autofill/content/browser/content_autofill_driver_factory.h
|
|
--- a/components/autofill/content/browser/content_autofill_driver_factory.h
|
|
+++ b/components/autofill/content/browser/content_autofill_driver_factory.h
|
|
@@ -45,6 +45,7 @@ class ContentAutofillDriverFactory : public content::WebContentsObserver,
|
|
const std::string& app_locale,
|
|
BrowserAutofillManager::AutofillDownloadManagerState
|
|
enable_download_manager,
|
|
+ bool enable_browser_autofill_manager,
|
|
AutofillManager::AutofillManagerFactoryCallback
|
|
autofill_manager_factory_callback = {});
|
|
|
|
@@ -84,6 +85,7 @@ class ContentAutofillDriverFactory : public content::WebContentsObserver,
|
|
const std::string& app_locale,
|
|
BrowserAutofillManager::AutofillDownloadManagerState
|
|
enable_download_manager,
|
|
+ bool enable_browser_autofill_manager,
|
|
AutofillManager::AutofillManagerFactoryCallback
|
|
autofill_manager_factory_callback);
|
|
|
|
@@ -97,6 +99,8 @@ class ContentAutofillDriverFactory : public content::WebContentsObserver,
|
|
// Must be destroyed after |driver_map_|'s elements.
|
|
ContentAutofillRouter router_;
|
|
|
|
+ bool enable_browser_autofill_manager_;
|
|
+
|
|
// The list of drivers, one for each frame in the WebContents.
|
|
// Should be empty at destruction time because its elements are erased in
|
|
// RenderFrameDeleted(). In case it is not empty, is must be destroyed before
|
|
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
|
|
@@ -724,7 +724,10 @@ void PasswordAutofillAgent::UpdateStateForTextChange(
|
|
|
|
void PasswordAutofillAgent::TrackAutofilledElement(
|
|
const blink::WebFormControlElement& element) {
|
|
- autofill_agent_->TrackAutofilledElement(element);
|
|
+ // fix for https://github.com/bromite/bromite/issues/1570
|
|
+ AutofillAgent* agent = autofill_agent_.get();
|
|
+ if (agent)
|
|
+ agent->TrackAutofilledElement(element);
|
|
}
|
|
|
|
bool PasswordAutofillAgent::FillSuggestion(
|
|
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
|
|
@@ -128,6 +128,10 @@ const char kAutofillWalletImportStorageCheckboxState[] =
|
|
const char kAutocompleteLastVersionRetentionPolicy[] =
|
|
"autocomplete.retention_policy_last_version";
|
|
|
|
+// Boolean that is true to enable native Android Autofill
|
|
+const char kAutofillAndroidEnabled[] = "autofill.android_autofill_enabled";
|
|
+const char kAutofillAndroidIncognitoEnabled[] = "autofill.android_autofill_incognito_enabled";
|
|
+
|
|
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
|
|
// Synced prefs. Used for cross-device choices, e.g., credit card Autofill.
|
|
registry->RegisterBooleanPref(
|
|
@@ -160,6 +164,10 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
|
|
registry->RegisterBooleanPref(
|
|
prefs::kAutofillCreditCardFidoAuthOfferCheckboxState, true);
|
|
#endif
|
|
+ registry->RegisterBooleanPref(
|
|
+ prefs::kAutofillAndroidEnabled, true);
|
|
+ registry->RegisterBooleanPref(
|
|
+ prefs::kAutofillAndroidIncognitoEnabled, false);
|
|
registry->RegisterIntegerPref(
|
|
prefs::kAutofillCreditCardSigninPromoImpressionCount, 0);
|
|
registry->RegisterBooleanPref(prefs::kAutofillWalletImportEnabled, true);
|
|
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
|
|
@@ -47,6 +47,8 @@ extern const char kAutofillUploadEventsLastResetTimestamp[];
|
|
extern const char kAutofillWalletImportEnabled[];
|
|
extern const char kAutofillWalletImportStorageCheckboxState[];
|
|
extern const char kAutocompleteLastVersionRetentionPolicy[];
|
|
+extern const char kAutofillAndroidEnabled[];
|
|
+extern const char kAutofillAndroidIncognitoEnabled[];
|
|
|
|
namespace sync_transport_opt_in {
|
|
enum Flags {
|
|
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
|
|
--- 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
|
|
@@ -37,6 +37,11 @@ import org.chromium.content_public.browser.WebContentsAccessibility;
|
|
import org.chromium.ui.base.EventForwarder;
|
|
import org.chromium.ui.base.EventOffsetHandler;
|
|
|
|
+import org.chromium.base.Log;
|
|
+import android.util.SparseArray;
|
|
+import android.view.autofill.AutofillValue;
|
|
+import org.chromium.ui.base.ViewAndroidDelegate;
|
|
+
|
|
/**
|
|
* The containing view for {@link WebContents} that exists in the Android UI hierarchy and exposes
|
|
* the various {@link View} functionality to it.
|
|
@@ -84,6 +89,8 @@ 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);
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
return new ContentViewApi23(context, eventOffsetHandler, webContents);
|
|
}
|
|
@@ -585,4 +592,43 @@ public class ContentView extends FrameLayout
|
|
if (wcax != null) wcax.onProvideVirtualStructure(structure, false);
|
|
}
|
|
}
|
|
+
|
|
+ /**
|
|
+ * API level 26 implementation that includes autofill.
|
|
+ */
|
|
+ public static class ContentViewWithAutofill extends ContentViewApi23 {
|
|
+ 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
|
|
--- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
|
|
+++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
|
|
@@ -27,6 +27,10 @@ import org.chromium.base.annotations.JNINamespace;
|
|
import org.chromium.base.compat.ApiHelperForN;
|
|
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.
|
|
*/
|
|
@@ -526,4 +530,8 @@ public class ViewAndroidDelegate {
|
|
public static void setDragAndDropDelegateForTest(DragAndDropDelegate testDelegate) {
|
|
sDragAndDropTestDelegate = testDelegate;
|
|
}
|
|
+
|
|
+ public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {}
|
|
+
|
|
+ public void autofill(final SparseArray<AutofillValue> values) {}
|
|
}
|
|
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc
|
|
--- a/weblayer/browser/tab_impl.cc
|
|
+++ b/weblayer/browser/tab_impl.cc
|
|
@@ -1393,7 +1393,8 @@ void TabImpl::InitializeAutofillDriver() {
|
|
autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
|
|
web_contents, AutofillClientImpl::FromWebContents(web_contents),
|
|
i18n::GetApplicationLocale(), enable_autofill_download_manager,
|
|
- base::BindRepeating(&autofill::AndroidAutofillManager::Create));
|
|
+ base::BindRepeating(&autofill::AndroidAutofillManager::Create),
|
|
+ /*enable_browser_autofill_manager*/ false);
|
|
}
|
|
|
|
#endif // BUILDFLAG(IS_ANDROID)
|
|
--
|
|
2.25.1
|