new two column suggestion dropdown
    http://b/issue?id=3039704

Change-Id: I8b32553682cc547c695d0089e6633ead77426869
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 5406d85..a8993d5 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -234,8 +234,6 @@
             mTitleBar.setProgress(100);
             mFakeTitleBar = new TitleBarXLarge(this);
             ActionBar actionBar = getActionBar();
-            actionBar.setBackgroundDrawable(getResources().
-                    getDrawable(R.drawable.tabbar_bg));
             mTabBar = new TabBar(this, mTabControl, (TitleBarXLarge) mFakeTitleBar);
             actionBar.setCustomNavigationMode(mTabBar);
             // disable built in zoom controls
diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
new file mode 100644
index 0000000..7cfd78e
--- /dev/null
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -0,0 +1,591 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import com.android.browser.search.SearchEngine;
+
+import android.app.SearchManager;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.BrowserContract;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ImageView;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * adapter to wrap multiple cursors for url/search completions
+ */
+public class SuggestionsAdapter extends BaseAdapter implements Filterable, OnClickListener {
+
+    static final int TYPE_SEARCH = 0;
+    static final int TYPE_SUGGEST = 1;
+    static final int TYPE_BOOKMARK = 2;
+    static final int TYPE_SUGGEST_URL = 3;
+    static final int TYPE_HISTORY = 4;
+
+    private static final String[] COMBINED_PROJECTION =
+            {BrowserContract.Combined._ID, BrowserContract.Combined.TITLE,
+                    BrowserContract.Combined.URL, BrowserContract.Combined.IS_BOOKMARK};
+
+    private static final String[] SEARCHES_PROJECTION = {BrowserContract.Searches.SEARCH};
+
+    private static final String COMBINED_SELECTION =
+            "(url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ? OR title LIKE ?)";
+
+    // Regular expression which matches http://, followed by some stuff, followed by
+    // optionally a trailing slash, all matched as separate groups.
+    private static final Pattern STRIP_URL_PATTERN = Pattern.compile("^(http://)(.*?)(/$)?");
+
+    Context mContext;
+    Filter mFilter;
+    SuggestionResults mResults;
+    List<CursorSource> mSources;
+    boolean mLandscapeMode;
+    CompletionListener mListener;
+    int mLinesPortrait;
+    int mLinesLandscape;
+
+    interface CompletionListener {
+
+        public void onSearch(String txt);
+
+        public void onSelect(String txt);
+
+    }
+
+    public SuggestionsAdapter(Context ctx, CompletionListener listener) {
+        mContext = ctx;
+        mListener = listener;
+        mLinesPortrait = mContext.getResources().
+                getInteger(R.integer.max_suggest_lines_portrait);
+        mLinesLandscape = mContext.getResources().
+                getInteger(R.integer.max_suggest_lines_landscape);
+        mFilter = new SuggestFilter();
+        addSource(new SuggestCursor());
+        addSource(new SearchesCursor());
+        addSource(new CombinedCursor());
+    }
+
+    public void setLandscapeMode(boolean mode) {
+        mLandscapeMode = mode;
+    }
+
+    public int getLeftCount() {
+        return mResults.getLeftCount();
+    }
+
+    public int getRightCount() {
+        return mResults.getRightCount();
+    }
+
+    public void addSource(CursorSource c) {
+        if (mSources == null) {
+            mSources = new ArrayList<CursorSource>(5);
+        }
+        mSources.add(c);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (R.id.icon2 == v.getId()) {
+            // replace input field text with suggestion text
+            SuggestItem item = (SuggestItem) ((View) v.getParent()).getTag();
+            mListener.onSearch(item.title);
+        } else {
+            SuggestItem item = (SuggestItem) v.getTag();
+            mListener.onSelect((TextUtils.isEmpty(item.url)? item.title : item.url));
+        }
+    }
+
+    @Override
+    public Filter getFilter() {
+        return mFilter;
+    }
+
+    @Override
+    public int getCount() {
+        return (mResults == null) ? 0 : mResults.getLineCount();
+    }
+
+    @Override
+    public SuggestItem getItem(int position) {
+        if (mResults == null) {
+            return null;
+        }
+        if (mLandscapeMode) {
+            if (position >= mResults.getLineCount()) {
+                // right column
+                position = position - mResults.getLineCount();
+                // index in column
+                if (position >= mResults.getRightCount()) {
+                    return null;
+                }
+                return mResults.items.get(position + mResults.getLeftCount());
+            } else {
+                // left column
+                if (position >= mResults.getLeftCount()) {
+                    return null;
+                }
+                return mResults.items.get(position);
+            }
+        } else {
+            return mResults.items.get(position);
+        }
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        if (mLandscapeMode) {
+            View view = inflater.inflate(R.layout.suggestion_two_column, parent, false);
+            SuggestItem item = getItem(position);
+            View iv = view.findViewById(R.id.suggest1);
+            LayoutParams lp = new LayoutParams(iv.getLayoutParams());
+            lp.weight = 0.5f;
+            iv.setLayoutParams(lp);
+            if (item != null) {
+                bindView(iv, item);
+            } else {
+                iv.setVisibility((mResults.getLeftCount() == 0) ? View.GONE : 
+                        View.INVISIBLE);
+            }
+            item = getItem(position + mResults.getLineCount());
+            iv = view.findViewById(R.id.suggest2);
+            lp = new LayoutParams(iv.getLayoutParams());
+            lp.weight = 0.5f;
+            iv.setLayoutParams(lp);
+            if (item != null) {
+                bindView(iv, item);
+            } else {
+                iv.setVisibility((mResults.getRightCount() == 0) ? View.GONE : 
+                        View.INVISIBLE);
+            }
+            return view;
+        } else {
+            View view = inflater.inflate(R.layout.suggestion_item, parent, false);
+            bindView(view, getItem(position));
+            return view;
+        }
+    }
+
+    private void bindView(View view, SuggestItem item) {
+        // store item for click handling
+        view.setTag(item);
+        TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
+        TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
+        ImageView ic1 = (ImageView) view.findViewById(R.id.icon1);
+        View spacer = view.findViewById(R.id.spacer);
+        View ic2 = view.findViewById(R.id.icon2);
+        tv1.setText(item.title);
+        tv2.setText(item.url);
+        int id = -1;
+        switch (item.type) {
+            case TYPE_SUGGEST:
+            case TYPE_SEARCH:
+                id = R.drawable.ic_search_category_suggest;
+                break;
+            case TYPE_BOOKMARK:
+                id = R.drawable.ic_search_category_bookmark;
+                break;
+            case TYPE_HISTORY:
+                id = R.drawable.ic_search_category_history;
+                break;
+            case TYPE_SUGGEST_URL:
+                id = R.drawable.ic_search_category_browser;
+                break;
+            default:
+                id = -1;
+        }
+        if (id != -1) {
+            ic1.setImageDrawable(mContext.getResources().getDrawable(id));
+        }
+        ic2.setVisibility(((TYPE_SUGGEST == item.type) || (TYPE_SEARCH == item.type))
+                ? View.VISIBLE : View.GONE);
+        spacer.setVisibility(((TYPE_SUGGEST == item.type) || (TYPE_SEARCH == item.type))
+                ? View.GONE : View.INVISIBLE);
+        view.setOnClickListener(this);
+        ic2.setOnClickListener(this);
+    }
+
+    class SuggestFilter extends Filter {
+
+        int count;
+        SuggestionResults results;
+
+        @Override
+        public CharSequence convertResultToString(Object item) {
+            if (item == null) {
+                return "";
+            }
+            SuggestItem sitem = (SuggestItem) item;
+            if (sitem.title != null) {
+                return sitem.title;
+            } else {
+                return sitem.url;
+            }
+        }
+
+        @Override
+        protected FilterResults performFiltering(CharSequence constraint) {
+            FilterResults res = new FilterResults();
+            if (TextUtils.isEmpty(constraint)) {
+                res.count = 0;
+                res.values = null;
+                return res;
+            }
+            results = new SuggestionResults();
+            count = 0;
+            if (constraint != null) {
+                for (CursorSource sc : mSources) {
+                    sc.runQuery(constraint);
+                }
+                mixResults();
+            }
+            res.count = count;
+            res.values = results;
+            return res;
+        }
+
+        void mixResults() {
+            for (int i = 0; i < mSources.size(); i++) {
+                CursorSource s = mSources.get(i);
+                int n = Math.min(s.getCount(), (mLandscapeMode ? mLinesLandscape 
+                        : mLinesPortrait));
+                boolean more = true;
+                for (int j = 0; j < n; j++) {
+                    results.addResult(s.getItem());
+                    more = s.moveToNext();
+                }
+                if (s instanceof SuggestCursor) {
+                    int k = n;
+                    while (more && (k < mLinesPortrait)) {
+                        SuggestItem item  = s.getItem();
+                        if (item.type == TYPE_SUGGEST_URL) {
+                            results.addResult(item);
+                            break;
+                        }
+                        more = s.moveToNext();
+                        k++;
+
+                    }
+                }
+            }
+
+        }
+
+        @Override
+        protected void publishResults(CharSequence constraint, FilterResults fresults) {
+            mResults = (SuggestionResults) fresults.values;
+            notifyDataSetChanged();
+        }
+
+    }
+
+    /**
+     * sorted list of results of a suggestion query
+     *
+     */
+    class SuggestionResults {
+
+        ArrayList<SuggestItem> items;
+        // count per type
+        int[] counts;
+
+        SuggestionResults() {
+            items = new ArrayList<SuggestItem>(24);
+            // n of types:
+            counts = new int[5];
+        }
+
+        int getTypeCount(int type) {
+            return counts[type];
+        }
+
+        void addResult(SuggestItem item) {
+            int ix = 0;
+            while ((ix < items.size()) && (item.type >= items.get(ix).type))
+                ix++;
+            items.add(ix, item);
+            counts[item.type]++;
+        }
+
+        int getLineCount() {
+            if (mLandscapeMode) {
+                return Math.max(getLeftCount(), getRightCount());
+            } else {
+                return getLeftCount() + getRightCount();
+            }
+        }
+
+        int getLeftCount() {
+            return counts[TYPE_SEARCH] + counts[TYPE_SUGGEST];
+        }
+
+        int getRightCount() {
+            return counts[TYPE_BOOKMARK] + counts[TYPE_HISTORY] + counts[TYPE_SUGGEST_URL];
+        }
+
+        public String toString() {
+            if (items == null) return null;
+            if (items.size() == 0) return "[]";
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < items.size(); i++) {
+                SuggestItem item = items.get(i);
+                sb.append(item.type + ": " + item.title);
+                if (i < items.size() - 1) {
+                    sb.append(", ");
+                }
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * data object to hold suggestion values
+     */
+    class SuggestItem {
+        String title;
+        String url;
+        int type;
+
+        public SuggestItem(String text, String u, int t) {
+            title = text;
+            url = u;
+            type = t;
+        }
+    }
+
+    abstract class CursorSource {
+
+        Cursor mCursor;
+
+        boolean moveToNext() {
+            return mCursor.moveToNext();
+        }
+
+        public abstract void runQuery(CharSequence constraint);
+
+        public abstract SuggestItem getItem();
+
+        public int getCount() {
+            return (mCursor != null) ? mCursor.getCount() : 0;
+        }
+
+        public void close() {
+            if (mCursor != null) {
+                mCursor.close();
+            }
+        }
+    }
+
+    /**
+     * combined bookmark & history source
+     */
+    class CombinedCursor extends CursorSource {
+
+        @Override
+        public SuggestItem getItem() {
+            if ((mCursor != null) && (!mCursor.isAfterLast())) {
+                String title = mCursor.getString(1);
+                String url = mCursor.getString(2);
+                boolean isBookmark = (mCursor.getInt(3) == 1);
+                return new SuggestItem(getTitle(title, url), getUrl(title, url),
+                        isBookmark ? TYPE_BOOKMARK : TYPE_HISTORY);
+            }
+            return null;
+        }
+
+        @Override
+        public void runQuery(CharSequence constraint) {
+            // constraint != null
+            if (mCursor != null) {
+                mCursor.close();
+            }
+            String like = constraint + "%";
+            String[] args = null;
+            String selection = null;
+            if (like.startsWith("http") || like.startsWith("file")) {
+                args = new String[1];
+                args[0] = like;
+                selection = "url LIKE ?";
+            } else {
+                args = new String[5];
+                args[0] = "http://" + like;
+                args[1] = "http://www." + like;
+                args[2] = "https://" + like;
+                args[3] = "https://www." + like;
+                // To match against titles.
+                args[4] = like;
+                selection = COMBINED_SELECTION;
+            }
+            Uri.Builder ub = BrowserContract.Combined.CONTENT_URI.buildUpon();
+            ub.appendQueryParameter(BrowserContract.PARAM_LIMIT, 
+                    Integer.toString(mLinesPortrait));
+            mCursor =
+                    mContext.getContentResolver().query(ub.build(), COMBINED_PROJECTION, 
+                            selection,
+                            (constraint != null) ? args : null,
+                            BrowserContract.Combined.VISITS + " DESC, " +
+                            BrowserContract.Combined.DATE_LAST_VISITED + " DESC");
+            if (mCursor != null) {
+                mCursor.moveToFirst();
+            }
+        }
+
+        /**
+         * Provides the title (text line 1) for a browser suggestion, which should be the
+         * webpage title. If the webpage title is empty, returns the stripped url instead.
+         *
+         * @return the title string to use
+         */
+        private String getTitle(String title, String url) {
+            if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
+                title = stripUrl(url);
+            }
+            return title;
+        }
+
+        /**
+         * Provides the subtitle (text line 2) for a browser suggestion, which should be the
+         * webpage url. If the webpage title is empty, then the url should go in the title
+         * instead, and the subtitle should be empty, so this would return null.
+         *
+         * @return the subtitle string to use, or null if none
+         */
+        private String getUrl(String title, String url) {
+            if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
+                return null;
+            } else {
+                return stripUrl(url);
+            }
+        }
+
+        /**
+         * Strips the provided url of preceding "http://" and any trailing "/". Does not
+         * strip "https://". If the provided string cannot be stripped, the original string
+         * is returned.
+         *
+         * TODO: Put this in TextUtils to be used by other packages doing something similar.
+         *
+         * @param url a url to strip, like "http://www.google.com/"
+         * @return a stripped url like "www.google.com", or the original string if it could
+         *         not be stripped
+         */
+        private String stripUrl(String url) {
+            if (url == null) return null;
+            Matcher m = STRIP_URL_PATTERN.matcher(url);
+            if (m.matches() && m.groupCount() == 3) {
+                return m.group(2);
+            } else {
+                return url;
+            }
+        }
+
+    }
+
+    class SearchesCursor extends CursorSource {
+
+        @Override
+        public SuggestItem getItem() {
+            if ((mCursor != null) && (!mCursor.isAfterLast())) {
+                return new SuggestItem(mCursor.getString(0), null, TYPE_SEARCH);
+            }
+            return null;
+        }
+
+        @Override
+        public void runQuery(CharSequence constraint) {
+            // constraint != null
+            if (mCursor != null) {
+                mCursor.close();
+            }
+            String like = constraint + "%";
+            String[] args = new String[] {constraint.toString()};
+            String selection = BrowserContract.Searches.SEARCH + " LIKE ?";
+            Uri.Builder ub = BrowserContract.Searches.CONTENT_URI.buildUpon();
+            ub.appendQueryParameter(BrowserContract.PARAM_LIMIT, 
+                    Integer.toString(mLinesPortrait));
+            mCursor =
+                    mContext.getContentResolver().query(ub.build(), SEARCHES_PROJECTION, 
+                            selection,
+                            args, BrowserContract.Searches.DATE + " DESC");
+            if (mCursor != null) {
+                mCursor.moveToFirst();
+            }
+        }
+
+    }
+
+    class SuggestCursor extends CursorSource {
+
+        @Override
+        public SuggestItem getItem() {
+            if (mCursor != null) {
+                String title = mCursor.getString(
+                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
+                String text2 = mCursor.getString(
+                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
+                String url = mCursor.getString(
+                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL));
+                String uri = mCursor.getString(
+                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA));
+                int type = (TextUtils.isEmpty(url)) ? TYPE_SUGGEST : TYPE_SUGGEST_URL;
+                return new SuggestItem(title, url, type);
+            }
+            return null;
+        }
+
+        @Override
+        public void runQuery(CharSequence constraint) {
+            if (mCursor != null) {
+                mCursor.close();
+            }
+            if (!TextUtils.isEmpty(constraint)) {
+                SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
+                if (searchEngine != null && searchEngine.supportsSuggestions()) {
+                    mCursor = searchEngine.getSuggestions(mContext, constraint.toString());
+                    if (mCursor != null) {
+                        mCursor.moveToFirst();
+                    }
+                }
+            } else {
+                mCursor = null;
+            }
+        }
+
+    }
+
+}
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index c52c074..da39307 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -101,6 +101,7 @@
         mGoButton.setOnClickListener(this);
         mUrlFocused.setUrlInputListener(this);
         mUrlUnfocused.setOnFocusChangeListener(this);
