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); |
+ } |
+ } |
+} |