Chromium Code Reviews| Index: android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java |
| diff --git a/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java b/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0aded7854c9e429f5e164e0cece4e93d0addd9e8 |
| --- /dev/null |
| +++ b/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java |
| @@ -0,0 +1,186 @@ |
| +package org.chromium.android_webview; |
| + |
| +import android.annotation.SuppressLint; |
| +import android.content.Context; |
| +import android.graphics.Rect; |
| +import android.util.Pair; |
| +import android.util.SparseArray; |
| +import android.view.View; |
| +import android.view.ViewGroup; |
| +import android.view.ViewStructure; |
| +import android.view.autofill.AutofillValue; |
| + |
| +import org.chromium.base.Log; |
| +import org.chromium.base.ThreadUtils; |
| +import org.chromium.components.autofill.AutofillProvider; |
| +import org.chromium.components.autofill.FormData; |
| +import org.chromium.components.autofill.FormFieldData; |
| + |
| +import java.util.List; |
| + |
| +// All methods are supposed to be called in UI thread. |
| +@SuppressLint("NewApi") // Removed once SDK roll to O |
| +public class AwAutofillProvider extends AutofillProvider { |
| + |
| + private static class AutofillRequest { |
| + public final static short OUT_OF_FOCUS = -1; |
| + private static int sClientId; |
| + public final int mClientId; |
| + private FormData mFormData; |
| + private short mFocusField; |
| + |
| + public AutofillRequest(FormData formData, short focus) { |
| + mClientId = getNextClientId(); |
| + mFormData = formData; |
| + mFocusField = focus; |
| + } |
| + |
| + public void fillViewStructure(ViewStructure structure) { |
|
svetoslavganov
2017/04/11 22:47:17
This children are not properly added which I suspe
|
| + Log.e(TAG, "fillViewStructure " + mFormData.mFields.size()); |
| + structure.setClassName(mFormData.mName); |
| + structure.setUrl(mFormData.mOrigin); |
| + int index = structure.addChildCount(mFormData.mFields.size()); |
| + short fieldIndex = 0; |
| + for (FormFieldData field : mFormData.mFields) { |
| + ViewStructure child = structure.newChild(index); |
| + child.setAutofillId(structure, toVirtualId(mClientId, fieldIndex++)); |
| + // This is just for testing purpose, we should set ViewStructure |
| + // according new API. |
| + child.setAutofillValue(AutofillValue.forText(field.mName)); |
| + } |
| + } |
| + |
| + public boolean autofill(final SparseArray<AutofillValue> values) { |
| + for (int i = 0; i < values.size(); ++i) { |
| + int id = values.keyAt(i); |
| + AutofillValue value = values.get(id); |
| + if (toClientId(id) != mClientId) |
| + return false; |
| + 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; |
| + field.updataValue((String) value.getTextValue()); |
| + } |
| + return true; |
| + } |
| + |
| + public void setFocusField(short focusField) { |
| + mFocusField = focusField; |
| + } |
| + |
| + public short getFocusField() { |
| + return mFocusField; |
| + } |
| + |
| + public AutofillValue getFieldNewValue(int index) { |
| + FormFieldData field = mFormData.mFields.get(index); |
| + if (field == null) |
| + return null; |
| + String value = field.getValue(); |
| + return AutofillValue.forText(value); |
| + } |
| + |
| + public int getVirtualId(short index) { |
| + return toVirtualId(mClientId, index); |
| + } |
| + |
| + private static int getNextClientId() { |
| + ThreadUtils.assertOnUiThread(); |
| + if (sClientId == 0xffff) sClientId = 0; |
| + return sClientId++; |
| + } |
| + |
| + private static int toClientId(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 static final String TAG = "bt:"; |
| + private AwAutofillManager mAutoFillManager; |
| + private final ViewGroup mContainerView; |
| + |
| + private AutofillRequest mRequest; |
| + |
| + public AwAutofillProvider(Context context, ViewGroup containerView, |
| + AwAutofillManager manager) { |
| + mAutoFillManager = manager; |
| + mContainerView = containerView; |
| + } |
| + |
| + public void onProvideAutoFillVirtualStructure(ViewStructure structure, int flags) { |
| + mRequest.fillViewStructure(structure); |
| + } |
| + |
| + public void autofill(final SparseArray<AutofillValue> values) { |
| + if (mRequest.autofill(values)) { |
| + autofill(mRequest.mFormData); |
| + } |
| + } |
| + |
| + @Override |
| + public void queryFormFieldAutofill(FormData formData, int focus, int x, int y, int width, |
| + int height) { |
| + Log.e(TAG, "queryFormFieldAutofill"); |
| + // Check focusField inside short value? |
| + // If query for credit card we need check if connection is secure. |
| + if (mRequest != null) { |
| + mAutoFillManager.cancel(); |
| + } |
| + Rect bounds = new Rect(x, y, x + width, y + height); |
| + mRequest = new AutofillRequest(formData, (short) focus); |
| + int virtualId = mRequest.getVirtualId((short) focus); |
| + mAutoFillManager.notifyVirtualViewEntered(mContainerView, virtualId, bounds); |
| + } |
| + |
| + @Override |
| + public void onTextFieldDidChange(int index) { |
| + // Check index inside short value? |
| + AutofillValue autofillValue = mRequest.getFieldNewValue(index); |
| + mAutoFillManager.notifyVirtualValueChanged(mContainerView, |
| + mRequest.getVirtualId((short) index), |
| + autofillValue); |
| + } |
| + |
| + @Override |
| + public void OnWillSubmitForm() { |
| + mAutoFillManager.commit(); |
| + mRequest = null; |
| + } |
| + |
| + @Override |
| + public void OnFocusChanged(boolean focusOnForm, int focusField, int x, int y, int width, |
| + int height) { |
| + // Check focusField inside short value? |
| + short prev = mRequest.getFocusField(); |
| + if (focusOnForm) { |
| + if (prev == focusField) return; |
| + // Notify focus changed. |
| + if (prev != AutofillRequest.OUT_OF_FOCUS) { |
| + mAutoFillManager.notifyVirtualViewExited(mContainerView, |
| + mRequest.getVirtualId(prev)); |
| + } |
| + mAutoFillManager.notifyVirtualViewEntered(mContainerView, |
| + mRequest.getVirtualId((short) focusField), |
| + new Rect(x, y, x + width, y + height)); |
| + mRequest.setFocusField((short)focusField); |
| + } else { |
| + if (prev == AutofillRequest.OUT_OF_FOCUS) return; |
| + // Notify focus changed. |
| + mAutoFillManager.notifyVirtualViewExited(mContainerView, |
| + mRequest.getVirtualId(prev)); |
| + mRequest.setFocusField(AutofillRequest.OUT_OF_FOCUS); |
| + } |
| + } |
| +} |