+        mUrlFocused.setContainer(mFocusContainer);
     }
     
     public void onFocusChange(View v, boolean hasFocus) {
@@ -217,7 +218,7 @@
 
     @Override
     /* package */ void setDisplayTitle(String title) {
-        mUrlFocused.setText(title);
+        mUrlFocused.setText(title, false);
         mUrlUnfocused.setText(title);
     }
 
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 96a5980..8662f55 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -16,31 +16,18 @@
 
 package com.android.browser;
 
-import android.app.SearchManager;
+import com.android.browser.SuggestionsAdapter.CompletionListener;
+
 import android.content.ContentResolver;
 import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.text.Editable;
-import android.text.SpannableStringBuilder;
-import android.text.TextWatcher;
-import android.text.style.BackgroundColorSpan;
+import android.content.res.Configuration;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.ActionMode;
 import android.view.KeyEvent;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
-import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.AutoCompleteTextView;
-import android.widget.CursorAdapter;
-import android.widget.Filterable;
-import android.widget.ImageButton;
-import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
@@ -49,13 +36,14 @@
  * handling suggestions
  */
 public class UrlInputView extends AutoCompleteTextView
-        implements OnFocusChangeListener, OnClickListener, OnEditorActionListener {
+        implements OnFocusChangeListener, OnEditorActionListener, CompletionListener {
 
     private UrlInputListener   mListener;
     private InputMethodManager mInputManager;
     private SuggestionsAdapter mAdapter;
-
     private OnFocusChangeListener mWrappedFocusListener;
+    private View mContainer;
+    private boolean mLandscape;
 
     public UrlInputView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -77,10 +65,36 @@
         setOnEditorActionListener(this);
         super.setOnFocusChangeListener(this);
         final ContentResolver cr = mContext.getContentResolver();
-        mAdapter = new SuggestionsAdapter(mContext,
-                BrowserProvider.getBookmarksSuggestions(cr, null));
+        mAdapter = new SuggestionsAdapter(ctx, this);
         setAdapter(mAdapter);
         setSelectAllOnFocus(false);
+        onConfigurationChanged(ctx.getResources().getConfiguration());
+    }
+
+    void setContainer(View container) {
+        mContainer = container;
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration config) {
+        mLandscape = (config.orientation &
+                Configuration.ORIENTATION_LANDSCAPE) > 0;
+        if (isPopupShowing() && (getVisibility() == View.VISIBLE)) {
+            dismissDropDown();
+            getFilter().filter(getText());
+        }
+    }
+
+    @Override
+    public void showDropDown() {
+        int width = mContainer.getWidth();
+        if ((mAdapter.getLeftCount() == 0) || (mAdapter.getRightCount() == 0)) {
+            width = width / 2;
+        }
+        setDropDownWidth(width);
+        setDropDownHorizontalOffset(-getLeft());
+        mAdapter.setLandscapeMode(mLandscape);
+        super.showDropDown();
     }
 
     @Override
@@ -99,7 +113,7 @@
         finishInput(getText().toString());
         return true;
     }
-    
+
     @Override
     public void onFocusChange(View v, boolean hasFocus) {
         if (hasFocus) {
@@ -112,19 +126,6 @@
         }
     }
 
-    @Override
-    public void onClick(View view) {
-        if (view instanceof ImageButton) {
-            // user pressed edit search button
-            String text = mAdapter.getViewString((View)view.getParent());
-            mListener.onEdit(text);
-        } else {
-            // user selected dropdown item
-            String url = mAdapter.getViewString(view);
-            finishInput(url);
-        }
-    }
-
     public void setUrlInputListener(UrlInputListener listener) {
         mListener = listener;
     }
@@ -144,6 +145,18 @@
         }
     }
 
