summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/android/java
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/autofill/android/java
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/autofill/android/java')
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java60
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java206
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProvider.java157
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderImpl.java540
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java255
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java56
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java150
7 files changed, 0 insertions, 1424 deletions
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java
deleted file mode 100644
index 6921fcab52c..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java
+++ /dev/null
@@ -1,60 +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.content.Context;
-import android.view.ActionMode;
-import android.view.Menu;
-import android.view.MenuItem;
-
-/**
- * The class to implement autofill context menu. To match the Android native view behavior, the
- * autofill context menu only appears when there is no text selected.
- */
-public class AutofillActionModeCallback implements ActionMode.Callback {
- private final Context mContext;
- private final AutofillProvider mAutofillProvider;
- private final int mAutofillMenuItemTitle;
- private final int mAutofillMenuItem;
-
- public AutofillActionModeCallback(Context context, AutofillProvider autofillProvider) {
- mContext = context;
- mAutofillProvider = autofillProvider;
- // TODO(michaelbai): Uses the resource directly after sdk roll to Android O MR1.
- // crbug.com/740628
- mAutofillMenuItemTitle =
- mContext.getResources().getIdentifier("autofill", "string", "android");
- mAutofillMenuItem = mContext.getResources().getIdentifier("autofill", "id", "android");
- }
-
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- return mAutofillMenuItemTitle != 0 && mAutofillMenuItem != 0;
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- if (mAutofillMenuItemTitle != 0 && mAutofillProvider.shouldQueryAutofillSuggestion()) {
- MenuItem item = menu.add(
- Menu.NONE, mAutofillMenuItem, Menu.CATEGORY_SECONDARY, mAutofillMenuItemTitle);
- item.setShowAsActionFlags(
- MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- }
- return true;
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- if (item.getItemId() == mAutofillMenuItem) {
- mAutofillProvider.queryAutofillSuggestion();
- mode.finish();
- return true;
- }
- return false;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {}
-}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
deleted file mode 100644
index 0287ac38f97..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
+++ /dev/null
@@ -1,206 +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.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Build;
-import android.view.View;
-import android.view.autofill.AutofillManager;
-import android.view.autofill.AutofillValue;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Log;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * The class to call Android's AutofillManager.
- */
-@TargetApi(Build.VERSION_CODES.O)
-public class AutofillManagerWrapper {
- // Don't change TAG, it is used for runtime log.
- // NOTE: As a result of the above, the tag below still references the name of this class from
- // when it was originally developed specifically for Android WebView.
- public static final String TAG = "AwAutofillManager";
-
- /**
- * The observer of suggestion window.
- */
- public static interface InputUIObserver { void onInputUIShown(); }
-
- private static class AutofillInputUIMonitor extends AutofillManager.AutofillCallback {
- private WeakReference<AutofillManagerWrapper> mManager;
-
- public AutofillInputUIMonitor(AutofillManagerWrapper manager) {
- mManager = new WeakReference<AutofillManagerWrapper>(manager);
- }
-
- @Override
- public void onAutofillEvent(View view, int virtualId, int event) {
- AutofillManagerWrapper manager = mManager.get();
- if (manager == null) return;
- manager.mIsAutofillInputUIShowing = (event == EVENT_INPUT_SHOWN);
- if (event == EVENT_INPUT_SHOWN) manager.notifyInputUIChange();
- }
- }
-
- private static boolean sIsLoggable;
- private AutofillManager mAutofillManager;
- private boolean mIsAutofillInputUIShowing;
- private AutofillInputUIMonitor mMonitor;
- private boolean mDestroyed;
- private boolean mDisabled;
- private ArrayList<WeakReference<InputUIObserver>> mInputUIObservers;
-
- public AutofillManagerWrapper(Context context) {
- updateLogStat();
- if (isLoggable()) log("constructor");
- mAutofillManager = context.getSystemService(AutofillManager.class);
- mDisabled = mAutofillManager == null || !mAutofillManager.isEnabled();
- if (mDisabled) {
- if (isLoggable()) log("disabled");
- return;
- }
-
- mMonitor = new AutofillInputUIMonitor(this);
- mAutofillManager.registerCallback(mMonitor);
- }
-
- public void notifyVirtualValueChanged(View parent, int childId, AutofillValue value) {
- if (mDisabled || checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("notifyVirtualValueChanged");
- mAutofillManager.notifyValueChanged(parent, childId, value);
- }
-
- public void commit(int submissionSource) {
- if (mDisabled || checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("commit source:" + submissionSource);
- mAutofillManager.commit();
- }
-
- public void cancel() {
- if (mDisabled || checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("cancel");
- mAutofillManager.cancel();
- }
-
- public void notifyVirtualViewEntered(View parent, int childId, Rect absBounds) {
- // Log warning only when the autofill is triggered.
- if (mDisabled) {
- Log.w(TAG, "Autofill is disabled: AutofillManager isn't available in given Context.");
- return;
- }
- if (checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("notifyVirtualViewEntered");
- mAutofillManager.notifyViewEntered(parent, childId, absBounds);
- }
-
- public void notifyVirtualViewExited(View parent, int childId) {
- if (mDisabled || checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("notifyVirtualViewExited");
- mAutofillManager.notifyViewExited(parent, childId);
- }
-
- public void requestAutofill(View parent, int virtualId, Rect absBounds) {
- if (mDisabled || checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("requestAutofill");
- mAutofillManager.requestAutofill(parent, virtualId, absBounds);
- }
-
- public boolean isAutofillInputUIShowing() {
- if (mDisabled || checkAndWarnIfDestroyed()) return false;
- if (isLoggable()) log("isAutofillInputUIShowing: " + mIsAutofillInputUIShowing);
- return mIsAutofillInputUIShowing;
- }
-
- public void destroy() {
- if (mDisabled || checkAndWarnIfDestroyed()) return;
- if (isLoggable()) log("destroy");
- try {
- // The binder in the autofill service side might already be dropped,
- // unregisterCallback() will cause various exceptions in this
- // scenario (see crbug.com/1078337), catching RuntimeException here prevents crash.
- mAutofillManager.unregisterCallback(mMonitor);
- } catch (RuntimeException e) {
- // We are not logging anything here since some of the exceptions are raised as 'generic'
- // RuntimeException which makes it difficult to catch and ignore separately; and the
- // RuntimeException seemed only happen in Android O, therefore, isn't actionable.
- } finally {
- mAutofillManager = null;
- mDestroyed = true;
- }
- }
-
- public boolean isDisabled() {
- return mDisabled;
- }
-
- private boolean checkAndWarnIfDestroyed() {
- if (mDestroyed) {
- Log.w(TAG, "Application attempted to call on a destroyed AutofillManagerWrapper",
- new Throwable());
- }
- return mDestroyed;
- }
-
- public void addInputUIObserver(InputUIObserver observer) {
- if (observer == null) return;
- if (mInputUIObservers == null) {
- mInputUIObservers = new ArrayList<WeakReference<InputUIObserver>>();
- }
- mInputUIObservers.add(new WeakReference<InputUIObserver>(observer));
- }
-
- public void removeInputUIObserver(InputUIObserver observer) {
- if (observer == null) return;
- for (Iterator<WeakReference<InputUIObserver>> i = mInputUIObservers.listIterator();
- i.hasNext();) {
- WeakReference<InputUIObserver> o = i.next();
- if (o.get() == null || o.get() == observer) i.remove();
- }
- }
-
- @VisibleForTesting
- public void notifyInputUIChange() {
- for (Iterator<WeakReference<InputUIObserver>> i = mInputUIObservers.listIterator();
- i.hasNext();) {
- WeakReference<InputUIObserver> o = i.next();
- InputUIObserver observer = o.get();
- if (observer == null) {
- i.remove();
- continue;
- }
- observer.onInputUIShown();
- }
- }
-
- public void notifyNewSessionStarted() {
- updateLogStat();
- if (isLoggable()) log("Session starts");
- }
-
- /**
- * Always check isLoggable() before call this method.
- */
- public static void log(String log) {
- // Log.i() instead of Log.d() is used here because log.d() is stripped out in release build.
- Log.i(TAG, log);
- }
-
- public static boolean isLoggable() {
- return sIsLoggable;
- }
-
- private static void updateLogStat() {
- // Use 'setprop log.tag.AwAutofillManager DEBUG' to enable the log at runtime.
- // NOTE: See the comment on TAG above for why this is still AwAutofillManager.
- sIsLoggable = Log.isLoggable(TAG, Log.DEBUG);
- }
-}
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/java/src/org/chromium/components/autofill/AutofillProviderImpl.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderImpl.java
deleted file mode 100644
index e53188067c3..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderImpl.java
+++ /dev/null
@@ -1,540 +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.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStructure;
-import android.view.autofill.AutofillValue;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Log;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.DoNotInline;
-import org.chromium.base.metrics.ScopedSysTraceEvent;
-import org.chromium.components.version_info.VersionConstants;
-import org.chromium.content_public.browser.WebContents;
-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 doesn't have 1:1 mapping to native AutofillProviderAndroid; the
- * normal ownership model is that this object is owned by the embedder-specific
- * Java WebContents wrapper (e.g., AwContents.java in //android_webview), and
- * 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.
- */
-@DoNotInline
-@TargetApi(Build.VERSION_CODES.O)
-public class AutofillProviderImpl extends AutofillProvider {
- private static final String TAG = "AutofillProviderImpl";
- private static class FocusField {
- public final short fieldIndex;
- public final Rect absBound;
-
- public FocusField(short fieldIndex, Rect absBound) {
- this.fieldIndex = fieldIndex;
- this.absBound = absBound;
- }
- }
- /**
- * The class to wrap the request to framework.
- *
- * Though framework guarantees always giving us the autofill value of current
- * session, we still want to verify this by using unique virtual id which is
- * composed of sessionId and form field index, we don't use the request id
- * which comes from renderer as session id because it is not unique.
- */
- private static class AutofillRequest {
- private static final int INIT_ID = 1; // ID can't be 0 in Android.
- private static int sSessionId = INIT_ID;
- public final int sessionId;
- private FormData mFormData;
- private FocusField mFocusField;
-
- public AutofillRequest(FormData formData, FocusField focus) {
- sessionId = getNextClientId();
- mFormData = formData;
- mFocusField = focus;
- }
-
- public void fillViewStructure(ViewStructure structure) {
- structure.setWebDomain(mFormData.mHost);
- structure.setHtmlInfo(structure.newHtmlInfoBuilder("form")
- .addAttribute("name", mFormData.mName)
- .build());
- int index = structure.addChildCount(mFormData.mFields.size());
- short fieldIndex = 0;
- for (FormFieldData field : mFormData.mFields) {
- ViewStructure child = structure.newChild(index++);
- int virtualId = toVirtualId(sessionId, fieldIndex++);
- child.setAutofillId(structure.getAutofillId(), virtualId);
- if (field.mAutocompleteAttr != null && !field.mAutocompleteAttr.isEmpty()) {
- child.setAutofillHints(field.mAutocompleteAttr.split(" +"));
- }
- child.setHint(field.mPlaceholder);
-
- RectF bounds = field.getBoundsInContainerViewCoordinates();
- // Field has no scroll.
- child.setDimens((int) bounds.left, (int) bounds.top, 0 /* scrollX*/,
- 0 /* scrollY */, (int) bounds.width(), (int) bounds.height());
-
- ViewStructure.HtmlInfo.Builder builder =
- child.newHtmlInfoBuilder("input")
- .addAttribute("name", field.mName)
- .addAttribute("type", field.mType)
- .addAttribute("label", field.mLabel)
- .addAttribute("ua-autofill-hints", field.mHeuristicType)
- .addAttribute("id", field.mId);
-
- switch (field.getControlType()) {
- case FormFieldData.ControlType.LIST:
- child.setAutofillType(View.AUTOFILL_TYPE_LIST);
- child.setAutofillOptions(field.mOptionContents);
- int i = findIndex(field.mOptionValues, field.getValue());
- if (i != -1) {
- child.setAutofillValue(AutofillValue.forList(i));
- }
- break;
- case FormFieldData.ControlType.TOGGLE:
- child.setAutofillType(View.AUTOFILL_TYPE_TOGGLE);
- child.setAutofillValue(AutofillValue.forToggle(field.isChecked()));
- break;
- case FormFieldData.ControlType.TEXT:
- child.setAutofillType(View.AUTOFILL_TYPE_TEXT);
- child.setAutofillValue(AutofillValue.forText(field.getValue()));
- if (field.mMaxLength != 0) {
- builder.addAttribute("maxlength", String.valueOf(field.mMaxLength));
- }
- break;
- default:
- break;
- }
- child.setHtmlInfo(builder.build());
- }
- }
-
- public boolean autofill(final SparseArray<AutofillValue> values) {
- for (int i = 0; i < values.size(); ++i) {
- int id = values.keyAt(i);
- if (toSessionId(id) != sessionId) return false;
- AutofillValue value = values.get(id);
- if (value == null) continue;
- short index = toIndex(id);
- if (index < 0 || index >= mFormData.mFields.size()) return false;
- FormFieldData field = mFormData.mFields.get(index);
- if (field == null) return false;
- try {
- switch (field.getControlType()) {
- case FormFieldData.ControlType.LIST:
- int j = value.getListValue();
- if (j < 0 && j >= field.mOptionValues.length) continue;
- field.setAutofillValue(field.mOptionValues[j]);
- break;
- case FormFieldData.ControlType.TOGGLE:
- field.setChecked(value.getToggleValue());
- break;
- case FormFieldData.ControlType.TEXT:
- field.setAutofillValue((String) value.getTextValue());
- break;
- default:
- break;
- }
- } catch (IllegalStateException e) {
- // Refer to crbug.com/1080580 .
- Log.e(TAG, "The given AutofillValue wasn't expected, abort autofill.", e);
- return false;
- }
- }
- return true;
- }
-
- public void setFocusField(FocusField focusField) {
- mFocusField = focusField;
- }
-
- public FocusField getFocusField() {
- return mFocusField;
- }
-
- public int getFieldCount() {
- return mFormData.mFields.size();
- }
-
- public AutofillValue getFieldNewValue(int index) {
- FormFieldData field = mFormData.mFields.get(index);
- if (field == null) return null;
- switch (field.getControlType()) {
- case FormFieldData.ControlType.LIST:
- int i = findIndex(field.mOptionValues, field.getValue());
- if (i == -1) return null;
- return AutofillValue.forList(i);
- case FormFieldData.ControlType.TOGGLE:
- return AutofillValue.forToggle(field.isChecked());
- case FormFieldData.ControlType.TEXT:
- return AutofillValue.forText(field.getValue());
- default:
- return null;
- }
- }
-
- public int getVirtualId(short index) {
- return toVirtualId(sessionId, index);
- }
-
- public FormFieldData getField(short index) {
- return mFormData.mFields.get(index);
- }
-
- private static int findIndex(String[] values, String value) {
- if (values != null && value != null) {
- for (int i = 0; i < values.length; i++) {
- if (value.equals(values[i])) return i;
- }
- }
- return -1;
- }
-
- private static int getNextClientId() {
- ThreadUtils.assertOnUiThread();
- if (sSessionId == 0xffff) sSessionId = INIT_ID;
- return sSessionId++;
- }
-
- private static int toSessionId(int virtualId) {
- return (virtualId & 0xffff0000) >> 16;
- }
-
- private static short toIndex(int virtualId) {
- return (short) (virtualId & 0xffff);
- }
-
- private static int toVirtualId(int clientId, short index) {
- return (clientId << 16) | index;
- }
- }
-
- private final String mProviderName;
- private AutofillManagerWrapper mAutofillManager;
- private ViewGroup mContainerView;
- private WebContents mWebContents;
-
- private AutofillRequest mRequest;
- private long mNativeAutofillProvider;
- private AutofillProviderUMA mAutofillUMA;
- private AutofillManagerWrapper.InputUIObserver mInputUIObserver;
- private long mAutofillTriggeredTimeMillis;
-
- public AutofillProviderImpl(Context context, ViewGroup containerView, String providerName) {
- this(containerView, new AutofillManagerWrapper(context), context, providerName);
- }
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- public AutofillProviderImpl(ViewGroup containerView, AutofillManagerWrapper manager,
- Context context, String providerName) {
- mProviderName = providerName;
- try (ScopedSysTraceEvent e =
- ScopedSysTraceEvent.scoped("AutofillProviderImpl.constructor")) {
- assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
- mAutofillManager = manager;
- mContainerView = containerView;
- mAutofillUMA = new AutofillProviderUMA(context);
- mInputUIObserver = new AutofillManagerWrapper.InputUIObserver() {
- @Override
- public void onInputUIShown() {
- // Not need to report suggestion window displayed if there is no live autofill
- // session.
- if (mRequest == null) return;
- mAutofillUMA.onSuggestionDisplayed(
- System.currentTimeMillis() - mAutofillTriggeredTimeMillis);
- }
- };
- mAutofillManager.addInputUIObserver(mInputUIObserver);
- }
- }
-
- @Override
- public void onContainerViewChanged(ViewGroup containerView) {
- mContainerView = containerView;
- }
-
- @Override
- 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
- // return.
- if (mRequest == null) return;
-
- Bundle bundle = structure.getExtras();
- if (bundle != null) {
- bundle.putCharSequence("VIRTUAL_STRUCTURE_PROVIDER_NAME", mProviderName);
- bundle.putCharSequence(
- "VIRTUAL_STRUCTURE_PROVIDER_VERSION", VersionConstants.PRODUCT_VERSION);
- }
- mRequest.fillViewStructure(structure);
- if (AutofillManagerWrapper.isLoggable()) {
- AutofillManagerWrapper.log(
- "onProvideAutoFillVirtualStructure fields:" + structure.getChildCount());
- }
- mAutofillUMA.onVirtualStructureProvided();
- }
-
- @Override
- public void autofill(final SparseArray<AutofillValue> values) {
- if (mNativeAutofillProvider != 0 && mRequest != null && mRequest.autofill((values))) {
- autofill(mNativeAutofillProvider, mRequest.mFormData);
- if (AutofillManagerWrapper.isLoggable()) {
- AutofillManagerWrapper.log("autofill values:" + values.size());
- }
- mAutofillUMA.onAutofill();
- }
- }
-
- @Override
- public boolean shouldQueryAutofillSuggestion() {
- return mRequest != null && mRequest.getFocusField() != null
- && !mAutofillManager.isAutofillInputUIShowing();
- }
-
- @Override
- public void queryAutofillSuggestion() {
- if (shouldQueryAutofillSuggestion()) {
- FocusField focusField = mRequest.getFocusField();
- mAutofillManager.requestAutofill(mContainerView,
- mRequest.getVirtualId(focusField.fieldIndex), focusField.absBound);
- }
- }
-
- @Override
- 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,
- // 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();
- transformFormFieldToContainViewCoordinates(formData);
- mRequest = new AutofillRequest(formData, new FocusField((short) focus, absBound));
- int virtualId = mRequest.getVirtualId((short) focus);
- mAutofillManager.notifyVirtualViewEntered(mContainerView, virtualId, absBound);
- mAutofillUMA.onSessionStarted(mAutofillManager.isDisabled());
- mAutofillTriggeredTimeMillis = System.currentTimeMillis();
- }
-
- @Override
- public void onFormFieldDidChange(int index, float x, float y, float width, float height) {
- // Check index inside short value?
- if (mRequest == null) return;
-
- short sIndex = (short) index;
- FocusField focusField = mRequest.getFocusField();
- if (focusField == null || sIndex != focusField.fieldIndex) {
- onFocusChangedImpl(true, index, x, y, width, height, true /*causedByValueChange*/);
- } else {
- // Currently there is no api to notify both value and position
- // change, before the API is available, we still need to call
- // notifyVirtualViewEntered() to tell current coordinates because
- // the position could be changed.
- 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);
- // Update focus field position.
- mRequest.setFocusField(new FocusField(focusField.fieldIndex, absBound));
- }
- }
- notifyVirtualValueChanged(index);
- mAutofillUMA.onUserChangeFieldValue(mRequest.getField(sIndex).hasPreviouslyAutofilled());
- }
-
- @Override
- 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.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) return;
- if (mRequest == null) return;
-
- short sIndex = (short) index;
- FocusField focusField = mRequest.getFocusField();
- if (focusField == null || sIndex != focusField.fieldIndex) return;
-
- int virtualId = mRequest.getVirtualId(sIndex);
- 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);
-
- // Update focus field position.
- mRequest.setFocusField(new FocusField(focusField.fieldIndex, absBound));
- }
-
- private void notifyVirtualValueChanged(int index) {
- AutofillValue autofillValue = mRequest.getFieldNewValue(index);
- if (autofillValue == null) return;
- mAutofillManager.notifyVirtualValueChanged(
- mContainerView, mRequest.getVirtualId((short) index), autofillValue);
- }
-
- @Override
- 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();
- mAutofillManager.commit(submissionSource);
- mRequest = null;
- mAutofillUMA.onFormSubmitted(submissionSource);
- }
-
- @Override
- 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() {
- if (mRequest == null) return;
- FocusField focusField = mRequest.getFocusField();
- if (focusField == null) return;
- mAutofillManager.notifyVirtualViewExited(
- mContainerView, mRequest.getVirtualId(focusField.fieldIndex));
- mRequest.setFocusField(null);
- }
-
- private void onFocusChangedImpl(boolean focusOnForm, int focusField, float x, float y,
- float width, float height, boolean causedByValueChange) {
- // Check focusField inside short value?
- // FocusNoLongerOnForm is called after form submitted.
- if (mRequest == null) return;
- FocusField prev = mRequest.getFocusField();
- if (focusOnForm) {
- Rect absBound = transformToWindowBounds(new RectF(x, y, x + width, y + height));
- if (prev != null && prev.fieldIndex == focusField && absBound.equals(prev.absBound)) {
- return;
- }
-
- // Notify focus changed.
- if (prev != null) {
- mAutofillManager.notifyVirtualViewExited(
- mContainerView, mRequest.getVirtualId(prev.fieldIndex));
- }
-
- mAutofillManager.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);
- 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));
- mRequest.setFocusField(null);
- }
- }
-
- @Override
- 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
- protected void setNativeAutofillProvider(long nativeAutofillProvider) {
- if (nativeAutofillProvider == mNativeAutofillProvider) return;
- // Setting the mNativeAutofillProvider to 0 may occur as a
- // result of WebView.destroy, or because a WebView has been
- // gc'ed. In the former case we can go ahead and clean up the
- // frameworks autofill manager, but in the latter case the
- // binder connection has already been dropped in a framework
- // finalizer, and so the methods we call will throw. It's not
- // possible to know which case we're in, so just catch the exception
- // in AutofillManagerWrapper.destroy().
- if (mNativeAutofillProvider != 0) mRequest = null;
- mNativeAutofillProvider = nativeAutofillProvider;
- if (nativeAutofillProvider == 0) mAutofillManager.destroy();
- }
-
- @Override
- public void setWebContents(WebContents webContents) {
- if (webContents == mWebContents) return;
- if (mWebContents != null) mRequest = null;
- mWebContents = webContents;
- }
-
- @Override
- protected void onDidFillAutofillFormData() {
- notifyFormValues();
- }
-
- private void notifyFormValues() {
- if (mRequest == null) return;
- for (int i = 0; i < mRequest.getFieldCount(); ++i) notifyVirtualValueChanged(i);
- }
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- public Rect transformToWindowBounds(RectF rect) {
- // Convert bounds to device pixel.
- WindowAndroid windowAndroid = mWebContents.getTopLevelNativeWindow();
- DisplayAndroid displayAndroid = windowAndroid.getDisplay();
- float dipScale = displayAndroid.getDipScale();
- RectF bounds = new RectF(rect);
- Matrix matrix = new Matrix();
- matrix.setScale(dipScale, dipScale);
- int[] location = new int[2];
- mContainerView.getLocationOnScreen(location);
- matrix.postTranslate(location[0], location[1]);
- matrix.mapRect(bounds);
- return new Rect(
- (int) bounds.left, (int) bounds.top, (int) bounds.right, (int) bounds.bottom);
- }
-
- /**
- * Transform FormFieldData's bounds to ContainView's coordinates and update the bounds with the
- * transformed one.
- *
- * @param formData the form need to be transformed.
- */
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- public void transformFormFieldToContainViewCoordinates(FormData formData) {
- WindowAndroid windowAndroid = mWebContents.getTopLevelNativeWindow();
- DisplayAndroid displayAndroid = windowAndroid.getDisplay();
- float dipScale = displayAndroid.getDipScale();
- Matrix matrix = new Matrix();
- matrix.setScale(dipScale, dipScale);
- matrix.postTranslate(mContainerView.getScrollX(), mContainerView.getScrollY());
-
- for (FormFieldData field : formData.mFields) {
- RectF bounds = new RectF();
- matrix.mapRect(bounds, field.getBounds());
- field.setBoundsInContainerViewCoordinates(bounds);
- }
- }
-}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java
deleted file mode 100644
index 394cd849c95..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/AutofillProviderUMA.java
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2018 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.content.Context;
-
-import org.chromium.autofill.mojom.SubmissionSource;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.metrics.RecordHistogram;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * The class for AutofillProvider-related UMA. Note that most of the concrete histogram
- * names include "WebView"; when this class was originally developed it was WebView-specific,
- * and when generalizing it we did not change these names to maintain continuity when
- * analyzing the histograms.
- */
-public class AutofillProviderUMA {
- // Records whether the Autofill service is enabled or not.
- public static final String UMA_AUTOFILL_ENABLED = "Autofill.WebView.Enabled";
-
- // Records whether the Autofill provider is created by activity context or not.
- public static final String UMA_AUTOFILL_CREATED_BY_ACTIVITY_CONTEXT =
- "Autofill.WebView.CreatedByActivityContext";
-
- // Records what happened in an autofill session.
- public static final String UMA_AUTOFILL_AUTOFILL_SESSION = "Autofill.WebView.AutofillSession";
- // The possible value of UMA_AUTOFILL_AUTOFILL_SESSION.
- public static final int SESSION_UNKNOWN = 0;
- public static final int NO_CALLBACK_FORM_FRAMEWORK = 1;
- public static final int NO_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED = 2;
- public static final int NO_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED = 3;
- public static final int NO_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED = 4;
- public static final int NO_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 5;
- public static final int USER_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED = 6;
- public static final int USER_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED = 7;
- public static final int USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED = 8;
- public static final int USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 9;
- public static final int USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED = 10;
- public static final int USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED = 11;
- public static final int USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED = 12;
- public static final int USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 13;
- public static final int AUTOFILL_SESSION_HISTOGRAM_COUNT = 14;
-
- // Records whether user changed autofilled field if user ever changed the form. The action isn't
- // recorded if user didn't change form at all.
- public static final String UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD =
- "Autofill.WebView.UserChangedAutofilledField";
-
- public static final String UMA_AUTOFILL_SUBMISSION_SOURCE = "Autofill.WebView.SubmissionSource";
- // The possible value of UMA_AUTOFILL_SUBMISSION_SOURCE.
- public static final int SAME_DOCUMENT_NAVIGATION = 0;
- public static final int XHR_SUCCEEDED = 1;
- public static final int FRAME_DETACHED = 2;
- public static final int DOM_MUTATION_AFTER_XHR = 3;
- public static final int PROBABLY_FORM_SUBMITTED = 4;
- public static final int FORM_SUBMISSION = 5;
- public static final int SUBMISSION_SOURCE_HISTOGRAM_COUNT = 6;
-
- // The million seconds from user touched the field to the autofill session starting.
- public static final String UMA_AUTOFILL_TRIGGERING_TIME = "Autofill.WebView.TriggeringTime";
-
- // The million seconds from the autofill session starting to the suggestion being displayed.
- public static final String UMA_AUTOFILL_SUGGESTION_TIME = "Autofill.WebView.SuggestionTime";
-
- // The expected time range of time is from 10ms to 2 seconds, and 50 buckets is sufficient.
- private static final long MIN_TIME_MILLIS = 10;
- private static final long MAX_TIME_MILLIS = TimeUnit.SECONDS.toMillis(2);
- private static final int NUM_OF_BUCKETS = 50;
-
- private static void recordTimesHistogram(String name, long durationMillis) {
- RecordHistogram.recordCustomTimesHistogram(
- name, durationMillis, MIN_TIME_MILLIS, MAX_TIME_MILLIS, NUM_OF_BUCKETS);
- }
-
- private static class SessionRecorder {
- public static final int EVENT_VIRTUAL_STRUCTURE_PROVIDED = 0x1 << 0;
- public static final int EVENT_SUGGESTION_DISPLAYED = 0x1 << 1;
- public static final int EVENT_FORM_AUTOFILLED = 0x1 << 2;
- public static final int EVENT_USER_CHANGED_FIELD_VALUE = 0x1 << 3;
- public static final int EVENT_FORM_SUBMITTED = 0x1 << 4;
- public static final int EVENT_USER_CHANGED_AUTOFILLED_FIELD = 0x1 << 5;
-
- private Long mSuggestionTimeMillis;
-
- public void record(int event) {
- // Not record any event until we get EVENT_VIRTUAL_STRUCTURE_PROVIDED which makes the
- // following events meaningful.
- if (event != EVENT_VIRTUAL_STRUCTURE_PROVIDED && mState == 0) return;
- if (EVENT_USER_CHANGED_FIELD_VALUE == event && mUserChangedAutofilledField == null) {
- mUserChangedAutofilledField = Boolean.valueOf(false);
- } else if (EVENT_USER_CHANGED_AUTOFILLED_FIELD == event) {
- if (mUserChangedAutofilledField == null) {
- mUserChangedAutofilledField = Boolean.valueOf(true);
- }
- mUserChangedAutofilledField = true;
- event = EVENT_USER_CHANGED_FIELD_VALUE;
- }
- mState |= event;
- }
-
- public void setSuggestionTimeMillis(long suggestionTimeMillis) {
- // Only record first suggestion.
- if (mSuggestionTimeMillis == null) {
- mSuggestionTimeMillis = Long.valueOf(suggestionTimeMillis);
- }
- }
-
- public void recordHistogram() {
- RecordHistogram.recordEnumeratedHistogram(UMA_AUTOFILL_AUTOFILL_SESSION,
- toUMAAutofillSessionValue(), AUTOFILL_SESSION_HISTOGRAM_COUNT);
- // Only record if user ever changed form.
- if (mUserChangedAutofilledField != null) {
- RecordHistogram.recordBooleanHistogram(
- UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD, mUserChangedAutofilledField);
- }
- if (mSuggestionTimeMillis != null) {
- recordTimesHistogram(UMA_AUTOFILL_SUGGESTION_TIME, mSuggestionTimeMillis);
- }
- }
-
- private int toUMAAutofillSessionValue() {
- if (mState == 0) {
- return NO_CALLBACK_FORM_FRAMEWORK;
- } else if (mState == EVENT_VIRTUAL_STRUCTURE_PROVIDED) {
- return NO_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_USER_CHANGED_FIELD_VALUE)) {
- return NO_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED;
- } else if (mState == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_FORM_SUBMITTED)) {
- return NO_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_USER_CHANGED_FIELD_VALUE
- | EVENT_FORM_SUBMITTED)) {
- return NO_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_FORM_AUTOFILLED)) {
- return USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_FORM_AUTOFILLED | EVENT_FORM_SUBMITTED)) {
- return USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_FORM_AUTOFILLED | EVENT_USER_CHANGED_FIELD_VALUE
- | EVENT_FORM_SUBMITTED)) {
- return USER_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_FORM_AUTOFILLED | EVENT_USER_CHANGED_FIELD_VALUE)) {
- return USER_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED;
- } else if (mState == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED)) {
- return USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_FORM_SUBMITTED)) {
- return USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_USER_CHANGED_FIELD_VALUE | EVENT_FORM_SUBMITTED)) {
- return USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED;
- } else if (mState
- == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
- | EVENT_USER_CHANGED_FIELD_VALUE)) {
- return USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED;
- } else {
- return SESSION_UNKNOWN;
- }
- }
-
- private int mState;
- private Boolean mUserChangedAutofilledField;
- }
-
- private SessionRecorder mRecorder;
- private Boolean mAutofillDisabled;
-
- public AutofillProviderUMA(Context context) {
- RecordHistogram.recordBooleanHistogram(UMA_AUTOFILL_CREATED_BY_ACTIVITY_CONTEXT,
- ContextUtils.activityFromContext(context) != null);
- }
-
- public void onFormSubmitted(int submissionSource) {
- if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_FORM_SUBMITTED);
- recordSession();
- // We record this no matter autofill service is disabled or not.
- RecordHistogram.recordEnumeratedHistogram(UMA_AUTOFILL_SUBMISSION_SOURCE,
- toUMASubmissionSource(submissionSource), SUBMISSION_SOURCE_HISTOGRAM_COUNT);
- }
-
- public void onSessionStarted(boolean autofillDisabled) {
- // Record autofill status once per instance and only if user triggers the autofill.
- if (mAutofillDisabled == null || mAutofillDisabled.booleanValue() != autofillDisabled) {
- RecordHistogram.recordBooleanHistogram(UMA_AUTOFILL_ENABLED, !autofillDisabled);
- mAutofillDisabled = Boolean.valueOf(autofillDisabled);
- }
-
- if (mRecorder != null) recordSession();
- mRecorder = new SessionRecorder();
- }
-
- public void onVirtualStructureProvided() {
- if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_VIRTUAL_STRUCTURE_PROVIDED);
- }
-
- public void onSuggestionDisplayed(long suggestionTimeMillis) {
- if (mRecorder != null) {
- mRecorder.record(SessionRecorder.EVENT_SUGGESTION_DISPLAYED);
- mRecorder.setSuggestionTimeMillis(suggestionTimeMillis);
- }
- }
-
- public void onAutofill() {
- if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_FORM_AUTOFILLED);
- }
-
- public void onUserChangeFieldValue(boolean isPreviouslyAutofilled) {
- if (mRecorder == null) return;
- if (isPreviouslyAutofilled) {
- mRecorder.record(SessionRecorder.EVENT_USER_CHANGED_AUTOFILLED_FIELD);
- } else {
- mRecorder.record(SessionRecorder.EVENT_USER_CHANGED_FIELD_VALUE);
- }
- }
-
- private void recordSession() {
- if (mAutofillDisabled != null && !mAutofillDisabled.booleanValue() && mRecorder != null) {
- mRecorder.recordHistogram();
- }
- mRecorder = null;
- }
-
- private int toUMASubmissionSource(int source) {
- switch (source) {
- case SubmissionSource.SAME_DOCUMENT_NAVIGATION:
- return SAME_DOCUMENT_NAVIGATION;
- case SubmissionSource.XHR_SUCCEEDED:
- return XHR_SUCCEEDED;
- case SubmissionSource.FRAME_DETACHED:
- return FRAME_DETACHED;
- case SubmissionSource.DOM_MUTATION_AFTER_XHR:
- return DOM_MUTATION_AFTER_XHR;
- case SubmissionSource.PROBABLY_FORM_SUBMITTED:
- return PROBABLY_FORM_SUBMITTED;
- case SubmissionSource.FORM_SUBMISSION:
- return FORM_SUBMISSION;
- default:
- return SUBMISSION_SOURCE_HISTOGRAM_COUNT;
- }
- }
-}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java
deleted file mode 100644
index 8069aa887b6..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormData.java
+++ /dev/null
@@ -1,56 +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 androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-
-import java.util.ArrayList;
-
-/**
- * The wrap class of native autofill::FormDataAndroid.
- */
-@JNINamespace("autofill")
-public class FormData {
- public final String mName;
- public final String mHost;
- public final ArrayList<FormFieldData> mFields;
-
- @CalledByNative
- private static FormData createFormData(
- long nativeObj, String name, String origin, int fieldCount) {
- return new FormData(nativeObj, name, origin, fieldCount);
- }
-
- private static ArrayList<FormFieldData> popupFormFields(long nativeObj, int fieldCount) {
- FormFieldData formFieldData = FormDataJni.get().getNextFormFieldData(nativeObj);
- ArrayList<FormFieldData> fields = new ArrayList<FormFieldData>(fieldCount);
- while (formFieldData != null) {
- fields.add(formFieldData);
- formFieldData = FormDataJni.get().getNextFormFieldData(nativeObj);
- }
- assert fields.size() == fieldCount;
- return fields;
- }
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- public FormData(String name, String host, ArrayList<FormFieldData> fields) {
- mName = name;
- mHost = host;
- mFields = fields;
- }
-
- private FormData(long nativeObj, String name, String host, int fieldCount) {
- this(name, host, popupFormFields(nativeObj, fieldCount));
- }
-
- @NativeMethods
- interface Natives {
- FormFieldData getNextFormFieldData(long nativeFormDataAndroid);
- }
-}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
deleted file mode 100644
index 964c73206c7..00000000000
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
+++ /dev/null
@@ -1,150 +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.graphics.RectF;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The wrap class of native autofill::FormFieldDataAndroid.
- */
-@JNINamespace("autofill")
-public class FormFieldData {
- /**
- * Define the control types supported by android.view.autofill.AutofillValue.
- */
- @IntDef({ControlType.TEXT, ControlType.TOGGLE, ControlType.LIST})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ControlType {
- int TEXT = 0;
- int TOGGLE = 1;
- int LIST = 2;
- }
-
- public final String mLabel;
- public final String mName;
- public final String mAutocompleteAttr;
- public final boolean mShouldAutocomplete;
- public final String mPlaceholder;
- public final String mType;
- public final String mId;
- public final String[] mOptionValues;
- public final String[] mOptionContents;
- public final @ControlType int mControlType;
- public final int mMaxLength;
- public final String mHeuristicType;
- // The bounds in the viewport's coordinates
- private final RectF mBounds;
- // The bounds in the container view's coordinates.
- private RectF mBoundsInContainerViewCoordinates;
-
- private boolean mIsChecked;
- private String mValue;
- // Indicates whether mValue is autofilled.
- private boolean mAutofilled;
- // Indicates whether this fields was autofilled, but changed by user.
- private boolean mPreviouslyAutofilled;
-
- 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) {
- mName = name;
- mLabel = label;
- mValue = value;
- mAutocompleteAttr = autocompleteAttr;
- mShouldAutocomplete = shouldAutocomplete;
- mPlaceholder = placeholder;
- mType = type;
- mId = id;
- mOptionValues = optionValues;
- mOptionContents = optionContents;
- mIsChecked = isChecked;
- if (mOptionValues != null && mOptionValues.length != 0) {
- mControlType = ControlType.LIST;
- } else if (isCheckField) {
- mControlType = ControlType.TOGGLE;
- } else {
- mControlType = ControlType.TEXT;
- }
- mMaxLength = maxLength;
- mHeuristicType = heuristicType;
- mBounds = new RectF(left, top, right, bottom);
- }
-
- public @ControlType int getControlType() {
- return mControlType;
- }
-
- public RectF getBounds() {
- return mBounds;
- }
-
- public void setBoundsInContainerViewCoordinates(RectF bounds) {
- mBoundsInContainerViewCoordinates = bounds;
- }
-
- public RectF getBoundsInContainerViewCoordinates() {
- return mBoundsInContainerViewCoordinates;
- }
-
- /**
- * @return value of field.
- */
- @CalledByNative
- public String getValue() {
- return mValue;
- }
-
- public void setAutofillValue(String value) {
- mValue = value;
- updateAutofillState(true);
- }
-
- public void setChecked(boolean checked) {
- mIsChecked = checked;
- updateAutofillState(true);
- }
-
- @CalledByNative
- private void updateValue(String value) {
- mValue = value;
- updateAutofillState(false);
- }
-
- @CalledByNative
- public boolean isChecked() {
- return mIsChecked;
- }
-
- public boolean hasPreviouslyAutofilled() {
- return mPreviouslyAutofilled;
- }
-
- private void updateAutofillState(boolean autofilled) {
- if (mAutofilled && !autofilled) mPreviouslyAutofilled = true;
- mAutofilled = autofilled;
- }
-
- @CalledByNative
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- public static FormFieldData createFormFieldData(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) {
- return new FormFieldData(name, label, value, autocompleteAttr, shouldAutocomplete,
- placeholder, type, id, optionValues, optionContents, isCheckField, isChecked,
- maxLength, heuristicType, left, top, right, bottom);
- }
-}