1fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb/*
2fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * Copyright (C) 2010 The Android Open Source Project
3fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *
4fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
5fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * you may not use this file except in compliance with the License.
6fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * You may obtain a copy of the License at
7fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *
8fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
9fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *
10fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * Unless required by applicable law or agreed to in writing, software
11fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
12fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * See the License for the specific language governing permissions and
14fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * limitations under the License.
15fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb */
16fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
17fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbpackage com.android.browser;
18fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
19fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.Context;
2021ce4d295802db811873b46e7821abfa0540dab2Michael Kolbimport android.content.res.Configuration;
218d021aa02f8f9e7f167649dbe83832827b0454e3John Reckimport android.content.res.TypedArray;
225119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamathimport android.graphics.Rect;
238d021aa02f8f9e7f167649dbe83832827b0454e3John Reckimport android.graphics.drawable.Drawable;
24f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamathimport android.text.Editable;
25dcda1d517fe1d8878a476f4ae6ecf244dbd976f4John Reckimport android.text.TextUtils;
26f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamathimport android.text.TextWatcher;
27fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.util.AttributeSet;
28b77bdc4dddf867e49a0157ca56119b85e12fb440John Reckimport android.util.Patterns;
29fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.view.KeyEvent;
30305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolbimport android.view.MotionEvent;
31fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.view.View;
32fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.view.inputmethod.InputMethodManager;
3387369eaa86190d500e80b5af663c3019249f77f3John Reckimport android.widget.AdapterView;
3487369eaa86190d500e80b5af663c3019249f77f3John Reckimport android.widget.AdapterView.OnItemClickListener;
35f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamathimport android.widget.AutoCompleteTextView;
36fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.widget.TextView;
37ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolbimport android.widget.TextView.OnEditorActionListener;
38fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
39305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolbimport com.android.browser.SuggestionsAdapter.CompletionListener;
40305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolbimport com.android.browser.SuggestionsAdapter.SuggestItem;
41305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolbimport com.android.browser.search.SearchEngine;
42305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolbimport com.android.browser.search.SearchEngineInfo;
43305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolbimport com.android.browser.search.SearchEngines;
448d021aa02f8f9e7f167649dbe83832827b0454e3John Reckimport com.android.internal.R;
45305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
46cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolbimport java.util.List;
47cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb
48fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb/**
49fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * url/search input view
50fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * handling suggestions
51fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb */
52f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamathpublic class UrlInputView extends AutoCompleteTextView
53dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        implements OnEditorActionListener,
54f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath        CompletionListener, OnItemClickListener, TextWatcher {
55257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb
56257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb    static final String TYPED = "browser-type";
57257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb    static final String SUGGESTED = "browser-suggest";
58257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb
5994ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb    static final int POST_DELAY = 100;
6094ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb
61305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    static interface StateListener {
62305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        static final int STATE_NORMAL = 0;
63305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        static final int STATE_HIGHLIGHTED = 1;
64305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        static final int STATE_EDITED = 2;
65305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
66305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        public void onStateChanged(int state);
67305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    }
68305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
69fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private UrlInputListener   mListener;
70fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private InputMethodManager mInputManager;
71fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private SuggestionsAdapter mAdapter;
7221ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    private View mContainer;
7321ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    private boolean mLandscape;
74b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck    private boolean mIncognitoMode;
75dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    private boolean mNeedsUpdate;
76fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
77305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    private int mState;
78305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    private StateListener mStateListener;
79305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
80fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    public UrlInputView(Context context, AttributeSet attrs, int defStyle) {
81fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        super(context, attrs, defStyle);
82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        init(context);
83fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
84fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    public UrlInputView(Context context, AttributeSet attrs) {
868d021aa02f8f9e7f167649dbe83832827b0454e3John Reck        this(context, attrs, R.attr.autoCompleteTextViewStyle);
87fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
88fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
89fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    public UrlInputView(Context context) {
908d021aa02f8f9e7f167649dbe83832827b0454e3John Reck        this(context, null);
91fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
92fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
93fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private void init(Context ctx) {
94fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mInputManager = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
95ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        setOnEditorActionListener(this);
9621ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        mAdapter = new SuggestionsAdapter(ctx, this);
97fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        setAdapter(mAdapter);
98ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb        setSelectAllOnFocus(true);
9921ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        onConfigurationChanged(ctx.getResources().getConfiguration());
10035defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck        setThreshold(1);
10187369eaa86190d500e80b5af663c3019249f77f3John Reck        setOnItemClickListener(this);
102dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mNeedsUpdate = false;
103f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath        addTextChangedListener(this);
10436b87b1acb4212147a9d5a2b159a174413050863Sungmann Cho        setDropDownAnchor(com.android.browser.R.id.taburlbar);
105305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        mState = StateListener.STATE_NORMAL;
106305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    }
107305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
108305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    protected void onFocusChanged(boolean focused, int direction, Rect prevRect) {
109305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        super.onFocusChanged(focused, direction, prevRect);
11094ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb        int state = -1;
111305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        if (focused) {
112305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb            if (hasSelection()) {
11394ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb                state = StateListener.STATE_HIGHLIGHTED;
114305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb            } else {
11594ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb                state = StateListener.STATE_EDITED;
116305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb            }
117305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        } else {
118305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb            // reset the selection state
11994ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb            state = StateListener.STATE_NORMAL;
120305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        }
12194ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb        final int s = state;
12294ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb        post(new Runnable() {
12394ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb            public void run() {
12494ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb                changeState(s);
12594ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb            }
12694ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb        });
127305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    }
128305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
129305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    @Override
130305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    public boolean onTouchEvent(MotionEvent evt) {
131305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        boolean hasSelection = hasSelection();
132305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        boolean res = super.onTouchEvent(evt);
133305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        if ((MotionEvent.ACTION_DOWN == evt.getActionMasked())
134305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb              && hasSelection) {
13594ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb            postDelayed(new Runnable() {
13694ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb                public void run() {
13794ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb                    changeState(StateListener.STATE_EDITED);
13894ec527ac5b4d4ca245c878de4eb559658a55d4dMichael Kolb                }}, POST_DELAY);
139305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        }
140305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        return res;
141dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    }
142dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb
143dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    /**
144dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb     * check if focus change requires a title bar update
145dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb     */
146dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    boolean needsUpdate() {
147dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        return mNeedsUpdate;
148dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    }
149dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb
150dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    /**
151dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb     * clear the focus change needs title bar update flag
152dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb     */
153dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    void clearNeedsUpdate() {
154dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mNeedsUpdate = false;
15521ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    }
15621ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
157ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    void setController(UiController controller) {
158ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb        UrlSelectionActionMode urlSelectionMode
159ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb                = new UrlSelectionActionMode(controller);
160ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb        setCustomSelectionActionModeCallback(urlSelectionMode);
161ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    }
162ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb
16321ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    void setContainer(View container) {
16421ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        mContainer = container;
16521ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    }
16621ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
167dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    public void setUrlInputListener(UrlInputListener listener) {
168dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mListener = listener;
169dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    }
170dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb
171305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    public void setStateListener(StateListener listener) {
172305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        mStateListener = listener;
173305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        // update listener
174305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        changeState(mState);
175305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    }
176305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
177305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    private void changeState(int newState) {
178305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        mState = newState;
179305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        if (mStateListener != null) {
180305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb            mStateListener.onStateChanged(mState);
181305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        }
182305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    }
183305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
1845e8f2b9cf44263ac77a21653eb3c012a98c3587fMichael Kolb    int getState() {
1855e8f2b9cf44263ac77a21653eb3c012a98c3587fMichael Kolb        return mState;
1865e8f2b9cf44263ac77a21653eb3c012a98c3587fMichael Kolb    }
1875e8f2b9cf44263ac77a21653eb3c012a98c3587fMichael Kolb
18821ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    @Override
18921ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    protected void onConfigurationChanged(Configuration config) {
19035defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck        super.onConfigurationChanged(config);
19121ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        mLandscape = (config.orientation &
19231d469bca6f6d5a8b444b7dac8038a1b75cd7e43Michael Kolb                Configuration.ORIENTATION_LANDSCAPE) != 0;
19335defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck        mAdapter.setLandscapeMode(mLandscape);
19421ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        if (isPopupShowing() && (getVisibility() == View.VISIBLE)) {
19536b87b1acb4212147a9d5a2b159a174413050863Sungmann Cho            dismissDropDown();
19636b87b1acb4212147a9d5a2b159a174413050863Sungmann Cho            showDropDown();
197f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath            performFiltering(getText(), 0);
19821ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        }
19921ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    }
20021ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
20121ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    @Override
20235defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck    public void dismissDropDown() {
20335defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck        super.dismissDropDown();
20435defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck        mAdapter.clearCache();
20535defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck    }
20635defffe93d70e9d5b37ff550968debdcd5d3d8bJohn Reck
207513286f421ad4aadc4d016d455ea7c520a0f2f59Michael Kolb    @Override
208ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
209f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath        finishInput(getText().toString(), null, TYPED);
210ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        return true;
211ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    }
21221ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
213dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    void forceFilter() {
214dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        showDropDown();
215a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
216a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
217dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    void hideIME() {
218dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mInputManager.hideSoftInputFromWindow(getWindowToken(), 0);
219dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    }
220dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb
2214bb6fcb473ec4b2ce4cddf573280fd47f21a20c7Michael Kolb    void showIME() {
2224bb6fcb473ec4b2ce4cddf573280fd47f21a20c7Michael Kolb        mInputManager.focusIn(this);
2234bb6fcb473ec4b2ce4cddf573280fd47f21a20c7Michael Kolb        mInputManager.showSoftInput(this, 0);
2244bb6fcb473ec4b2ce4cddf573280fd47f21a20c7Michael Kolb    }
2254bb6fcb473ec4b2ce4cddf573280fd47f21a20c7Michael Kolb
226257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb    private void finishInput(String url, String extra, String source) {
227dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mNeedsUpdate = true;
228dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        dismissDropDown();
229fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mInputManager.hideSoftInputFromWindow(getWindowToken(), 0);
230dcda1d517fe1d8878a476f4ae6ecf244dbd976f4John Reck        if (TextUtils.isEmpty(url)) {
231fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            mListener.onDismiss();
232fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        } else {
233b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck            if (mIncognitoMode && isSearch(url)) {
234b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                // To prevent logging, intercept this request
235b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                // TODO: This is a quick hack, refactor this
236b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                SearchEngine searchEngine = BrowserSettings.getInstance()
237b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                        .getSearchEngine();
238b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                if (searchEngine == null) return;
239b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                SearchEngineInfo engineInfo = SearchEngines
240b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                        .getSearchEngineInfo(mContext, searchEngine.getName());
241b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                if (engineInfo == null) return;
242b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                url = engineInfo.getSearchUriForQuery(url);
243b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                // mLister.onAction can take it from here without logging
244b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck            }
245257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb            mListener.onAction(url, extra, source);
246fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        }
247fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
248fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
249b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck    boolean isSearch(String inUrl) {
250b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        String url = UrlUtils.fixUrl(inUrl).trim();
251b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        if (TextUtils.isEmpty(url)) return false;
252b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck
253b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        if (Patterns.WEB_URL.matcher(url).matches()
254b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck                || UrlUtils.ACCEPTED_URI_SCHEMA.matcher(url).matches()) {
255b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck            return false;
256b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        }
257b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        return true;
258b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck    }
259b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck
26021ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    // Completion Listener
26121ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
26221ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    @Override
26321ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    public void onSearch(String search) {
2647cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb        mListener.onCopySuggestion(search);
26521ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    }
26621ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
26721ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    @Override
268bd2dd64dda88ca8a7c2b148d88c5a44e73e1c331Michael Kolb    public void onSelect(String url, int type, String extra) {
2695ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb        finishInput(url, extra, SUGGESTED);
27021ce4d295802db811873b46e7821abfa0540dab2Michael Kolb    }
27121ce4d295802db811873b46e7821abfa0540dab2Michael Kolb
272fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    @Override
27387369eaa86190d500e80b5af663c3019249f77f3John Reck    public void onItemClick(
27487369eaa86190d500e80b5af663c3019249f77f3John Reck            AdapterView<?> parent, View view, int position, long id) {
27587369eaa86190d500e80b5af663c3019249f77f3John Reck        SuggestItem item = mAdapter.getItem(position);
2765119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath        onSelect(SuggestionsAdapter.getSuggestionUrl(item), item.type, item.extra);
27787369eaa86190d500e80b5af663c3019249f77f3John Reck    }
27887369eaa86190d500e80b5af663c3019249f77f3John Reck
279fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    interface UrlInputListener {
280fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
28121ce4d295802db811873b46e7821abfa0540dab2Michael Kolb        public void onDismiss();
282fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
283257cc2c8fcdd7117317e89861d4509955a622be8Michael Kolb        public void onAction(String text, String extra, String source);
284fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
2857cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb        public void onCopySuggestion(String text);
286fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
287fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
288fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
289117f07d08e3e25e3c920a1dabe31dcd7643bacb2John Reck    public void setIncognitoMode(boolean incognito) {
290b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        mIncognitoMode = incognito;
291b77bdc4dddf867e49a0157ca56119b85e12fb440John Reck        mAdapter.setIncognitoMode(mIncognitoMode);
292117f07d08e3e25e3c920a1dabe31dcd7643bacb2John Reck    }
293117f07d08e3e25e3c920a1dabe31dcd7643bacb2John Reck
294dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    @Override
295dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    public boolean onKeyDown(int keyCode, KeyEvent evt) {
296dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        if (keyCode == KeyEvent.KEYCODE_ESCAPE && !isInTouchMode()) {
297dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb            finishInput(null, null, null);
298dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb            return true;
299dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        }
300dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        return super.onKeyDown(keyCode, evt);
301dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    }
302dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb
30380aad8d851601d39f73214c198111ca49e25f654Narayan Kamath    public SuggestionsAdapter getAdapter() {
30480aad8d851601d39f73214c198111ca49e25f654Narayan Kamath        return mAdapter;
30580aad8d851601d39f73214c198111ca49e25f654Narayan Kamath    }
3065119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath
30774e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb    /*
30874e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb     * no-op to prevent scrolling of webview when embedded titlebar
30974e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb     * gets edited
31074e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb     */
31174e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb    @Override
31274e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb    public boolean requestRectangleOnScreen(Rect rect, boolean immediate) {
31374e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb        return false;
31474e60c2d77ee84e6f2b5311dc465e2933d304fb8Michael Kolb    }
315305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
316305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    @Override
317f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
318f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath
319f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath    @Override
320f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath    public void onTextChanged(CharSequence s, int start, int before, int count) {
321305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        if (StateListener.STATE_HIGHLIGHTED == mState) {
322305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb            changeState(StateListener.STATE_EDITED);
323305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb        }
324305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb    }
325305b1c51f5e0d48a59d0e7c646b6cd0bc777a5dcMichael Kolb
326f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath    @Override
327f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath    public void afterTextChanged(Editable s) { }
328f3174a588cdf63ef59055998c23aad4b36b7856eNarayan Kamath
329fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb}
330