summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/android
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/autofill/android')
-rw-r--r--chromium/components/autofill/android/BUILD.gn47
-rw-r--r--chromium/components/autofill/android/OWNERS6
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProvider.java157
-rw-r--r--chromium/components/autofill/android/provider/BUILD.gn53
-rw-r--r--chromium/components/autofill/android/provider/OWNERS (renamed from chromium/components/autofill/android/junit/OWNERS)0
-rw-r--r--chromium/components/autofill/android/provider/autofill_provider_android.cc (renamed from chromium/components/autofill/android/autofill_provider_android.cc)61
-rw-r--r--chromium/components/autofill/android/provider/autofill_provider_android.h (renamed from chromium/components/autofill/android/autofill_provider_android.h)16
-rw-r--r--chromium/components/autofill/android/provider/form_data_android.cc (renamed from chromium/components/autofill/android/form_data_android.cc)6
-rw-r--r--chromium/components/autofill/android/provider/form_data_android.h (renamed from chromium/components/autofill/android/form_data_android.h)6
-rw-r--r--chromium/components/autofill/android/provider/form_field_data_android.cc (renamed from chromium/components/autofill/android/form_field_data_android.cc)11
-rw-r--r--chromium/components/autofill/android/provider/form_field_data_android.h (renamed from chromium/components/autofill/android/form_field_data_android.h)6
-rw-r--r--chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java (renamed from chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java)0
-rw-r--r--chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java (renamed from chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java)0
-rw-r--r--chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java (renamed from chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderImpl.java)340
-rw-r--r--chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java (renamed from chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java)0
-rw-r--r--chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormData.java (renamed from chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java)0
-rw-r--r--chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java (renamed from chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java)20
-rw-r--r--chromium/components/autofill/android/provider/junit/BUILD.gn (renamed from chromium/components/autofill/android/junit/BUILD.gn)8
-rw-r--r--chromium/components/autofill/android/provider/junit/src/org/chromium/components/autofill/AutofillProviderTest.java (renamed from chromium/components/autofill/android/junit/src/org/chromium/components/autofill/AutofillProviderImplTest.java)13
19 files changed, 462 insertions, 288 deletions
diff --git a/chromium/components/autofill/android/BUILD.gn b/chromium/components/autofill/android/BUILD.gn
index f246baeb159..e29c613e982 100644
--- a/chromium/components/autofill/android/BUILD.gn
+++ b/chromium/components/autofill/android/BUILD.gn
@@ -41,6 +41,7 @@ android_library("autofill_java") {
"//base:base_java",
"//content/public/android:content_java",
"//third_party/android_deps:android_support_v7_appcompat_java",
+ "//third_party/android_deps:androidx_appcompat_appcompat_resources_java",
"//ui/android:ui_java",
]
sources = [
@@ -54,49 +55,3 @@ android_library("autofill_java") {
]
srcjar_deps = [ ":autofill_core_browser_java_enums" ]
}
-
-android_library("provider_java") {
- deps = [
- "//base:base_java",
- "//base:jni_java",
- "//components/autofill/core/common/mojom:mojo_types_java",
- "//components/version_info/android:version_constants_java",
- "//content/public/android:content_java",
- "//third_party/android_deps:androidx_annotation_annotation_java",
- "//ui/android:ui_java",
- ]
- annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
- sources = [
- "java/src/org/chromium/components/autofill/AutofillActionModeCallback.java",
- "java/src/org/chromium/components/autofill/AutofillManagerWrapper.java",
- "java/src/org/chromium/components/autofill/AutofillProvider.java",
- "java/src/org/chromium/components/autofill/AutofillProviderImpl.java",
- "java/src/org/chromium/components/autofill/AutofillProviderUMA.java",
- "java/src/org/chromium/components/autofill/FormData.java",
- "java/src/org/chromium/components/autofill/FormFieldData.java",
- ]
-}
-
-generate_jni("jni_headers") {
- sources = [
- "java/src/org/chromium/components/autofill/AutofillProvider.java",
- "java/src/org/chromium/components/autofill/FormData.java",
- "java/src/org/chromium/components/autofill/FormFieldData.java",
- ]
-}
-
-static_library("provider") {
- sources = [
- "autofill_provider_android.cc",
- "autofill_provider_android.h",
- "form_data_android.cc",
- "form_data_android.h",
- "form_field_data_android.cc",
- "form_field_data_android.h",
- ]
- deps = [
- ":jni_headers",
- "//components/autofill/core/browser:browser",
- "//content/public/browser",
- ]
-}
diff --git a/chromium/components/autofill/android/OWNERS b/chromium/components/autofill/android/OWNERS
index 7f956d082c5..475b1659fb0 100644
--- a/chromium/components/autofill/android/OWNERS
+++ b/chromium/components/autofill/android/OWNERS
@@ -1,8 +1,2 @@
file://ui/android/OWNERS
-# Files related to integration with system autofill
-per-file *autofill_provider*=michaelbai@chromium.org
-per-file *AutofillProvider*=michaelbai@chromium.org
-per-file *AutofillManagerWrapper*=michaelbai@chromium.org
-per-file *form*=michaelbai@chromium.org
-per-file *Form*=michaelbai@chromium.org
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProvider.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProvider.java
deleted file mode 100644
index a7d05d359a4..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProvider.java
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// 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.util.SparseArray;
-import android.view.ViewGroup;
-import android.view.ViewStructure;
-import android.view.autofill.AutofillValue;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.content_public.browser.WebContents;
-
-/**
- * This class defines interface of AutofillProvider, it doesn't use chrome's
- * autofill service or suggestion UI, instead, uses third party autofill service
- * by knowing of format structure and user's input.
- *
- * AutofillProvider handles one autofill session at time, each call of
- * queryFormFieldAutofill cancels previous session and starts a new one, the
- * calling of other methods shall associate with current session.
- *
- */
-@JNINamespace("autofill")
-public abstract class AutofillProvider {
- public AutofillProvider() {}
-
- /**
- * Invoked when container view is changed.
- *
- * @param containerView new container view.
- */
- public abstract void onContainerViewChanged(ViewGroup containerView);
-
- public abstract void setWebContents(WebContents webContents);
-
- /**
- * Invoked when autofill value is available, AutofillProvider shall fill the
- * form with the provided values.
- *
- * @param values the array of autofill values, the key is virtual id of form
- * field.
- */
- public abstract void autofill(final SparseArray<AutofillValue> values);
-
- /**
- * Invoked when autofill service needs the form structure.
- *
- * @param structure see View.onProvideAutofillVirtualStructure()
- * @param flags see View.onProvideAutofillVirtualStructure()
- */
- public abstract void onProvideAutoFillVirtualStructure(ViewStructure structure, int flags);
-
- /**
- * @return whether query autofill suggestion.
- */
- public abstract boolean shouldQueryAutofillSuggestion();
-
- public abstract void queryAutofillSuggestion();
-
- /**
- * Invoked when filling form is need. AutofillProvider shall ask autofill
- * service for the values with which to fill the form.
- *
- * @param formData the form needs to fill.
- * @param focus the index of focus field in formData
- * @param x the boundary of focus field.
- * @param y the boundary of focus field.
- * @param width the boundary of focus field.
- * @param height the boundary of focus field.
- */
- @CalledByNative
- protected abstract void startAutofillSession(
- FormData formData, int focus, float x, float y, float width, float height);
-
- /**
- * Invoked when form field's value is changed.
- *
- * @param index index of field in current form.
- * @param x the boundary of focus field.
- * @param y the boundary of focus field.
- * @param width the boundary of focus field.
- * @param height the boundary of focus field.
- *
- */
- @CalledByNative
- protected abstract void onFormFieldDidChange(
- int index, float x, float y, float width, float height);
-
- /**
- * Invoked when text field is scrolled.
- *
- * @param index index of field in current form.
- * @param x the boundary of focus field.
- * @param y the boundary of focus field.
- * @param width the boundary of focus field.
- * @param height the boundary of focus field.
- *
- */
- @CalledByNative
- protected abstract void onTextFieldDidScroll(
- int index, float x, float y, float width, float height);
-
- /**
- * Invoked when current form will be submitted.
- * @param submissionSource the submission source, could be any member defined in
- * SubmissionSource.java
- */
- @CalledByNative
- protected abstract void onFormSubmitted(int submissionSource);
-
- /**
- * Invoked when focus field changed.
- *
- * @param focusOnForm whether focus is still on form.
- * @param focusItem the index of field has focus
- * @param x the boundary of focus field.
- * @param y the boundary of focus field.
- * @param width the boundary of focus field.
- * @param height the boundary of focus field.
- */
- @CalledByNative
- protected abstract void onFocusChanged(
- boolean focusOnForm, int focusItem, float x, float y, float width, float height);
-
- /**
- * Send form to renderer for filling.
- *
- * @param nativeAutofillProvider the native autofill provider.
- * @param formData the form to fill.
- */
- protected void autofill(long nativeAutofillProvider, FormData formData) {
- AutofillProviderJni.get().onAutofillAvailable(
- nativeAutofillProvider, AutofillProvider.this, formData);
- }
-
- /**
- * Invoked when current query need to be reset.
- */
- @CalledByNative
- protected abstract void reset();
-
- @CalledByNative
- protected abstract void setNativeAutofillProvider(long nativeAutofillProvider);
-
- @CalledByNative
- protected abstract void onDidFillAutofillFormData();
-
- @NativeMethods
- interface Natives {
- void onAutofillAvailable(
- long nativeAutofillProviderAndroid, AutofillProvider caller, FormData formData);
- }
-}
diff --git a/chromium/components/autofill/android/provider/BUILD.gn b/chromium/components/autofill/android/provider/BUILD.gn
new file mode 100644
index 00000000000..263b88afd5e
--- /dev/null
+++ b/chromium/components/autofill/android/provider/BUILD.gn
@@ -0,0 +1,53 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+import("//build/config/locales.gni")
+
+android_library("java") {
+ deps = [
+ "//base:base_java",
+ "//base:jni_java",
+ "//components/autofill/android:autofill_java",
+ "//components/autofill/core/common/mojom:mojo_types_java",
+ "//components/version_info/android:version_constants_java",
+ "//content/public/android:content_java",
+ "//third_party/android_deps:androidx_annotation_annotation_java",
+ "//ui/android:ui_java",
+ ]
+ annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+ sources = [
+ "java/src/org/chromium/components/autofill/AutofillActionModeCallback.java",
+ "java/src/org/chromium/components/autofill/AutofillManagerWrapper.java",
+ "java/src/org/chromium/components/autofill/AutofillProvider.java",
+ "java/src/org/chromium/components/autofill/AutofillProviderUMA.java",
+ "java/src/org/chromium/components/autofill/FormData.java",
+ "java/src/org/chromium/components/autofill/FormFieldData.java",
+ ]
+}
+
+generate_jni("jni_headers") {
+ sources = [
+ "java/src/org/chromium/components/autofill/AutofillProvider.java",
+ "java/src/org/chromium/components/autofill/FormData.java",
+ "java/src/org/chromium/components/autofill/FormFieldData.java",
+ ]
+}
+
+static_library("provider") {
+ sources = [
+ "autofill_provider_android.cc",
+ "autofill_provider_android.h",
+ "form_data_android.cc",
+ "form_data_android.h",
+ "form_field_data_android.cc",
+ "form_field_data_android.h",
+ ]
+ deps = [
+ ":jni_headers",
+ "//components/autofill/core/browser:browser",
+ "//content/public/browser",
+ "//ui/android",
+ ]
+}
diff --git a/chromium/components/autofill/android/junit/OWNERS b/chromium/components/autofill/android/provider/OWNERS
index 44a22b15980..44a22b15980 100644
--- a/chromium/components/autofill/android/junit/OWNERS
+++ b/chromium/components/autofill/android/provider/OWNERS
diff --git a/chromium/components/autofill/android/autofill_provider_android.cc b/chromium/components/autofill/android/provider/autofill_provider_android.cc
index 76129371d95..408ff96c130 100644
--- a/chromium/components/autofill/android/autofill_provider_android.cc
+++ b/chromium/components/autofill/android/provider/autofill_provider_android.cc
@@ -2,27 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/autofill/android/autofill_provider_android.h"
+#include "components/autofill/android/provider/autofill_provider_android.h"
#include <memory>
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
-#include "components/autofill/android/form_data_android.h"
-#include "components/autofill/android/jni_headers/AutofillProvider_jni.h"
+#include "components/autofill/android/provider/form_data_android.h"
+#include "components/autofill/android/provider/jni_headers/AutofillProvider_jni.h"
#include "components/autofill/core/browser/autofill_driver.h"
#include "components/autofill/core/browser/autofill_handler_proxy.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
+#include "ui/android/window_android.h"
#include "ui/gfx/geometry/rect_f.h"
using base::android::AttachCurrentThread;
+using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaArrayOfStrings;
using content::BrowserThread;
using content::WebContents;
using gfx::RectF;
@@ -85,6 +88,21 @@ void AutofillProviderAndroid::OnQueryFormFieldAutofill(
// ignored if the form is same.
if (ShouldStartNewSession(handler, form))
StartNewSession(handler, form, field, bounding_box);
+
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ if (!field.datalist_values.empty()) {
+ ScopedJavaLocalRef<jobjectArray> jdatalist_values =
+ ToJavaArrayOfStrings(env, field.datalist_values);
+ ScopedJavaLocalRef<jobjectArray> jdatalist_labels =
+ ToJavaArrayOfStrings(env, field.datalist_labels);
+ Java_AutofillProvider_showDatalistPopup(
+ env, obj, jdatalist_values, jdatalist_labels,
+ field.text_direction == base::i18n::RIGHT_TO_LEFT);
+ }
}
bool AutofillProviderAndroid::ShouldStartNewSession(
@@ -141,6 +159,31 @@ void AutofillProviderAndroid::OnAutofillAvailable(JNIEnv* env,
}
}
+void AutofillProviderAndroid::OnAcceptDataListSuggestion(JNIEnv* env,
+ jobject jcaller,
+ jstring value) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (auto* handler = handler_.get()) {
+ RendererShouldAcceptDataListSuggestion(
+ handler, ConvertJavaStringToUTF16(env, value));
+ }
+}
+
+void AutofillProviderAndroid::SetAnchorViewRect(JNIEnv* env,
+ jobject jcaller,
+ jobject anchor_view,
+ jfloat x,
+ jfloat y,
+ jfloat width,
+ jfloat height) {
+ ui::ViewAndroid* view_android = web_contents_->GetNativeView();
+ if (!view_android)
+ return;
+
+ view_android->SetAnchorRect(ScopedJavaLocalRef<jobject>(env, anchor_view),
+ gfx::RectF(x, y, width, height));
+}
+
void AutofillProviderAndroid::OnTextFieldDidChange(
AutofillHandlerProxy* handler,
const FormData& form,
@@ -314,6 +357,18 @@ void AutofillProviderAndroid::OnFormsSeen(AutofillHandlerProxy* handler,
FireSuccessfulSubmission(pending_submission_source_);
}
+void AutofillProviderAndroid::OnHidePopup(AutofillHandlerProxy* handler) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (handler == handler_.get()) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ Java_AutofillProvider_hidePopup(env, obj);
+ }
+}
+
void AutofillProviderAndroid::Reset(AutofillHandlerProxy* handler) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (handler == handler_.get()) {
diff --git a/chromium/components/autofill/android/autofill_provider_android.h b/chromium/components/autofill/android/provider/autofill_provider_android.h
index 270a05eea00..b0830e2338e 100644
--- a/chromium/components/autofill/android/autofill_provider_android.h
+++ b/chromium/components/autofill/android/provider/autofill_provider_android.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_AUTOFILL_ANDROID_AUTOFILL_PROVIDER_ANDROID_H_
-#define COMPONENTS_AUTOFILL_ANDROID_AUTOFILL_PROVIDER_ANDROID_H_
+#ifndef COMPONENTS_AUTOFILL_ANDROID_PROVIDER_AUTOFILL_PROVIDER_ANDROID_H_
+#define COMPONENTS_AUTOFILL_ANDROID_PROVIDER_AUTOFILL_PROVIDER_ANDROID_H_
#include "base/android/jni_weak_ref.h"
#include "base/memory/weak_ptr.h"
@@ -67,11 +67,21 @@ class AutofillProviderAndroid : public AutofillProvider {
void OnFormsSeen(AutofillHandlerProxy* handler,
const std::vector<FormData>& forms,
const base::TimeTicks timestamp) override;
+ void OnHidePopup(AutofillHandlerProxy* handler) override;
void Reset(AutofillHandlerProxy* handler) override;
// Methods called by Java.
void OnAutofillAvailable(JNIEnv* env, jobject jcaller, jobject form_data);
+ void OnAcceptDataListSuggestion(JNIEnv* env, jobject jcaller, jstring value);
+
+ void SetAnchorViewRect(JNIEnv* env,
+ jobject jcaller,
+ jobject anchor_view,
+ jfloat x,
+ jfloat y,
+ jfloat width,
+ jfloat height);
private:
void FireSuccessfulSubmission(mojom::SubmissionSource source);
@@ -114,4 +124,4 @@ class AutofillProviderAndroid : public AutofillProvider {
};
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_ANDROID_AUTOFILL_PROVIDER_ANDROID_H_
+#endif // COMPONENTS_AUTOFILL_ANDROID_PROVIDER_AUTOFILL_PROVIDER_ANDROID_H_
diff --git a/chromium/components/autofill/android/form_data_android.cc b/chromium/components/autofill/android/provider/form_data_android.cc
index c91a0c62472..7f24f8967c5 100644
--- a/chromium/components/autofill/android/form_data_android.cc
+++ b/chromium/components/autofill/android/provider/form_data_android.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/autofill/android/form_data_android.h"
+#include "components/autofill/android/provider/form_data_android.h"
#include "base/android/jni_string.h"
-#include "components/autofill/android/form_field_data_android.h"
-#include "components/autofill/android/jni_headers/FormData_jni.h"
+#include "components/autofill/android/provider/form_field_data_android.h"
+#include "components/autofill/android/provider/jni_headers/FormData_jni.h"
#include "components/autofill/core/browser/form_structure.h"
using base::android::AttachCurrentThread;
diff --git a/chromium/components/autofill/android/form_data_android.h b/chromium/components/autofill/android/provider/form_data_android.h
index a2b33c8d917..8882a788673 100644
--- a/chromium/components/autofill/android/form_data_android.h
+++ b/chromium/components/autofill/android/provider/form_data_android.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_AUTOFILL_ANDROID_FORM_DATA_ANDROID_H_
-#define COMPONENTS_AUTOFILL_ANDROID_FORM_DATA_ANDROID_H_
+#ifndef COMPONENTS_AUTOFILL_ANDROID_PROVIDER_FORM_DATA_ANDROID_H_
+#define COMPONENTS_AUTOFILL_ANDROID_PROVIDER_FORM_DATA_ANDROID_H_
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
@@ -70,4 +70,4 @@ class FormDataAndroid {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_ANDROID_FORM_DATA_ANDROID_H_
+#endif // COMPONENTS_AUTOFILL_ANDROID_PROVIDER_FORM_DATA_ANDROID_H_
diff --git a/chromium/components/autofill/android/form_field_data_android.cc b/chromium/components/autofill/android/provider/form_field_data_android.cc
index da134267220..ee5471f5239 100644
--- a/chromium/components/autofill/android/form_field_data_android.cc
+++ b/chromium/components/autofill/android/provider/form_field_data_android.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/autofill/android/form_field_data_android.h"
+#include "components/autofill/android/provider/form_field_data_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
-#include "components/autofill/android/jni_headers/FormFieldData_jni.h"
+#include "components/autofill/android/provider/jni_headers/FormFieldData_jni.h"
#include "components/autofill/core/common/autofill_util.h"
using base::android::AttachCurrentThread;
@@ -50,6 +50,10 @@ ScopedJavaLocalRef<jobject> FormFieldDataAndroid::GetJavaPeer() {
if (!heuristic_type_.IsUnknown())
jheuristic_type =
ConvertUTF8ToJavaString(env, heuristic_type_.ToString());
+ ScopedJavaLocalRef<jobjectArray> jdatalist_values =
+ ToJavaArrayOfStrings(env, field_ptr_->datalist_values);
+ ScopedJavaLocalRef<jobjectArray> jdatalist_labels =
+ ToJavaArrayOfStrings(env, field_ptr_->datalist_labels);
obj = Java_FormFieldData_createFormFieldData(
env, jname, jlabel, jvalue, jautocomplete_attr,
@@ -57,7 +61,8 @@ ScopedJavaLocalRef<jobject> FormFieldDataAndroid::GetJavaPeer() {
joption_values, joption_contents, IsCheckable(field_ptr_->check_status),
IsChecked(field_ptr_->check_status), field_ptr_->max_length,
jheuristic_type, field_ptr_->bounds.x(), field_ptr_->bounds.y(),
- field_ptr_->bounds.right(), field_ptr_->bounds.bottom());
+ field_ptr_->bounds.right(), field_ptr_->bounds.bottom(),
+ jdatalist_values, jdatalist_labels);
java_ref_ = JavaObjectWeakGlobalRef(env, obj);
}
return obj;
diff --git a/chromium/components/autofill/android/form_field_data_android.h b/chromium/components/autofill/android/provider/form_field_data_android.h
index e882bb49704..a12ad979bfe 100644
--- a/chromium/components/autofill/android/form_field_data_android.h
+++ b/chromium/components/autofill/android/provider/form_field_data_android.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_AUTOFILL_ANDROID_FORM_FIELD_DATA_ANDROID_H_
-#define COMPONENTS_AUTOFILL_ANDROID_FORM_FIELD_DATA_ANDROID_H_
+#ifndef COMPONENTS_AUTOFILL_ANDROID_PROVIDER_FORM_FIELD_DATA_ANDROID_H_
+#define COMPONENTS_AUTOFILL_ANDROID_PROVIDER_FORM_FIELD_DATA_ANDROID_H_
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
@@ -39,4 +39,4 @@ class FormFieldDataAndroid {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_ANDROID_FORM_FIELD_DATA_ANDROID_H_
+#endif // COMPONENTS_AUTOFILL_ANDROID_PROVIDER_FORM_FIELD_DATA_ANDROID_H_
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java
index 6921fcab52c..6921fcab52c 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java
+++ b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
index 0287ac38f97..0287ac38f97 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
+++ b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderImpl.java b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java
index e53188067c3..acbf7a61a22 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderImpl.java
+++ b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java
@@ -19,18 +19,30 @@ import android.view.autofill.AutofillValue;
import androidx.annotation.VisibleForTesting;
+import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
+import org.chromium.base.StrictModeContext;
import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.DoNotInline;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
+import org.chromium.base.annotations.VerifiesOnO;
import org.chromium.base.metrics.ScopedSysTraceEvent;
import org.chromium.components.version_info.VersionConstants;
import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.browser.WebContentsAccessibility;
+import org.chromium.ui.DropdownItem;
+import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.display.DisplayAndroid;
/**
- * This class uses Android autofill service to fill web form. All methods are
- * supposed to be called in UI thread.
+ * This class works with Android autofill service to fill web form, it doesn't use chrome's
+ * autofill service or suggestion UI. All methods are supposed to be called in UI thread.
+ *
+ * AutofillProvider handles one autofill session at time, each call of
+ * queryFormFieldAutofill cancels previous session and starts a new one, the
+ * calling of other methods shall associate with current session.
*
* This class doesn't have 1:1 mapping to native AutofillProviderAndroid; the
* normal ownership model is that this object is owned by the embedder-specific
@@ -38,12 +50,13 @@ import org.chromium.ui.display.DisplayAndroid;
* AutofillProviderAndroid is owned by the embedder-specific C++ WebContents
* wrapper (e.g., native AwContents in //android_webview).
*
- * DoNotInline since it causes class verification errors, see crbug.com/991851.
+ * VerifiesOnO since it causes class verification errors, see crbug.com/991851.
*/
-@DoNotInline
+@VerifiesOnO
@TargetApi(Build.VERSION_CODES.O)
-public class AutofillProviderImpl extends AutofillProvider {
- private static final String TAG = "AutofillProviderImpl";
+@JNINamespace("autofill")
+public class AutofillProvider {
+ private static final String TAG = "AutofillProvider";
private static class FocusField {
public final short fieldIndex;
public final Rect absBound;
@@ -117,11 +130,15 @@ public class AutofillProviderImpl extends AutofillProvider {
child.setAutofillValue(AutofillValue.forToggle(field.isChecked()));
break;
case FormFieldData.ControlType.TEXT:
+ case FormFieldData.ControlType.DATALIST:
child.setAutofillType(View.AUTOFILL_TYPE_TEXT);
child.setAutofillValue(AutofillValue.forText(field.getValue()));
if (field.mMaxLength != 0) {
builder.addAttribute("maxlength", String.valueOf(field.mMaxLength));
}
+ if (field.getControlType() == FormFieldData.ControlType.DATALIST) {
+ child.setAutofillOptions(field.mDatalistValues);
+ }
break;
default:
break;
@@ -151,6 +168,7 @@ public class AutofillProviderImpl extends AutofillProvider {
field.setChecked(value.getToggleValue());
break;
case FormFieldData.ControlType.TEXT:
+ case FormFieldData.ControlType.DATALIST:
field.setAutofillValue((String) value.getTextValue());
break;
default:
@@ -188,6 +206,7 @@ public class AutofillProviderImpl extends AutofillProvider {
case FormFieldData.ControlType.TOGGLE:
return AutofillValue.forToggle(field.isChecked());
case FormFieldData.ControlType.TEXT:
+ case FormFieldData.ControlType.DATALIST:
return AutofillValue.forText(field.getValue());
default:
return null;
@@ -240,17 +259,20 @@ public class AutofillProviderImpl extends AutofillProvider {
private AutofillProviderUMA mAutofillUMA;
private AutofillManagerWrapper.InputUIObserver mInputUIObserver;
private long mAutofillTriggeredTimeMillis;
+ private Context mContext;
+ private AutofillPopup mDatalistPopup;
+ private WebContentsAccessibility mWebContentsAccessibility;
+ private View mAnchorView;
- public AutofillProviderImpl(Context context, ViewGroup containerView, String providerName) {
+ public AutofillProvider(Context context, ViewGroup containerView, String providerName) {
this(containerView, new AutofillManagerWrapper(context), context, providerName);
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- public AutofillProviderImpl(ViewGroup containerView, AutofillManagerWrapper manager,
+ public AutofillProvider(ViewGroup containerView, AutofillManagerWrapper manager,
Context context, String providerName) {
mProviderName = providerName;
- try (ScopedSysTraceEvent e =
- ScopedSysTraceEvent.scoped("AutofillProviderImpl.constructor")) {
+ try (ScopedSysTraceEvent e = ScopedSysTraceEvent.scoped("AutofillProvider.constructor")) {
assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
mAutofillManager = manager;
mContainerView = containerView;
@@ -266,15 +288,25 @@ public class AutofillProviderImpl extends AutofillProvider {
}
};
mAutofillManager.addInputUIObserver(mInputUIObserver);
+ mContext = context;
}
}
- @Override
+ /**
+ * Invoked when container view is changed.
+ *
+ * @param containerView new container view.
+ */
public void onContainerViewChanged(ViewGroup containerView) {
mContainerView = containerView;
}
- @Override
+ /**
+ * Invoked when autofill service needs the form structure.
+ *
+ * @param structure see View.onProvideAutofillVirtualStructure()
+ * @param flags see View.onProvideAutofillVirtualStructure()
+ */
public void onProvideAutoFillVirtualStructure(ViewStructure structure, int flags) {
// This method could be called for the session started by the native
// control outside of the scope of autofill, e.g. the URL bar, in this case, we simply
@@ -295,7 +327,13 @@ public class AutofillProviderImpl extends AutofillProvider {
mAutofillUMA.onVirtualStructureProvided();
}
- @Override
+ /**
+ * Invoked when autofill value is available, AutofillProvider shall fill the
+ * form with the provided values.
+ *
+ * @param values the array of autofill values, the key is virtual id of form
+ * field.
+ */
public void autofill(final SparseArray<AutofillValue> values) {
if (mNativeAutofillProvider != 0 && mRequest != null && mRequest.autofill((values))) {
autofill(mNativeAutofillProvider, mRequest.mFormData);
@@ -306,13 +344,14 @@ public class AutofillProviderImpl extends AutofillProvider {
}
}
- @Override
+ /**
+ * @return whether query autofill suggestion.
+ */
public boolean shouldQueryAutofillSuggestion() {
return mRequest != null && mRequest.getFocusField() != null
&& !mAutofillManager.isAutofillInputUIShowing();
}
- @Override
public void queryAutofillSuggestion() {
if (shouldQueryAutofillSuggestion()) {
FocusField focusField = mRequest.getFocusField();
@@ -321,27 +360,50 @@ public class AutofillProviderImpl extends AutofillProvider {
}
}
- @Override
+ /**
+ * Invoked when filling form is need. AutofillProvider shall ask autofill
+ * service for the values with which to fill the form.
+ *
+ * @param formData the form needs to fill.
+ * @param focus the index of focus field in formData
+ * @param x the boundary of focus field.
+ * @param y the boundary of focus field.
+ * @param width the boundary of focus field.
+ * @param height the boundary of focus field.
+ */
+ @CalledByNative
public void startAutofillSession(
FormData formData, int focus, float x, float y, float width, float height) {
// Check focusField inside short value?
- // Autofill Manager might have session that wasn't started by AutofillProviderImpl,
+ // Autofill Manager might have session that wasn't started by AutofillProvider,
// we just always cancel existing session here.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
mAutofillManager.cancel();
}
- mAutofillManager.notifyNewSessionStarted();
+
Rect absBound = transformToWindowBounds(new RectF(x, y, x + width, y + height));
- if (mRequest != null) notifyViewExitBeforeDestoryRequest();
+ if (mRequest != null) notifyViewExitBeforeDestroyRequest();
transformFormFieldToContainViewCoordinates(formData);
mRequest = new AutofillRequest(formData, new FocusField((short) focus, absBound));
int virtualId = mRequest.getVirtualId((short) focus);
- mAutofillManager.notifyVirtualViewEntered(mContainerView, virtualId, absBound);
+ notifyVirtualViewEntered(mContainerView, virtualId, absBound);
mAutofillUMA.onSessionStarted(mAutofillManager.isDisabled());
mAutofillTriggeredTimeMillis = System.currentTimeMillis();
+
+ mAutofillManager.notifyNewSessionStarted();
}
- @Override
+ /**
+ * Invoked when form field's value is changed.
+ *
+ * @param index index of field in current form.
+ * @param x the boundary of focus field.
+ * @param y the boundary of focus field.
+ * @param width the boundary of focus field.
+ * @param height the boundary of focus field.
+ *
+ */
+ @CalledByNative
public void onFormFieldDidChange(int index, float x, float y, float width, float height) {
// Check index inside short value?
if (mRequest == null) return;
@@ -358,17 +420,27 @@ public class AutofillProviderImpl extends AutofillProvider {
int virtualId = mRequest.getVirtualId(sIndex);
Rect absBound = transformToWindowBounds(new RectF(x, y, x + width, y + height));
if (!focusField.absBound.equals(absBound)) {
- mAutofillManager.notifyVirtualViewExited(mContainerView, virtualId);
- mAutofillManager.notifyVirtualViewEntered(mContainerView, virtualId, absBound);
+ notifyVirtualViewExited(mContainerView, virtualId);
+ notifyVirtualViewEntered(mContainerView, virtualId, absBound);
// Update focus field position.
mRequest.setFocusField(new FocusField(focusField.fieldIndex, absBound));
}
}
- notifyVirtualValueChanged(index);
+ notifyVirtualValueChanged(index, /* forceNotify = */ false);
mAutofillUMA.onUserChangeFieldValue(mRequest.getField(sIndex).hasPreviouslyAutofilled());
}
- @Override
+ /**
+ * Invoked when text field is scrolled.
+ *
+ * @param index index of field in current form.
+ * @param x the boundary of focus field.
+ * @param y the boundary of focus field.
+ * @param width the boundary of focus field.
+ * @param height the boundary of focus field.
+ *
+ */
+ @CalledByNative
public void onTextFieldDidScroll(int index, float x, float y, float width, float height) {
// crbug.com/730764 - from P and above, Android framework listens to the onScrollChanged()
// and repositions the autofill UI automatically.
@@ -383,42 +455,94 @@ public class AutofillProviderImpl extends AutofillProvider {
Rect absBound = transformToWindowBounds(new RectF(x, y, x + width, y + height));
// Notify the new position to the Android framework. Note that we do not call
// notifyVirtualViewExited() here intentionally to avoid flickering.
- mAutofillManager.notifyVirtualViewEntered(mContainerView, virtualId, absBound);
+ notifyVirtualViewEntered(mContainerView, virtualId, absBound);
// Update focus field position.
mRequest.setFocusField(new FocusField(focusField.fieldIndex, absBound));
}
- private void notifyVirtualValueChanged(int index) {
+ private boolean isDatalistField(int childId) {
+ FormFieldData field = mRequest.getField((short) childId);
+ return field.mControlType == FormFieldData.ControlType.DATALIST;
+ }
+
+ private void notifyVirtualValueChanged(int index, boolean forceNotify) {
+ // The ValueChanged, ViewEntered and ViewExited aren't notified to the autofill service for
+ // the focused datalist to avoid the potential UI conflict.
+ // The datalist support was added later and the option list is displayed by WebView, the
+ // autofill service might also show its suggestions when the datalist (associated the input
+ // field) is focused, the two UI overlap, the solution is to completely hide the fact that
+ // the datalist is being focused to the autofill service to prevent it from displaying the
+ // suggestion.
+ // The ValueChange will still be sent to autofill service when the form
+ // submitted or autofilled.
+ if (!forceNotify && isDatalistField(index)) return;
AutofillValue autofillValue = mRequest.getFieldNewValue(index);
if (autofillValue == null) return;
mAutofillManager.notifyVirtualValueChanged(
mContainerView, mRequest.getVirtualId((short) index), autofillValue);
}
- @Override
+ private void notifyVirtualViewEntered(View parent, int childId, Rect absBounds) {
+ // Refer to notifyVirtualValueChanged() for the reason of the datalist's special handling.
+ if (isDatalistField(childId)) return;
+ mAutofillManager.notifyVirtualViewEntered(parent, childId, absBounds);
+ }
+
+ private void notifyVirtualViewExited(View parent, int childId) {
+ // Refer to notifyVirtualValueChanged() for the reason of the datalist's special handling.
+ if (isDatalistField(childId)) return;
+ mAutofillManager.notifyVirtualViewExited(parent, childId);
+ }
+
+ /**
+ * Invoked when current form will be submitted.
+ * @param submissionSource the submission source, could be any member defined in
+ * SubmissionSource.java
+ */
+ @CalledByNative
public void onFormSubmitted(int submissionSource) {
// The changes could be missing, like those made by Javascript, we'd better to notify
// AutofillManager current values. also see crbug.com/353001 and crbug.com/732856.
- notifyFormValues();
+ forceNotifyFormValues();
mAutofillManager.commit(submissionSource);
mRequest = null;
mAutofillUMA.onFormSubmitted(submissionSource);
}
- @Override
+ /**
+ * Invoked when focus field changed.
+ *
+ * @param focusOnForm whether focus is still on form.
+ * @param focusItem the index of field has focus
+ * @param x the boundary of focus field.
+ * @param y the boundary of focus field.
+ * @param width the boundary of focus field.
+ * @param height the boundary of focus field.
+ */
+ @CalledByNative
public void onFocusChanged(
boolean focusOnForm, int focusField, float x, float y, float width, float height) {
onFocusChangedImpl(
focusOnForm, focusField, x, y, width, height, false /*causedByValueChange*/);
}
- private void notifyViewExitBeforeDestoryRequest() {
+ @CalledByNative
+ public void hidePopup() {
+ if (mDatalistPopup != null) {
+ mDatalistPopup.dismiss();
+ mDatalistPopup = null;
+ }
+ if (mWebContentsAccessibility != null) {
+ mWebContentsAccessibility.onAutofillPopupDismissed();
+ }
+ }
+
+ private void notifyViewExitBeforeDestroyRequest() {
if (mRequest == null) return;
FocusField focusField = mRequest.getFocusField();
if (focusField == null) return;
- mAutofillManager.notifyVirtualViewExited(
- mContainerView, mRequest.getVirtualId(focusField.fieldIndex));
+ notifyVirtualViewExited(mContainerView, mRequest.getVirtualId(focusField.fieldIndex));
mRequest.setFocusField(null);
}
@@ -436,37 +560,118 @@ public class AutofillProviderImpl extends AutofillProvider {
// Notify focus changed.
if (prev != null) {
- mAutofillManager.notifyVirtualViewExited(
- mContainerView, mRequest.getVirtualId(prev.fieldIndex));
+ notifyVirtualViewExited(mContainerView, mRequest.getVirtualId(prev.fieldIndex));
}
- mAutofillManager.notifyVirtualViewEntered(
+ notifyVirtualViewEntered(
mContainerView, mRequest.getVirtualId((short) focusField), absBound);
if (!causedByValueChange) {
// The focus field value might not sync with platform's
// AutofillManager, just notify it value changed.
- notifyVirtualValueChanged(focusField);
+ notifyVirtualValueChanged(focusField, /* forceNotify = */ false);
mAutofillTriggeredTimeMillis = System.currentTimeMillis();
}
mRequest.setFocusField(new FocusField((short) focusField, absBound));
} else {
if (prev == null) return;
// Notify focus changed.
- mAutofillManager.notifyVirtualViewExited(
- mContainerView, mRequest.getVirtualId(prev.fieldIndex));
+ notifyVirtualViewExited(mContainerView, mRequest.getVirtualId(prev.fieldIndex));
mRequest.setFocusField(null);
}
}
- @Override
+ @CalledByNative
+ protected void showDatalistPopup(
+ String[] datalistValues, String[] datalistLabels, boolean isRtl) {
+ if (mRequest == null) return;
+ FocusField focusField = mRequest.getFocusField();
+ if (focusField != null) {
+ showDatalistPopup(datalistValues, datalistLabels,
+ mRequest.getField(focusField.fieldIndex).getBounds(), isRtl);
+ }
+ }
+
+ /**
+ * Display the simplest popup for the datalist. This is same as WebView's datalist popup in
+ * Android pre-o. No suggestion from the autofill service will be presented, No advance
+ * features of AutofillPopup are used.
+ */
+ private void showDatalistPopup(
+ String[] datalistValues, String[] datalistLabels, RectF bounds, boolean isRtl) {
+ final AutofillSuggestion[] suggestions = new AutofillSuggestion[datalistValues.length];
+ for (int i = 0; i < suggestions.length; i++) {
+ suggestions[i] = new AutofillSuggestion(datalistValues[i], datalistLabels[i],
+ DropdownItem.NO_ICON, false /* isIconAtLeft */, i, false /* isDeletable */,
+ false /* isMultilineLabel */, false /* isBoldLabel */);
+ }
+ if (mWebContentsAccessibility == null) {
+ mWebContentsAccessibility = WebContentsAccessibility.fromWebContents(mWebContents);
+ }
+ if (mDatalistPopup == null) {
+ if (ContextUtils.activityFromContext(mContext) == null) return;
+ ViewAndroidDelegate delegate = mWebContents.getViewAndroidDelegate();
+ if (mAnchorView == null) mAnchorView = delegate.acquireView();
+ setAnchorViewRect(bounds);
+ try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
+ mDatalistPopup = new AutofillPopup(mContext, mAnchorView, new AutofillDelegate() {
+ @Override
+ public void dismissed() {
+ onDatalistPopupDismissed();
+ }
+
+ @Override
+ public void suggestionSelected(int listIndex) {
+ onSuggestionSelected(suggestions[listIndex].getLabel());
+ }
+
+ @Override
+ public void deleteSuggestion(int listIndex) {}
+
+ @Override
+ public void accessibilityFocusCleared() {
+ mWebContentsAccessibility.onAutofillPopupAccessibilityFocusCleared();
+ }
+ });
+ } catch (RuntimeException e) {
+ // Deliberately swallowing exception because bad framework implementation can
+ // throw exceptions in ListPopupWindow constructor.
+ onDatalistPopupDismissed();
+ return;
+ }
+ }
+ mDatalistPopup.filterAndShow(suggestions, isRtl, false);
+ if (mWebContentsAccessibility != null) {
+ mWebContentsAccessibility.onAutofillPopupDisplayed(mDatalistPopup.getListView());
+ }
+ }
+
+ private void onDatalistPopupDismissed() {
+ ViewAndroidDelegate delegate = mWebContents.getViewAndroidDelegate();
+ delegate.removeView(mAnchorView);
+ mAnchorView = null;
+ }
+
+ private void onSuggestionSelected(String value) {
+ acceptDataListSuggestion(mNativeAutofillProvider, value);
+ hidePopup();
+ }
+
+ private void setAnchorViewRect(RectF rect) {
+ setAnchorViewRect(mNativeAutofillProvider, mAnchorView, rect);
+ }
+
+ /**
+ * Invoked when current query need to be reset.
+ */
+ @CalledByNative
protected void reset() {
// We don't need to reset anything here, it should be safe to cancel
// current autofill session when new one starts in
// startAutofillSession().
}
- @Override
+ @CalledByNative
protected void setNativeAutofillProvider(long nativeAutofillProvider) {
if (nativeAutofillProvider == mNativeAutofillProvider) return;
// Setting the mNativeAutofillProvider to 0 may occur as a
@@ -482,21 +687,29 @@ public class AutofillProviderImpl extends AutofillProvider {
if (nativeAutofillProvider == 0) mAutofillManager.destroy();
}
- @Override
public void setWebContents(WebContents webContents) {
if (webContents == mWebContents) return;
if (mWebContents != null) mRequest = null;
mWebContents = webContents;
}
- @Override
+ @CalledByNative
protected void onDidFillAutofillFormData() {
- notifyFormValues();
+ // The changes were caused by the autofill service autofill form,
+ // notified it about the result.
+ forceNotifyFormValues();
}
- private void notifyFormValues() {
+ private void forceNotifyFormValues() {
if (mRequest == null) return;
- for (int i = 0; i < mRequest.getFieldCount(); ++i) notifyVirtualValueChanged(i);
+ for (int i = 0; i < mRequest.getFieldCount(); ++i) {
+ notifyVirtualValueChanged(i, /* forceNotify = */ true);
+ }
+ }
+
+ @VisibleForTesting
+ public AutofillPopup getDatalistPopupForTesting() {
+ return mDatalistPopup;
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
@@ -537,4 +750,37 @@ public class AutofillProviderImpl extends AutofillProvider {
field.setBoundsInContainerViewCoordinates(bounds);
}
}
+
+ /**
+ * Send form to renderer for filling.
+ *
+ * @param nativeAutofillProvider the native autofill provider.
+ * @param formData the form to fill.
+ */
+ private void autofill(long nativeAutofillProvider, FormData formData) {
+ AutofillProviderJni.get().onAutofillAvailable(
+ nativeAutofillProvider, AutofillProvider.this, formData);
+ }
+
+ private void acceptDataListSuggestion(long nativeAutofillProvider, String value) {
+ AutofillProviderJni.get().onAcceptDataListSuggestion(
+ nativeAutofillProvider, AutofillProvider.this, value);
+ }
+
+ private void setAnchorViewRect(long nativeAutofillProvider, View anchorView, RectF rect) {
+ AutofillProviderJni.get().setAnchorViewRect(nativeAutofillProvider, AutofillProvider.this,
+ anchorView, rect.left, rect.top, rect.width(), rect.height());
+ }
+
+ @NativeMethods
+ interface Natives {
+ void onAutofillAvailable(
+ long nativeAutofillProviderAndroid, AutofillProvider caller, FormData formData);
+
+ void onAcceptDataListSuggestion(
+ long nativeAutofillProviderAndroid, AutofillProvider caller, String value);
+
+ void setAnchorViewRect(long nativeAutofillProviderAndroid, AutofillProvider caller,
+ View anchorView, float x, float y, float width, float height);
+ }
}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java
index 394cd849c95..394cd849c95 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java
+++ b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormData.java
index 8069aa887b6..8069aa887b6 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java
+++ b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormData.java
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java
index 964c73206c7..eb0a94a6bce 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
+++ b/chromium/components/autofill/android/provider/java/src/org/chromium/components/autofill/FormFieldData.java
@@ -22,13 +22,17 @@ import java.lang.annotation.RetentionPolicy;
public class FormFieldData {
/**
* Define the control types supported by android.view.autofill.AutofillValue.
+ *
+ * Android doesn't have DATALIST control, it is sent to the Autofill service as
+ * View.AUTOFILL_TYPE_TEXT with AutofillOptions.
*/
- @IntDef({ControlType.TEXT, ControlType.TOGGLE, ControlType.LIST})
+ @IntDef({ControlType.TEXT, ControlType.TOGGLE, ControlType.LIST, ControlType.DATALIST})
@Retention(RetentionPolicy.SOURCE)
public @interface ControlType {
int TEXT = 0;
int TOGGLE = 1;
int LIST = 2;
+ int DATALIST = 3;
}
public final String mLabel;
@@ -43,6 +47,9 @@ public class FormFieldData {
public final @ControlType int mControlType;
public final int mMaxLength;
public final String mHeuristicType;
+ public final String[] mDatalistValues;
+ public final String[] mDatalistLabels;
+
// The bounds in the viewport's coordinates
private final RectF mBounds;
// The bounds in the container view's coordinates.
@@ -58,7 +65,8 @@ public class FormFieldData {
private FormFieldData(String name, String label, String value, String autocompleteAttr,
boolean shouldAutocomplete, String placeholder, String type, String id,
String[] optionValues, String[] optionContents, boolean isCheckField, boolean isChecked,
- int maxLength, String heuristicType, float left, float top, float right, float bottom) {
+ int maxLength, String heuristicType, float left, float top, float right, float bottom,
+ String[] datalistValues, String[] datalistLabels) {
mName = name;
mLabel = label;
mValue = value;
@@ -70,8 +78,12 @@ public class FormFieldData {
mOptionValues = optionValues;
mOptionContents = optionContents;
mIsChecked = isChecked;
+ mDatalistLabels = datalistLabels;
+ mDatalistValues = datalistValues;
if (mOptionValues != null && mOptionValues.length != 0) {
mControlType = ControlType.LIST;
+ } else if (mDatalistValues != null && mDatalistValues.length != 0) {
+ mControlType = ControlType.DATALIST;
} else if (isCheckField) {
mControlType = ControlType.TOGGLE;
} else {
@@ -142,9 +154,9 @@ public class FormFieldData {
String autocompleteAttr, boolean shouldAutocomplete, String placeholder, String type,
String id, String[] optionValues, String[] optionContents, boolean isCheckField,
boolean isChecked, int maxLength, String heuristicType, float left, float top,
- float right, float bottom) {
+ float right, float bottom, String[] datalistValues, String[] datalistLabels) {
return new FormFieldData(name, label, value, autocompleteAttr, shouldAutocomplete,
placeholder, type, id, optionValues, optionContents, isCheckField, isChecked,
- maxLength, heuristicType, left, top, right, bottom);
+ maxLength, heuristicType, left, top, right, bottom, datalistValues, datalistLabels);
}
}
diff --git a/chromium/components/autofill/android/junit/BUILD.gn b/chromium/components/autofill/android/provider/junit/BUILD.gn
index 0f58b8ac6fa..95cea50bf90 100644
--- a/chromium/components/autofill/android/junit/BUILD.gn
+++ b/chromium/components/autofill/android/provider/junit/BUILD.gn
@@ -9,13 +9,15 @@ java_library("components_autofill_junit_tests") {
# Platform checks are broken for Robolectric. See https://crbug.com/1071638.
bypass_platform_checks = true
testonly = true
- sources =
- [ "src/org/chromium/components/autofill/AutofillProviderImplTest.java" ]
+ sources = [ "src/org/chromium/components/autofill/AutofillProviderTest.java" ]
deps = [
"//base:base_java_test_support",
"//base:base_junit_test_support",
- "//components/autofill/android:provider_java",
+ "//components/autofill/android/provider:java",
"//content/public/android:content_java",
+ "//third_party/android_deps:robolectric_all_java",
+ "//third_party/junit",
+ "//third_party/mockito:mockito_java",
"//ui/android:ui_java",
]
}
diff --git a/chromium/components/autofill/android/junit/src/org/chromium/components/autofill/AutofillProviderImplTest.java b/chromium/components/autofill/android/provider/junit/src/org/chromium/components/autofill/AutofillProviderTest.java
index d8c8c2bfd3d..e4b12cec808 100644
--- a/chromium/components/autofill/android/junit/src/org/chromium/components/autofill/AutofillProviderImplTest.java
+++ b/chromium/components/autofill/android/provider/junit/src/org/chromium/components/autofill/AutofillProviderTest.java
@@ -31,11 +31,11 @@ import org.chromium.ui.display.DisplayAndroid;
import java.util.ArrayList;
/**
- * The unit tests for AutofillProviderImpl.
+ * The unit tests for AutofillProvider.
*/
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
-public class AutofillProviderImplTest {
+public class AutofillProviderTest {
private static final float EXPECTED_DIP_SCALE = 2;
private static final int SCROLL_X = 15;
private static final int SCROLL_Y = 155;
@@ -46,7 +46,7 @@ public class AutofillProviderImplTest {
private WindowAndroid mWindowAndroid;
private WebContents mWebContents;
private ViewGroup mContainerView;
- private AutofillProviderImpl mAutofillProvider;
+ private AutofillProvider mAutofillProvider;
private DisplayAndroid mDisplayAndroid;
@Before
@@ -57,8 +57,7 @@ public class AutofillProviderImplTest {
mDisplayAndroid = Mockito.mock(DisplayAndroid.class);
mWebContents = Mockito.mock(WebContents.class);
mContainerView = Mockito.mock(ViewGroup.class);
- mAutofillProvider =
- new AutofillProviderImpl(mContext, mContainerView, "AutofillProviderImplTest");
+ mAutofillProvider = new AutofillProvider(mContext, mContainerView, "AutofillProviderTest");
mAutofillProvider.setWebContents(mWebContents);
when(mWebContents.getTopLevelNativeWindow()).thenReturn(mWindowAndroid);
@@ -85,10 +84,10 @@ public class AutofillProviderImplTest {
ArrayList<FormFieldData> fields = new ArrayList<FormFieldData>(1);
fields.add(FormFieldData.createFormFieldData(null, null, null, null, false, null, null,
null, null, null, false, false, 0, null, 10 /* left */, 20 /* top */,
- 300 /* right */, 60 /*bottom*/));
+ 300 /* right */, 60 /*bottom*/, null, null));
fields.add(FormFieldData.createFormFieldData(null, null, null, null, false, null, null,
null, null, null, false, false, 0, null, 20 /* left */, 100 /* top */,
- 400 /* right */, 200 /*bottom*/));
+ 400 /* right */, 200 /*bottom*/, null, null));
FormData formData = new FormData(null, null, fields);
mAutofillProvider.transformFormFieldToContainViewCoordinates(formData);
RectF result = formData.mFields.get(0).getBoundsInContainerViewCoordinates();