summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraurimas@chromium.org <aurimas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-02 22:02:34 +0000
committeraurimas@chromium.org <aurimas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-02 22:02:34 +0000
commitd122cfbfac5f51d322042d2d5d531b51e07f3d2b (patch)
tree57024fe64ce1d601591edbd6deec9ed396d2cfa4
parentdc3655978522565626b88a329d5e2b2ea0ef515b (diff)
downloadchromium_src-d122cfbfac5f51d322042d2d5d531b51e07f3d2b.zip
chromium_src-d122cfbfac5f51d322042d2d5d531b51e07f3d2b.tar.gz
chromium_src-d122cfbfac5f51d322042d2d5d531b51e07f3d2b.tar.bz2
[Android] Add AutofillPopup to AutofillDialog.
Add AutofillPopup support to AutofillDialog. The same AutofillPopup code is now used for web pages and AutofillDialog. BUG=222743 NOTRY=true Review URL: https://chromiumcodereview.appspot.com/14253011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197979 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/android/java/res/layout/autofill_text.xml18
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialog.java69
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogGlue.java14
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopup.java119
-rw-r--r--chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc16
-rw-r--r--chrome/browser/ui/android/autofill/autofill_dialog_view_android.h6
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc4
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java32
-rw-r--r--ui/android/java/src/org/chromium/ui/ViewAndroidDelegate.java23
9 files changed, 191 insertions, 110 deletions
diff --git a/chrome/android/java/res/layout/autofill_text.xml b/chrome/android/java/res/layout/autofill_text.xml
index 889ab06..967f4b8 100644
--- a/chrome/android/java/res/layout/autofill_text.xml
+++ b/chrome/android/java/res/layout/autofill_text.xml
@@ -8,25 +8,25 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
+ android:background="#FFF"
android:orientation="horizontal">
- <TextView android:id="@+id/autofill_name"
- android:layout_alignParentLeft="true"
- android:layout_width="fill_parent"
+ <TextView android:id="@+id/autofill_label"
+ android:layout_alignParentRight="true"
+ android:layout_width="wrap_content"
android:layout_height="fill_parent"
- android:background="#FFF"
android:padding="5dp"
android:textSize="18sp"
- android:textColor="#000"
+ android:textColor="#CCC"
android:ellipsize="end"
android:singleLine="true"/>
- <TextView android:id="@+id/autofill_label"
- android:layout_alignParentRight="true"
+ <TextView android:id="@+id/autofill_name"
+ android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:padding="5dp"
- android:textSize="18sp"
android:background="#FFF"
- android:textColor="#CCC"
+ android:textSize="18sp"
+ android:textColor="#000"
android:ellipsize="end"
android:singleLine="true"/>
</RelativeLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialog.java
index adaa1ce..f48559d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialog.java
@@ -8,9 +8,10 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
-import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.text.Editable;
import android.text.TextUtils;
+import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnFocusChangeListener;
@@ -29,10 +30,9 @@ import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.ui.UiUtils;
+import org.chromium.ui.ViewAndroidDelegate;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
/**
* This is the dialog that will act as the java side controller between the
@@ -42,13 +42,16 @@ import java.util.List;
public class AutofillDialog extends AlertDialog
implements OnClickListener, OnItemSelectedListener,
AutofillDialogContentView.OnItemEditButtonClickedListener,
- OnFocusChangeListener {
+ OnFocusChangeListener, ViewAndroidDelegate {
private final AutofillDialogContentView mContentView;
private final AutofillDialogTitleView mTitleView;
private final AutofillDialogDelegate mDelegate;
private AutofillDialogField[][] mAutofillSectionFieldData =
new AutofillDialogField[AutofillDialogConstants.NUM_SECTIONS][];
+ private TextWatcher mCurrentTextWatcher;
+ private int mFocusedFieldNativePointer;
+ private EditText mFocusedField;
/**
* An interface to handle the interaction with an AutofillDialog object.
@@ -100,6 +103,17 @@ public class AutofillDialog extends AlertDialog
public void editingCancel(int section);
/**
+ * Informs AutofillDialog controller that the user has edited or activate an EditText field.
+ * @param dialogInputPointer The native pointer to the field that was edited or activated.
+ * @param delegate The ViewAndroidDelegate that should be used to attach the AutofillPopup
+ * if the AutofillPopup controller has any suggestions.
+ * @param value The current value the focused field.
+ * @param wasEdit True if it is an edit, otherwise False.
+ */
+ public void editedOrActivatedField(int dialogInputPointer, ViewAndroidDelegate delegate,
+ String value, boolean wasEdit);
+
+ /**
* Requests AutofillDialog controller to validate the specified field. If the field is
* invalid the returned value contains the error string. If the field is valid then
* the returned value is null.
@@ -483,6 +497,7 @@ public class AutofillDialog extends AlertDialog
boolean clobberInputs, int fieldTypeToAlwaysClobber) {
View currentField;
String inputValue;
+
for (int i = 0; i < dialogInputs.length; i++) {
currentField = findViewById(AutofillDialogUtils.getViewIDForField(
section, dialogInputs[i].mFieldType));
@@ -672,36 +687,80 @@ public class AutofillDialog extends AlertDialog
internalDismiss();
}
+ private void addTextWatcher(EditText view, int nativePointer) {
+ mFocusedFieldNativePointer = nativePointer;
+ if (mCurrentTextWatcher == null) {
+ mCurrentTextWatcher = new TextWatcher() {
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ mDelegate.editedOrActivatedField(mFocusedFieldNativePointer,
+ AutofillDialog.this, editable.toString(), true);
+ }
+ };
+ }
+ view.addTextChangedListener(mCurrentTextWatcher);
+ }
+
/**
* Validates EditText fields in the editing mode when they get unfocused.
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus || !mContentView.isInEditingMode()) return;
+ if (!mContentView.isInEditingMode()) return;
if (!(v instanceof EditText)) return;
EditText currentfield = (EditText) v;
+ if (!hasFocus) currentfield.removeTextChangedListener(mCurrentTextWatcher);
+ mFocusedField = currentfield;
// Validation is performed when user changes from one EditText view to another.
int section = mContentView.getCurrentSection();
AutofillDialogField[] fields = getFieldsForSection(section);
if (fields == null) return;
int fieldType = AutofillDialogConstants.UNKNOWN_TYPE;
+ int nativePointer = 0;
for (AutofillDialogField field : fields) {
View currentView = findViewById(AutofillDialogUtils.getViewIDForField(
section, field.mFieldType));
if (v.equals(currentView)) {
fieldType = field.mFieldType;
+ nativePointer = field.mNativePointer;
break;
}
}
assert (fieldType != AutofillDialogConstants.UNKNOWN_TYPE);
if (fieldType == AutofillDialogConstants.UNKNOWN_TYPE) return;
+ addTextWatcher(currentfield, nativePointer);
+ mDelegate.editedOrActivatedField(mFocusedFieldNativePointer, this, mFocusedField.toString(),
+ false);
+
+ if (hasFocus) return;
String errorText = mDelegate.validateField(fieldType, currentfield.getText().toString());
currentfield.setError(errorText);
// Entire section is validated if the field is valid.
if (errorText == null) mDelegate.validateSection(section);
}
+
+ @Override
+ public View acquireAnchorView() {
+ return mFocusedField;
+ }
+
+ @Override
+ public void setAnchorViewPosition(View view, float x, float y, float width, float height) {
+ }
+
+ @Override
+ public void releaseAnchorView(View anchorView) {
+ }
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogGlue.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogGlue.java
index e0d84d0..db9eee2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogGlue.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogGlue.java
@@ -10,6 +10,8 @@ import android.os.Handler;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.chrome.browser.autofill.AutofillDialog.AutofillDialogDelegate;
+import org.chromium.ui.ViewAndroid;
+import org.chromium.ui.ViewAndroidDelegate;
import org.chromium.ui.WindowAndroid;
/**
@@ -22,12 +24,15 @@ public class AutofillDialogGlue implements AutofillDialogDelegate,
private final AutofillDialog mAutofillDialog;
private final AutofillDialogAccountHelper mAccountHelper;
private int mNativeDialogPopup; // could be 0 after onDestroy().
+ private ViewAndroid mViewAndroid;
public AutofillDialogGlue(int nativeAutofillDialogViewAndroid, WindowAndroid windowAndroid) {
mNativeDialogPopup = nativeAutofillDialogViewAndroid;
+
mAccountHelper = new AutofillDialogAccountHelper(this, windowAndroid.getContext());
mAutofillDialog = new AutofillDialog(windowAndroid.getContext(), this);
+ mViewAndroid = new ViewAndroid(windowAndroid, mAutofillDialog);
mAutofillDialog.show();
}
@@ -199,6 +204,13 @@ public class AutofillDialogGlue implements AutofillDialogDelegate,
}
@Override
+ public void editedOrActivatedField(int dialogInputPointer, ViewAndroidDelegate delegate,
+ String value, boolean wasEdit) {
+ nativeEditedOrActivatedField(mNativeDialogPopup, dialogInputPointer,
+ mViewAndroid.getNativePointer(), value, wasEdit);
+ }
+
+ @Override
public String validateField(int fieldType, String value) {
return nativeValidateField(mNativeDialogPopup, fieldType, value);
}
@@ -372,6 +384,8 @@ public class AutofillDialogGlue implements AutofillDialogDelegate,
private native void nativeEditingStart(int nativeAutofillDialogViewAndroid, int section);
private native boolean nativeEditingComplete(int nativeAutofillDialogViewAndroid, int section);
private native void nativeEditingCancel(int nativeAutofillDialogViewAndroid, int section);
+ private native void nativeEditedOrActivatedField(int nativeAutofillDialogViewAndroid,
+ int dialogInputPointer, int viewAndroid, String value, boolean wasEdit);
private native String nativeValidateField(int nativeAutofillDialogViewAndroid, int fieldType,
String value);
private native void nativeValidateSection(int nativeAutofillDialogViewAndroid, int section);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopup.java
index 61b0d84..28b151d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopup.java
@@ -5,25 +5,19 @@
package org.chromium.chrome.browser.autofill;
import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Paint;
-import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.WindowManager;
+import android.view.View.OnLayoutChangeListener;
import android.widget.AdapterView;
-import android.widget.FrameLayout;
import android.widget.ListPopupWindow;
import android.widget.TextView;
import java.util.ArrayList;
import org.chromium.chrome.R;
-import org.chromium.ui.gfx.DeviceDisplayInfo;
import org.chromium.ui.ViewAndroidDelegate;
-import org.chromium.ui.WindowAndroid;
/**
* The Autofill suggestion popup that lists relevant suggestions.
@@ -41,15 +35,19 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
private static final int ITEM_ID_PASSWORD_ENTRY = -2;
private static final int ITEM_ID_DATA_LIST_ENTRY = -6;
- private static final int TEXT_PADDING_DP = 30;
+ private static final int TEXT_PADDING_DP = 40;
private final AutofillPopupDelegate mAutofillCallback;
private final Context mContext;
private final ViewAndroidDelegate mViewAndroidDelegate;
- private AnchorView mAnchorView;
- private Rect mAnchorRect;
+ private View mAnchorView;
+ private float mAnchorWidth;
+ private float mAnchorHeight;
+ private float mAnchorX;
+ private float mAnchorY;
private Paint mNameViewPaint;
private Paint mLabelViewPaint;
+ private OnLayoutChangeListener mLayoutChangeListener;
/**
* An interface to handle the touch interaction with an AutofillPopup object.
@@ -67,59 +65,6 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
public void suggestionSelected(int listIndex);
}
- // ListPopupWindow needs an anchor view to determine it's size and position. We create a view
- // with the given desired width at the text edit area as a stand-in. This is "Fake" in the
- // sense that it draws nothing, accepts no input, and thwarts all attempts at laying it out
- // "properly".
- private static class AnchorView extends View {
- private int mCurrentOrientation;
- private AutofillPopup mAutofillPopup;
-
- AnchorView(Context c, AutofillPopup autofillPopup) {
- super(c);
- mAutofillPopup = autofillPopup;
- mCurrentOrientation = getResources().getConfiguration().orientation;
-
- addOnLayoutChangeListener(new OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- if (v instanceof AnchorView) mAutofillPopup.show();
- }
- });
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (newConfig.orientation != mCurrentOrientation) mAutofillPopup.dismiss();
- }
-
- public void setSize(Rect r, int desiredWidth) {
- int width = Math.max(desiredWidth, r.right - r.left);
-
- // Make sure that the anchor view does not go outside the screen.
- Point size = new Point();
- WindowManager wm = (WindowManager) getContext().getSystemService(
- Context.WINDOW_SERVICE);
- wm.getDefaultDisplay().getSize(size);
- if (r.left + width > size.x) width = size.x - r.left;
-
- int height = r.bottom - r.top;
-
- // Get rid of the padding added by ListPopupWindow class.
- Drawable popupBackground = mAutofillPopup.getBackground();
- Rect paddingRect = new Rect();
- if (popupBackground != null) popupBackground.getPadding(paddingRect);
- width += paddingRect.left + paddingRect.right;
-
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width, height);
- lp.leftMargin = r.left - paddingRect.left;
- lp.topMargin = r.top;
- setLayoutParams(lp);
- }
- }
-
/**
* Creates an AutofillWindow with specified parameters.
* @param context Application context.
@@ -135,8 +80,19 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
setOnItemClickListener(this);
- mAnchorView = new AnchorView(context, this);
- mViewAndroidDelegate.addViewToContainerView(mAnchorView);
+ mAnchorView = mViewAndroidDelegate.acquireAnchorView();
+ mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY, mAnchorWidth,
+ mAnchorHeight);
+
+ mLayoutChangeListener = new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (v == mAnchorView) AutofillPopup.this.show();
+ }
+ };
+
+ mAnchorView.addOnLayoutChangeListener(mLayoutChangeListener);
setAnchorView(mAnchorView);
}
@@ -149,10 +105,14 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
* @param height The height of the anchor view.
*/
public void setAnchorRect(float x, float y, float width, float height) {
- float scale = (float) DeviceDisplayInfo.create(mContext).getDIPScale();
- mAnchorRect = new Rect(Math.round(x * scale), Math.round(y * scale),
- Math.round((x + width) * scale), Math.round((y + height) * scale));
- mAnchorRect.offset(0, mViewAndroidDelegate.getChildViewOffsetYPix());
+ mAnchorWidth = width;
+ mAnchorHeight = height;
+ mAnchorX = x;
+ mAnchorY = y;
+ if (mAnchorView != null) {
+ mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY,
+ mAnchorWidth, mAnchorHeight);
+ }
}
/**
@@ -171,10 +131,11 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
}
setAdapter(new AutofillListAdapter(mContext, cleanedData));
// Once the mAnchorRect is resized and placed correctly, it will show the Autofill popup.
- mAnchorView.setSize(mAnchorRect, getDesiredWidth(suggestions));
+ mAnchorWidth = Math.max(getDesiredWidth(suggestions), mAnchorWidth);
+ mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY, mAnchorWidth,
+ mAnchorHeight);
}
-
/**
* Overrides the default dismiss behavior to request the controller to dismiss the view.
*/
@@ -188,15 +149,16 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
*/
public void hide() {
super.dismiss();
- mViewAndroidDelegate.removeViewFromContainerView(mAnchorView);
+ mAnchorView.removeOnLayoutChangeListener(mLayoutChangeListener);
+ mViewAndroidDelegate.releaseAnchorView(mAnchorView);
}
/**
* Get desired popup window width by calculating the maximum text length from Autofill data.
* @param data Autofill suggestion data.
- * @return The popup window width.
+ * @return The popup window width in DIP.
*/
- private int getDesiredWidth(AutofillSuggestion[] data) {
+ private float getDesiredWidth(AutofillSuggestion[] data) {
if (mNameViewPaint == null || mLabelViewPaint == null) {
LayoutInflater inflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -207,12 +169,12 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
mLabelViewPaint = labelView.getPaint();
}
- int maxTextWidth = 0;
+ float maxTextWidth = 0;
Rect bounds = new Rect();
for (int i = 0; i < data.length; ++i) {
bounds.setEmpty();
String name = data[i].mName;
- int width = 0;
+ float width = 0;
mNameViewPaint.getTextBounds(name, 0, name.length(), bounds);
width += bounds.width();
@@ -222,9 +184,10 @@ public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItem
width += bounds.width();
maxTextWidth = Math.max(width, maxTextWidth);
}
+ // Scale it down to make it unscaled by screen density.
+ maxTextWidth = maxTextWidth / mContext.getResources().getDisplayMetrics().density;
// Adding padding.
- return maxTextWidth + (int) (TEXT_PADDING_DP *
- mContext.getResources().getDisplayMetrics().density);
+ return maxTextWidth + TEXT_PADDING_DP;
}
@Override
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc
index 2df20a8..865c3f5 100644
--- a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc
@@ -22,6 +22,7 @@
#include "ui/base/models/combobox_model.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/rect.h"
namespace autofill {
@@ -337,6 +338,20 @@ void AutofillDialogViewAndroid::EditingCancel(JNIEnv* env,
UpdateSection(section);
}
+void AutofillDialogViewAndroid::EditedOrActivatedField(JNIEnv* env,
+ jobject obj,
+ jint detail_input,
+ jint view_android,
+ jstring value,
+ jboolean was_edit) {
+ DetailInput* input = reinterpret_cast<DetailInput*>(detail_input);
+ ui::ViewAndroid* view = reinterpret_cast<ui::ViewAndroid*>(view_android);
+ gfx::Rect rect = gfx::Rect(0, 0, 0, 0);
+ string16 value16 = base::android::ConvertJavaStringToUTF16(
+ env, value);
+ controller_->UserEditedOrActivatedInput(input, view, rect, value16, was_edit);
+}
+
ScopedJavaLocalRef<jstring> AutofillDialogViewAndroid::ValidateField(
JNIEnv* env,
jobject obj,
@@ -736,5 +751,4 @@ bool AutofillDialogViewAndroid::CollapseUserDataIntoMenuItem(
*icon_to_set = icon;
return true;
}
-
} // namespace autofill
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h
index 39e1459..1f86c5b 100644
--- a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h
@@ -49,6 +49,12 @@ class AutofillDialogViewAndroid : public AutofillDialogView {
void EditingStart(JNIEnv* env, jobject obj, jint section);
jboolean EditingComplete(JNIEnv* env, jobject obj, jint section);
void EditingCancel(JNIEnv* env, jobject obj, jint section);
+ void EditedOrActivatedField(JNIEnv* env,
+ jobject obj,
+ jint detail_input,
+ jint view_android,
+ jstring value,
+ jboolean was_edit);
base::android::ScopedJavaLocalRef<jstring> ValidateField(
JNIEnv* env, jobject obj, jint type, jstring value);
void ValidateSection(JNIEnv* env, jobject obj, jint section);
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index 3fde362..5a70aa1 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -1105,8 +1105,10 @@ void AutofillDialogControllerImpl::UserEditedOrActivatedInput(
&popup_guids_);
}
- if (popup_values.empty())
+ if (popup_values.empty()) {
+ HidePopup();
return;
+ }
// TODO(estade): do we need separators and control rows like 'Clear
// Form'?
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index df730b89..7dbd3ec 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -34,6 +34,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
import com.google.common.annotations.VisibleForTesting;
@@ -54,6 +55,7 @@ import org.chromium.content.common.TraceEvent;
import org.chromium.ui.ViewAndroid;
import org.chromium.ui.ViewAndroidDelegate;
import org.chromium.ui.WindowAndroid;
+import org.chromium.ui.gfx.DeviceDisplayInfo;
import java.lang.annotation.Annotation;
import java.util.HashMap;
@@ -387,18 +389,36 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient {
public ViewAndroidDelegate getViewAndroidDelegate() {
return new ViewAndroidDelegate() {
@Override
- public void addViewToContainerView(View view) {
- mContainerView.addView(view);
+ public View acquireAnchorView() {
+ View anchorView = new View(getContext());
+ mContainerView.addView(anchorView);
+ return anchorView;
}
@Override
- public void removeViewFromContainerView(View view) {
- mContainerView.removeView(view);
+ public void setAnchorViewPosition(
+ View view, float x, float y, float width, float height) {
+ assert(view.getParent() == mContainerView);
+ float scale = (float) DeviceDisplayInfo.create(getContext()).getDIPScale();
+
+ // The anchor view should not go outside the bounds of the ContainerView.
+ int scaledX = Math.round(x * scale);
+ int scaledWidth = Math.round(width * scale);
+ if (scaledWidth + scaledX > mContainerView.getWidth()) {
+ scaledWidth = mContainerView.getWidth() - scaledX;
+ }
+
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+ scaledWidth, Math.round(height * scale));
+ lp.leftMargin = scaledX;
+ lp.topMargin = (int) mRenderCoordinates.getContentOffsetYPix() +
+ Math.round(y * scale);
+ view.setLayoutParams(lp);
}
@Override
- public int getChildViewOffsetYPix() {
- return (int) mRenderCoordinates.getContentOffsetYPix();
+ public void releaseAnchorView(View anchorView) {
+ mContainerView.removeView(anchorView);
}
};
}
diff --git a/ui/android/java/src/org/chromium/ui/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/ViewAndroidDelegate.java
index c6855a1..531dce8 100644
--- a/ui/android/java/src/org/chromium/ui/ViewAndroidDelegate.java
+++ b/ui/android/java/src/org/chromium/ui/ViewAndroidDelegate.java
@@ -7,25 +7,28 @@ package org.chromium.ui;
import android.view.View;
/**
- * Interface to add and remove views from the implementing view.
+ * Interface to acquire and release anchor views from the implementing View.
*/
public interface ViewAndroidDelegate {
/**
- * Add the view.
- * @param view The view to be added.
+ * @return An anchor view that can be used to anchor decoration views like Autofill popup.
*/
- void addViewToContainerView(View view);
+ View acquireAnchorView();
/**
- * Remove the view if it is present, otherwise do nothing.
- * @param view The view to be removed.
+ * Set the anchor view to specified position and width (all units in dp).
+ * @param view The anchor view that needs to be positioned.
+ * @param x X coordinate of the top left corner of the anchor view.
+ * @param y Y coordinate of the top left corner of the anchor view.
+ * @param width The width of the anchor view.
+ * @param height The height of the anchor view.
*/
- void removeViewFromContainerView(View view);
+ void setAnchorViewPosition(View view, float x, float y, float width, float height);
/**
- * Used for any calculations that need to place a View near a particular piece of web content.
- * @return The Y offset in pixels to apply to any added views.
+ * Release given anchor view.
+ * @param anchorView The anchor view that needs to be released.
*/
- int getChildViewOffsetYPix();
+ void releaseAnchorView(View anchorView);
} \ No newline at end of file