+    // Completion Listener
+
+    @Override
+    public void onSearch(String search) {
+        mListener.onEdit(search);
+    }
+
+    @Override
+    public void onSelect(String url) {
+        finishInput(url);
+    }
+
     @Override
     public boolean onKeyPreIme(int keyCode, KeyEvent evt) {
         if (keyCode == KeyEvent.KEYCODE_BACK) {
@@ -155,84 +168,12 @@
     }
 
     interface UrlInputListener {
+
         public void onDismiss();
+
         public void onAction(String text);
+
         public void onEdit(String text);
-    }
-
-    /**
-     * adapter used by suggestion dropdown
-     */
-    class SuggestionsAdapter extends CursorAdapter implements Filterable {
-
-        private Cursor          mLastCursor;
-        private ContentResolver mContent;
-        private int             mIndexText1;
-        private int             mIndexText2;
-        private int             mIndexIcon;
-
-        public SuggestionsAdapter(Context context, Cursor c) {
-            super(context, c);
-            mContent = context.getContentResolver();
-            mIndexText1 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
-            mIndexText2 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL);
-            mIndexIcon = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
-        }
-
-        public String getViewString(View view) {
-            TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
-            if (tv2.getText().length() > 0) {
-                return tv2.getText().toString();
-            } else {
-                TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
-                return tv1.getText().toString();
-            }
-        }
-
-        @Override
-        public View newView(Context context, Cursor cursor, ViewGroup parent) {
-            final LayoutInflater inflater = LayoutInflater.from(context);
-            final View view = inflater.inflate(
-                    R.layout.url_dropdown_item, parent, false);
-            bindView(view, context, cursor);
-            return view;
-        }
-
-        @Override
-        public void bindView(View view, Context context, Cursor cursor) {
-            TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
-            TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
-            ImageView ic1 = (ImageView) view.findViewById(R.id.icon1);
-            View ic2 = view.findViewById(R.id.icon2);
-            tv1.setText(cursor.getString(mIndexText1));
-            String url = cursor.getString(mIndexText2);
-            tv2.setText((url != null) ? url : "");
-            ic2.setOnClickListener(UrlInputView.this);
-            // assume an id
-            try {
-                int id = Integer.parseInt(cursor.getString(mIndexIcon));
-                Drawable d = context.getResources().getDrawable(id);
-                ic1.setImageDrawable(d);
-                ic2.setVisibility((id == R.drawable.ic_search_category_suggest)? View.VISIBLE : View.GONE);
-            } catch (NumberFormatException nfx) {
-            }
-            view.setOnClickListener(UrlInputView.this);
-        }
-
-        @Override
-        public String convertToString(Cursor cursor) {
-            return cursor.getString(mIndexText1);
-        }
-
-        @Override
-        public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
-            if (getFilterQueryProvider() != null) {
-                return getFilterQueryProvider().runQuery(constraint);
-            }
-            mLastCursor = BrowserProvider.getBookmarksSuggestions(mContent,
-                    (constraint != null) ? constraint.toString() : null);
-            return mLastCursor;
-        }
 
     }
 
diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java
index 47d92de..973f229 100644
--- a/src/com/android/browser/provider/BrowserProvider2.java
+++ b/src/com/android/browser/provider/BrowserProvider2.java
@@ -64,6 +64,8 @@
 
     static final String DEFAULT_SORT_HISTORY = History.DATE_LAST_VISITED + " DESC";
 
+    static final String DEFAULT_SORT_SEARCHES = Searches.DATE + " DESC";
+
     static final int BOOKMARKS = 1000;
     static final int BOOKMARKS_ID = 1001;
     static final int BOOKMARKS_FOLDER = 1002;
@@ -96,12 +98,13 @@
 
     static final HashMap<String, String> ACCOUNTS_PROJECTION_MAP = new HashMap<String, String>();
     static final HashMap<String, String> BOOKMARKS_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> OTHER_BOOKMARKS_PROJECTION_MAP = 
+    static final HashMap<String, String> OTHER_BOOKMARKS_PROJECTION_MAP =
             new HashMap<String, String>();
     static final HashMap<String, String> HISTORY_PROJECTION_MAP = new HashMap<String, String>();
     static final HashMap<String, String> SYNC_STATE_PROJECTION_MAP = new HashMap<String, String>();
     static final HashMap<String, String> IMAGES_PROJECTION_MAP = new HashMap<String, String>();
     static final HashMap<String, String> COMBINED_PROJECTION_MAP = new HashMap<String, String>();
