1bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount/*
2bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * Copyright (C) 2012 The Android Open Source Project
3bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount *
4bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * Licensed under the Apache License, Version 2.0 (the "License");
5bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * you may not use this file except in compliance with the License.
6bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * You may obtain a copy of the License at
7bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount *
8bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount *      http://www.apache.org/licenses/LICENSE-2.0
9bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount *
10bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * Unless required by applicable law or agreed to in writing, software
11bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * distributed under the License is distributed on an "AS IS" BASIS,
12bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * See the License for the specific language governing permissions and
14bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount * limitations under the License.
15bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount */
16bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountpackage android.webkit;
17bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
18bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.content.Context;
19bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.os.Handler;
20bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.os.Message;
21bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.text.Editable;
22bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.view.KeyEvent;
23bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.view.View;
24bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.AbsoluteLayout;
25bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.AdapterView;
26bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.AdapterView.OnItemClickListener;
27bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.Filter;
28bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.Filterable;
29bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.ListAdapter;
30bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mountimport android.widget.ListPopupWindow;
3157bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mountimport android.widget.PopupWindow.OnDismissListener;
32bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
3357bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mountclass AutoCompletePopup implements OnItemClickListener, Filter.FilterListener,
3457bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        OnDismissListener{
35bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private static class AnchorView extends View {
36bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        AnchorView(Context context) {
37bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            super(context);
38bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            setFocusable(false);
3957bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            setVisibility(INVISIBLE);
40bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
41bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
42bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private static final int AUTOFILL_FORM = 100;
43bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private boolean mIsAutoFillProfileSet;
44bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private Handler mHandler;
45bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private int mQueryId;
46bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private ListPopupWindow mPopup;
47bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private Filter mFilter;
48bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private CharSequence mText;
49bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private ListAdapter mAdapter;
50bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private View mAnchor;
51bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private WebViewClassic.WebViewInputConnection mInputConnection;
52bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private WebViewClassic mWebView;
53bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
5457bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount    public AutoCompletePopup(WebViewClassic webView,
55bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            WebViewClassic.WebViewInputConnection inputConnection) {
56bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mInputConnection = inputConnection;
57bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mWebView = webView;
58bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mHandler = new Handler() {
59bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            @Override
60bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            public void handleMessage(Message msg) {
61bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                switch (msg.what) {
62bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                case AUTOFILL_FORM:
63bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    mWebView.autoFillForm(mQueryId);
64bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    break;
65bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                }
66bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
67bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        };
68bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
69bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
70bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
7157bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        if (mPopup == null) {
7257bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            return false;
7357bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        }
74bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (keyCode == KeyEvent.KEYCODE_BACK && mPopup.isShowing()) {
75bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            // special case for the back key, we do not even try to send it
76bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            // to the drop down list but instead, consume it immediately
77bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
78bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState();
79bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                if (state != null) {
80bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    state.startTracking(event, this);
81bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                }
82bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                return true;
83bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            } else if (event.getAction() == KeyEvent.ACTION_UP) {
84bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState();
85bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                if (state != null) {
86bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    state.handleUpEvent(event);
87bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                }
88bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                if (event.isTracking() && !event.isCanceled()) {
89bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    mPopup.dismiss();
90bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    return true;
91bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                }
92bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
93bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
94bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (mPopup.isShowing()) {
95bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            return mPopup.onKeyPreIme(keyCode, event);
96bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
97bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        return false;
98bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
99bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
100bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void setText(CharSequence text) {
101bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mText = text;
102bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (mFilter != null) {
103bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mFilter.filter(text, this);
104bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
105bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
106bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
107bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void setAutoFillQueryId(int queryId) {
108bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mQueryId = queryId;
109bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
110bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
111bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void clearAdapter() {
112bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mAdapter = null;
113bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mFilter = null;
11457bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        if (mPopup != null) {
11557bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mPopup.dismiss();
11657bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mPopup.setAdapter(null);
11757bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        }
118bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
119bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
120bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
12157bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        ensurePopup();
122bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mPopup.setAdapter(adapter);
123bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mAdapter = adapter;
124bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (adapter != null) {
125bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mFilter = adapter.getFilter();
126bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mFilter.filter(mText, this);
127bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        } else {
128bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mFilter = null;
129bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
130bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        resetRect();
131bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
132bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
133bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void resetRect() {
13457bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        ensurePopup();
1357102eb2d3068e0b7e5a3b44b61044de20910eca0George Mount        int left = mWebView.contentToViewX(mWebView.mEditTextContentBounds.left);
1367102eb2d3068e0b7e5a3b44b61044de20910eca0George Mount        int right = mWebView.contentToViewX(mWebView.mEditTextContentBounds.right);
137bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        int width = right - left;
138bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mPopup.setWidth(width);
139bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
1407102eb2d3068e0b7e5a3b44b61044de20910eca0George Mount        int bottom = mWebView.contentToViewY(mWebView.mEditTextContentBounds.bottom);
1417102eb2d3068e0b7e5a3b44b61044de20910eca0George Mount        int top = mWebView.contentToViewY(mWebView.mEditTextContentBounds.top);
142bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        int height = bottom - top;
143bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
144bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        AbsoluteLayout.LayoutParams lp =
145bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                (AbsoluteLayout.LayoutParams) mAnchor.getLayoutParams();
146bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        boolean needsUpdate = false;
147bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (null == lp) {
148bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            lp = new AbsoluteLayout.LayoutParams(width, height, left, top);
149bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        } else {
150bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            if ((lp.x != left) || (lp.y != top) || (lp.width != width)
151bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                    || (lp.height != height)) {
152bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                needsUpdate = true;
153bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                lp.x = left;
154bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                lp.y = top;
155bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                lp.width = width;
156bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                lp.height = height;
157bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
158bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
159bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (needsUpdate) {
160bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mAnchor.setLayoutParams(lp);
161bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
162bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (mPopup.isShowing()) {
163bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mPopup.show(); // update its position
164bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
165bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
166bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
167bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    // AdapterView.OnItemClickListener implementation
168bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    @Override
169bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
17057bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        if (mPopup == null) {
17157bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            return;
17257bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        }
173bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (id == 0 && position == 0 && mInputConnection.getIsAutoFillable()) {
174bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mText = "";
175bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            pushTextToInputConnection();
176bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            // Blank out the text box while we wait for WebCore to fill the form.
177bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            if (mIsAutoFillProfileSet) {
178bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                // Call a webview method to tell WebCore to autofill the form.
179bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                mWebView.autoFillForm(mQueryId);
180bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            } else {
181bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                // There is no autofill profile setup yet and the user has
182bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                // elected to try and set one up. Call through to the
183bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                // embedder to action that.
1847a2cb35513b1016a5042f0a48d7008455f24a479George Mount                WebChromeClient webChromeClient = mWebView.getWebChromeClient();
1857a2cb35513b1016a5042f0a48d7008455f24a479George Mount                if (webChromeClient != null) {
1867a2cb35513b1016a5042f0a48d7008455f24a479George Mount                    webChromeClient.setupAutoFill(
187bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                        mHandler.obtainMessage(AUTOFILL_FORM));
1887a2cb35513b1016a5042f0a48d7008455f24a479George Mount                }
189bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
190bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        } else {
191bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            Object selectedItem;
192bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            if (position < 0) {
193bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                selectedItem = mPopup.getSelectedItem();
194bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            } else {
195bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                selectedItem = mAdapter.getItem(position);
196bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
197bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            if (selectedItem != null) {
198bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                setText(mFilter.convertResultToString(selectedItem));
199bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                pushTextToInputConnection();
200bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
201bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
202bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mPopup.dismiss();
203bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
204bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
205bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void setIsAutoFillProfileSet(boolean isAutoFillProfileSet) {
206bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mIsAutoFillProfileSet = isAutoFillProfileSet;
207bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
208bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
209bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    private void pushTextToInputConnection() {
210bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        Editable oldText = mInputConnection.getEditable();
211bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mInputConnection.setSelection(0, oldText.length());
212bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mInputConnection.replaceSelection(mText);
213bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        mInputConnection.setSelection(mText.length(), mText.length());
214bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
215bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
216bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    @Override
217bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    public void onFilterComplete(int count) {
21857bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        ensurePopup();
219bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        boolean showDropDown = (count > 0) &&
220bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                (mInputConnection.getIsAutoFillable() || mText.length() > 0);
221bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        if (showDropDown) {
222bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            if (!mPopup.isShowing()) {
223bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                // Make sure the list does not obscure the IME when shown for the first time.
224bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount                mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
225bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            }
226bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mPopup.show();
227bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
228bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        } else {
229bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount            mPopup.dismiss();
230bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount        }
231bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount    }
23257bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount
23357bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount    @Override
23457bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount    public void onDismiss() {
23557bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        mWebView.getWebView().removeView(mAnchor);
23657bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount    }
23757bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount
23857bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount    private void ensurePopup() {
23957bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        if (mPopup == null) {
24057bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mPopup = new ListPopupWindow(mWebView.getContext());
24157bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mAnchor = new AnchorView(mWebView.getContext());
24257bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mWebView.getWebView().addView(mAnchor);
24357bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mPopup.setOnItemClickListener(this);
24457bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mPopup.setAnchorView(mAnchor);
24557bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
24657bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        } else if (mWebView.getWebView().indexOfChild(mAnchor) < 0) {
24757bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount            mWebView.getWebView().addView(mAnchor);
24857bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount        }
24957bd51713e7923cad9ad9fc9ac9bfd339cb6bb9cGeorge Mount    }
250bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount}
251bcd5dd7c9a6d5fb5add4041dbd62d1670a69d526George Mount
252