+    static final HashMap<String, String> SEARCHES_PROJECTION_MAP = new HashMap<String, String>();
 
     static {
         final UriMatcher matcher = URI_MATCHER;
@@ -208,7 +211,13 @@
         map.put(Combined.THUMBNAIL, Combined.THUMBNAIL);
         map.put(Combined.TOUCH_ICON, Combined.TOUCH_ICON);
         map.put(Combined.USER_ENTERED, Combined.USER_ENTERED);
-    }
+
+        // Searches
+        map = SEARCHES_PROJECTION_MAP;
+        map.put(Searches._ID, Searches._ID);
+        map.put(Searches.SEARCH, Searches.SEARCH);
+        map.put(Searches.DATE, Searches.DATE);
+}
 
     static final String bookmarkOrHistoryColumn(String column) {
         return "CASE WHEN bookmarks." + column + " IS NOT NULL THEN " +
@@ -333,7 +342,7 @@
             mSyncHelper.onDatabaseOpened(db);
         }
 
-        
+
         private void createDefaultBookmarks(SQLiteDatabase db) {
             ContentValues values = new ContentValues();
             // TODO figure out how to deal with localization for the defaults
@@ -667,6 +676,21 @@
                 break;
             }
 
+            case SEARCHES_ID: {
+                selection = DatabaseUtils.concatenateWhere(selection, TABLE_SEARCHES + "._id=?");
+                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
+                        new String[] { Long.toString(ContentUris.parseId(uri)) });
+                // fall through
+            }
+            case SEARCHES: {
+                if (sortOrder == null) {
+                    sortOrder = DEFAULT_SORT_SEARCHES;
+                }
+                qb.setTables(TABLE_SEARCHES);
+                qb.setProjectionMap(SEARCHES_PROJECTION_MAP);
+                break;
+            }
+
             case SYNCSTATE: {
                 return mSyncHelper.query(db, projection, selection, selectionArgs, sortOrder);
             }