blob: 6a9111f24624c0b8c88fb9032d3aad50bffaedfe [file] [log] [blame]
Michael Kolb21ce4d22010-09-15 14:55:05 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import com.android.browser.search.SearchEngine;
20
21import android.app.SearchManager;
22import android.content.Context;
23import android.database.Cursor;
24import android.net.Uri;
John Reck35defff2010-11-11 14:06:45 -080025import android.os.AsyncTask;
Michael Kolb21ce4d22010-09-15 14:55:05 -070026import android.provider.BrowserContract;
Narayan Kamath5119edd2011-02-23 15:49:17 +000027import android.text.Html;
Michael Kolb21ce4d22010-09-15 14:55:05 -070028import android.text.TextUtils;
29import android.view.LayoutInflater;
30import android.view.View;
31import android.view.View.OnClickListener;
32import android.view.ViewGroup;
33import android.widget.BaseAdapter;
34import android.widget.Filter;
35import android.widget.Filterable;
36import android.widget.ImageView;
Michael Kolb21ce4d22010-09-15 14:55:05 -070037import android.widget.TextView;
38
39import java.util.ArrayList;
40import java.util.List;
Michael Kolb21ce4d22010-09-15 14:55:05 -070041
42/**
43 * adapter to wrap multiple cursors for url/search completions
44 */
Michael Kolbbd2dd642011-01-13 13:01:30 -080045public class SuggestionsAdapter extends BaseAdapter implements Filterable,
46 OnClickListener {
Michael Kolb21ce4d22010-09-15 14:55:05 -070047
Narayan Kamath5119edd2011-02-23 15:49:17 +000048 public static final int TYPE_BOOKMARK = 0;
49 public static final int TYPE_HISTORY = 1;
50 public static final int TYPE_SUGGEST_URL = 2;
51 public static final int TYPE_SEARCH = 3;
52 public static final int TYPE_SUGGEST = 4;
53 public static final int TYPE_VOICE_SEARCH = 5;
Michael Kolb21ce4d22010-09-15 14:55:05 -070054
55 private static final String[] COMBINED_PROJECTION =
56 {BrowserContract.Combined._ID, BrowserContract.Combined.TITLE,
57 BrowserContract.Combined.URL, BrowserContract.Combined.IS_BOOKMARK};
58
Michael Kolb21ce4d22010-09-15 14:55:05 -070059 private static final String COMBINED_SELECTION =
60 "(url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ? OR title LIKE ?)";
61
Narayan Kamath5119edd2011-02-23 15:49:17 +000062 final Context mContext;
63 final Filter mFilter;
John Reck35defff2010-11-11 14:06:45 -080064 SuggestionResults mMixedResults;
65 List<SuggestItem> mSuggestResults, mFilterResults;
Michael Kolb21ce4d22010-09-15 14:55:05 -070066 List<CursorSource> mSources;
67 boolean mLandscapeMode;
Narayan Kamath5119edd2011-02-23 15:49:17 +000068 final CompletionListener mListener;
69 final int mLinesPortrait;
70 final int mLinesLandscape;
71 final Object mResultsLock = new Object();
Michael Kolbcfa3af52010-12-14 10:36:11 -080072 List<String> mVoiceResults;
John Reck1605bef2011-01-10 18:11:18 -080073 boolean mReverseResults;
John Reck117f07d2011-01-24 09:39:03 -080074 boolean mIncognitoMode;
Michael Kolb21ce4d22010-09-15 14:55:05 -070075
76 interface CompletionListener {
77
78 public void onSearch(String txt);
79
Michael Kolbbd2dd642011-01-13 13:01:30 -080080 public void onSelect(String txt, int type, String extraData);
Michael Kolb21ce4d22010-09-15 14:55:05 -070081
82 }
83
84 public SuggestionsAdapter(Context ctx, CompletionListener listener) {
85 mContext = ctx;
86 mListener = listener;
87 mLinesPortrait = mContext.getResources().
88 getInteger(R.integer.max_suggest_lines_portrait);
89 mLinesLandscape = mContext.getResources().
90 getInteger(R.integer.max_suggest_lines_landscape);
Narayan Kamath5119edd2011-02-23 15:49:17 +000091
Michael Kolb21ce4d22010-09-15 14:55:05 -070092 mFilter = new SuggestFilter();
Michael Kolb21ce4d22010-09-15 14:55:05 -070093 addSource(new CombinedCursor());
94 }
95
Michael Kolbcfa3af52010-12-14 10:36:11 -080096 void setVoiceResults(List<String> voiceResults) {
97 mVoiceResults = voiceResults;
Michael Kolba50c4462010-12-15 10:49:12 -080098 notifyDataSetChanged();
Michael Kolbcfa3af52010-12-14 10:36:11 -080099 }
100
Michael Kolb21ce4d22010-09-15 14:55:05 -0700101 public void setLandscapeMode(boolean mode) {
102 mLandscapeMode = mode;
John Reck35defff2010-11-11 14:06:45 -0800103 notifyDataSetChanged();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700104 }
105
Michael Kolb21ce4d22010-09-15 14:55:05 -0700106 public void addSource(CursorSource c) {
107 if (mSources == null) {
108 mSources = new ArrayList<CursorSource>(5);
109 }
110 mSources.add(c);
111 }
112
113 @Override
114 public void onClick(View v) {
John Reckad373302010-12-17 15:28:13 -0800115 SuggestItem item = (SuggestItem) ((View) v.getParent()).getTag();
Narayan Kamath5119edd2011-02-23 15:49:17 +0000116
Michael Kolb21ce4d22010-09-15 14:55:05 -0700117 if (R.id.icon2 == v.getId()) {
118 // replace input field text with suggestion text
Narayan Kamath5119edd2011-02-23 15:49:17 +0000119 mListener.onSearch(getSuggestionUrl(item));
Michael Kolb21ce4d22010-09-15 14:55:05 -0700120 } else {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000121 mListener.onSelect(getSuggestionUrl(item), item.type, item.extra);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700122 }
123 }
124
125 @Override
126 public Filter getFilter() {
127 return mFilter;
128 }
129
130 @Override
131 public int getCount() {
Michael Kolbcfa3af52010-12-14 10:36:11 -0800132 if (mVoiceResults != null) {
133 return mVoiceResults.size();
134 }
John Reck35defff2010-11-11 14:06:45 -0800135 return (mMixedResults == null) ? 0 : mMixedResults.getLineCount();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700136 }
137
138 @Override
139 public SuggestItem getItem(int position) {
John Reck1605bef2011-01-10 18:11:18 -0800140 if (mReverseResults) {
141 position = (getCount() - 1) - position;
142 }
Michael Kolbcfa3af52010-12-14 10:36:11 -0800143 if (mVoiceResults != null) {
Michael Kolbbd2dd642011-01-13 13:01:30 -0800144 SuggestItem item = new SuggestItem(mVoiceResults.get(position),
145 null, TYPE_VOICE_SEARCH);
146 item.extra = Integer.toString(position);
147 return item;
Michael Kolbcfa3af52010-12-14 10:36:11 -0800148 }
John Reck35defff2010-11-11 14:06:45 -0800149 if (mMixedResults == null) {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700150 return null;
151 }
John Reckad373302010-12-17 15:28:13 -0800152 return mMixedResults.items.get(position);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700153 }
154
John Reck1605bef2011-01-10 18:11:18 -0800155 public void setReverseResults(boolean reverse) {
156 mReverseResults = reverse;
157 }
158
Michael Kolb21ce4d22010-09-15 14:55:05 -0700159 @Override
160 public long getItemId(int position) {
John Reck1605bef2011-01-10 18:11:18 -0800161 return position;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700162 }
163
164 @Override
165 public View getView(int position, View convertView, ViewGroup parent) {
166 final LayoutInflater inflater = LayoutInflater.from(mContext);
John Reck35defff2010-11-11 14:06:45 -0800167 View view = convertView;
168 if (view == null) {
John Reckad373302010-12-17 15:28:13 -0800169 view = inflater.inflate(R.layout.suggestion_item, parent, false);
John Reck35defff2010-11-11 14:06:45 -0800170 }
John Reckad373302010-12-17 15:28:13 -0800171 bindView(view, getItem(position));
172 return view;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700173 }
174
175 private void bindView(View view, SuggestItem item) {
176 // store item for click handling
177 view.setTag(item);
178 TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
179 TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
180 ImageView ic1 = (ImageView) view.findViewById(R.id.icon1);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700181 View ic2 = view.findViewById(R.id.icon2);
Michael Kolb7b20ddd2010-10-14 15:03:28 -0700182 View div = view.findViewById(R.id.divider);
Narayan Kamath5119edd2011-02-23 15:49:17 +0000183 tv1.setText(Html.fromHtml(item.title));
John Reckad373302010-12-17 15:28:13 -0800184 if (TextUtils.isEmpty(item.url)) {
185 tv2.setVisibility(View.GONE);
186 } else {
187 tv2.setVisibility(View.VISIBLE);
188 tv2.setText(item.url);
189 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700190 int id = -1;
191 switch (item.type) {
192 case TYPE_SUGGEST:
193 case TYPE_SEARCH:
Michael Kolbbd2dd642011-01-13 13:01:30 -0800194 case TYPE_VOICE_SEARCH:
Michael Kolb21ce4d22010-09-15 14:55:05 -0700195 id = R.drawable.ic_search_category_suggest;
196 break;
197 case TYPE_BOOKMARK:
198 id = R.drawable.ic_search_category_bookmark;
199 break;
200 case TYPE_HISTORY:
201 id = R.drawable.ic_search_category_history;
202 break;
203 case TYPE_SUGGEST_URL:
204 id = R.drawable.ic_search_category_browser;
205 break;
206 default:
207 id = -1;
208 }
209 if (id != -1) {
210 ic1.setImageDrawable(mContext.getResources().getDrawable(id));
211 }
Michael Kolbbd2dd642011-01-13 13:01:30 -0800212 ic2.setVisibility(((TYPE_SUGGEST == item.type)
213 || (TYPE_SEARCH == item.type)
214 || (TYPE_VOICE_SEARCH == item.type))
Michael Kolb21ce4d22010-09-15 14:55:05 -0700215 ? View.VISIBLE : View.GONE);
Michael Kolb7b20ddd2010-10-14 15:03:28 -0700216 div.setVisibility(ic2.getVisibility());
Michael Kolb21ce4d22010-09-15 14:55:05 -0700217 ic2.setOnClickListener(this);
John Reckad373302010-12-17 15:28:13 -0800218 view.findViewById(R.id.suggestion).setOnClickListener(this);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700219 }
220
John Reck35defff2010-11-11 14:06:45 -0800221 class SlowFilterTask extends AsyncTask<CharSequence, Void, List<SuggestItem>> {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700222
John Reck35defff2010-11-11 14:06:45 -0800223 @Override
224 protected List<SuggestItem> doInBackground(CharSequence... params) {
225 SuggestCursor cursor = new SuggestCursor();
226 cursor.runQuery(params[0]);
227 List<SuggestItem> results = new ArrayList<SuggestItem>();
228 int count = cursor.getCount();
229 for (int i = 0; i < count; i++) {
230 results.add(cursor.getItem());
231 cursor.moveToNext();
232 }
233 cursor.close();
234 return results;
235 }
236
237 @Override
238 protected void onPostExecute(List<SuggestItem> items) {
239 mSuggestResults = items;
240 mMixedResults = buildSuggestionResults();
241 notifyDataSetChanged();
John Reck35defff2010-11-11 14:06:45 -0800242 }
243 }
244
245 SuggestionResults buildSuggestionResults() {
246 SuggestionResults mixed = new SuggestionResults();
247 List<SuggestItem> filter, suggest;
248 synchronized (mResultsLock) {
249 filter = mFilterResults;
250 suggest = mSuggestResults;
251 }
252 if (filter != null) {
253 for (SuggestItem item : filter) {
254 mixed.addResult(item);
255 }
256 }
257 if (suggest != null) {
258 for (SuggestItem item : suggest) {
259 mixed.addResult(item);
260 }
261 }
262 return mixed;
263 }
264
265 class SuggestFilter extends Filter {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700266
267 @Override
268 public CharSequence convertResultToString(Object item) {
269 if (item == null) {
270 return "";
271 }
272 SuggestItem sitem = (SuggestItem) item;
273 if (sitem.title != null) {
274 return sitem.title;
275 } else {
276 return sitem.url;
277 }
278 }
279
John Reck35defff2010-11-11 14:06:45 -0800280 void startSuggestionsAsync(final CharSequence constraint) {
John Reck117f07d2011-01-24 09:39:03 -0800281 if (!mIncognitoMode) {
282 new SlowFilterTask().execute(constraint);
283 }
John Reck35defff2010-11-11 14:06:45 -0800284 }
285
Narayan Kamath5119edd2011-02-23 15:49:17 +0000286 private boolean shouldProcessEmptyQuery() {
287 final SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
288 return searchEngine.wantsEmptyQuery();
289 }
290
Michael Kolb21ce4d22010-09-15 14:55:05 -0700291 @Override
292 protected FilterResults performFiltering(CharSequence constraint) {
293 FilterResults res = new FilterResults();
Michael Kolbcfa3af52010-12-14 10:36:11 -0800294 if (mVoiceResults == null) {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000295 if (TextUtils.isEmpty(constraint) && !shouldProcessEmptyQuery()) {
Michael Kolbcfa3af52010-12-14 10:36:11 -0800296 res.count = 0;
297 res.values = null;
298 return res;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700299 }
Michael Kolbcfa3af52010-12-14 10:36:11 -0800300 startSuggestionsAsync(constraint);
301 List<SuggestItem> filterResults = new ArrayList<SuggestItem>();
302 if (constraint != null) {
303 for (CursorSource sc : mSources) {
304 sc.runQuery(constraint);
305 }
306 mixResults(filterResults);
307 }
308 synchronized (mResultsLock) {
309 mFilterResults = filterResults;
310 }
311 SuggestionResults mixed = buildSuggestionResults();
312 res.count = mixed.getLineCount();
313 res.values = mixed;
314 } else {
315 res.count = mVoiceResults.size();
316 res.values = mVoiceResults;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700317 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700318 return res;
319 }
320
John Reck35defff2010-11-11 14:06:45 -0800321 void mixResults(List<SuggestItem> results) {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000322 int maxLines = getMaxLines();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700323 for (int i = 0; i < mSources.size(); i++) {
324 CursorSource s = mSources.get(i);
John Reck35defff2010-11-11 14:06:45 -0800325 int n = Math.min(s.getCount(), maxLines);
326 maxLines -= n;
Michael Kolb0506f2d2010-10-14 16:20:16 -0700327 boolean more = false;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700328 for (int j = 0; j < n; j++) {
John Reck35defff2010-11-11 14:06:45 -0800329 results.add(s.getItem());
Michael Kolb21ce4d22010-09-15 14:55:05 -0700330 more = s.moveToNext();
331 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700332 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700333 }
334
335 @Override
336 protected void publishResults(CharSequence constraint, FilterResults fresults) {
Michael Kolbcfa3af52010-12-14 10:36:11 -0800337 if (fresults.values instanceof SuggestionResults) {
338 mMixedResults = (SuggestionResults) fresults.values;
John Recka005cd72011-02-01 11:46:53 -0800339 notifyDataSetChanged();
Michael Kolbcfa3af52010-12-14 10:36:11 -0800340 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700341 }
Narayan Kamath5119edd2011-02-23 15:49:17 +0000342 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700343
Narayan Kamath5119edd2011-02-23 15:49:17 +0000344 private int getMaxLines() {
345 int maxLines = mLandscapeMode ? mLinesLandscape : mLinesPortrait;
346 maxLines = (int) Math.ceil(maxLines / 2.0);
347 return maxLines;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700348 }
349
350 /**
351 * sorted list of results of a suggestion query
352 *
353 */
354 class SuggestionResults {
355
356 ArrayList<SuggestItem> items;
357 // count per type
358 int[] counts;
359
360 SuggestionResults() {
361 items = new ArrayList<SuggestItem>(24);
362 // n of types:
363 counts = new int[5];
364 }
365
366 int getTypeCount(int type) {
367 return counts[type];
368 }
369
370 void addResult(SuggestItem item) {
371 int ix = 0;
372 while ((ix < items.size()) && (item.type >= items.get(ix).type))
373 ix++;
374 items.add(ix, item);
375 counts[item.type]++;
376 }
377
378 int getLineCount() {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000379 return Math.min((mLandscapeMode ? mLinesLandscape : mLinesPortrait), items.size());
Michael Kolb21ce4d22010-09-15 14:55:05 -0700380 }
381
John Reck35defff2010-11-11 14:06:45 -0800382 @Override
Michael Kolb21ce4d22010-09-15 14:55:05 -0700383 public String toString() {
384 if (items == null) return null;
385 if (items.size() == 0) return "[]";
386 StringBuilder sb = new StringBuilder();
387 for (int i = 0; i < items.size(); i++) {
388 SuggestItem item = items.get(i);
389 sb.append(item.type + ": " + item.title);
390 if (i < items.size() - 1) {
391 sb.append(", ");
392 }
393 }
394 return sb.toString();
395 }
396 }
397
398 /**
399 * data object to hold suggestion values
400 */
Narayan Kamath80aad8d2011-02-23 12:01:13 +0000401 public class SuggestItem {
402 public String title;
403 public String url;
404 public int type;
405 public String extra;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700406
407 public SuggestItem(String text, String u, int t) {
408 title = text;
409 url = u;
410 type = t;
411 }
Michael Kolbbd2dd642011-01-13 13:01:30 -0800412
Michael Kolb21ce4d22010-09-15 14:55:05 -0700413 }
414
415 abstract class CursorSource {
416
417 Cursor mCursor;
418
419 boolean moveToNext() {
420 return mCursor.moveToNext();
421 }
422
423 public abstract void runQuery(CharSequence constraint);
424
425 public abstract SuggestItem getItem();
426
427 public int getCount() {
428 return (mCursor != null) ? mCursor.getCount() : 0;
429 }
430
431 public void close() {
432 if (mCursor != null) {
433 mCursor.close();
434 }
435 }
436 }
437
438 /**
439 * combined bookmark & history source
440 */
441 class CombinedCursor extends CursorSource {
442
443 @Override
444 public SuggestItem getItem() {
445 if ((mCursor != null) && (!mCursor.isAfterLast())) {
446 String title = mCursor.getString(1);
447 String url = mCursor.getString(2);
448 boolean isBookmark = (mCursor.getInt(3) == 1);
449 return new SuggestItem(getTitle(title, url), getUrl(title, url),
450 isBookmark ? TYPE_BOOKMARK : TYPE_HISTORY);
451 }
452 return null;
453 }
454
455 @Override
456 public void runQuery(CharSequence constraint) {
457 // constraint != null
458 if (mCursor != null) {
459 mCursor.close();
460 }
461 String like = constraint + "%";
462 String[] args = null;
463 String selection = null;
464 if (like.startsWith("http") || like.startsWith("file")) {
465 args = new String[1];
466 args[0] = like;
467 selection = "url LIKE ?";
468 } else {
469 args = new String[5];
470 args[0] = "http://" + like;
471 args[1] = "http://www." + like;
472 args[2] = "https://" + like;
473 args[3] = "https://www." + like;
474 // To match against titles.
475 args[4] = like;
476 selection = COMBINED_SELECTION;
477 }
478 Uri.Builder ub = BrowserContract.Combined.CONTENT_URI.buildUpon();
Michael Kolb0506f2d2010-10-14 16:20:16 -0700479 ub.appendQueryParameter(BrowserContract.PARAM_LIMIT,
John Reckad373302010-12-17 15:28:13 -0800480 Integer.toString(Math.max(mLinesLandscape, mLinesPortrait)));
John Reck3dff1ce2010-12-10 11:13:57 -0800481 BookmarkUtils.addAccountInfo(mContext, ub);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700482 mCursor =
Michael Kolb0506f2d2010-10-14 16:20:16 -0700483 mContext.getContentResolver().query(ub.build(), COMBINED_PROJECTION,
Michael Kolb21ce4d22010-09-15 14:55:05 -0700484 selection,
485 (constraint != null) ? args : null,
John Reck3dff1ce2010-12-10 11:13:57 -0800486 BrowserContract.Combined.IS_BOOKMARK + " DESC, " +
Michael Kolb21ce4d22010-09-15 14:55:05 -0700487 BrowserContract.Combined.VISITS + " DESC, " +
488 BrowserContract.Combined.DATE_LAST_VISITED + " DESC");
489 if (mCursor != null) {
490 mCursor.moveToFirst();
491 }
492 }
493
494 /**
495 * Provides the title (text line 1) for a browser suggestion, which should be the
496 * webpage title. If the webpage title is empty, returns the stripped url instead.
497 *
498 * @return the title string to use
499 */
500 private String getTitle(String title, String url) {
501 if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
John Reckfb3017f2010-10-26 19:01:24 -0700502 title = UrlUtils.stripUrl(url);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700503 }
504 return title;
505 }
506
507 /**
508 * Provides the subtitle (text line 2) for a browser suggestion, which should be the
509 * webpage url. If the webpage title is empty, then the url should go in the title
510 * instead, and the subtitle should be empty, so this would return null.
511 *
512 * @return the subtitle string to use, or null if none
513 */
514 private String getUrl(String title, String url) {
John Reck7d132b12010-10-26 15:10:21 -0700515 if (TextUtils.isEmpty(title)
516 || TextUtils.getTrimmedLength(title) == 0
517 || title.equals(url)) {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700518 return null;
519 } else {
John Reckfb3017f2010-10-26 19:01:24 -0700520 return UrlUtils.stripUrl(url);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700521 }
522 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700523 }
524
Michael Kolb21ce4d22010-09-15 14:55:05 -0700525 class SuggestCursor extends CursorSource {
526
527 @Override
528 public SuggestItem getItem() {
529 if (mCursor != null) {
530 String title = mCursor.getString(
531 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
532 String text2 = mCursor.getString(
533 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
534 String url = mCursor.getString(
535 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL));
536 String uri = mCursor.getString(
537 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA));
538 int type = (TextUtils.isEmpty(url)) ? TYPE_SUGGEST : TYPE_SUGGEST_URL;
John Reck40f720e2010-11-10 11:57:04 -0800539 SuggestItem item = new SuggestItem(title, url, type);
540 item.extra = mCursor.getString(
541 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA));
542 return item;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700543 }
544 return null;
545 }
546
547 @Override
548 public void runQuery(CharSequence constraint) {
549 if (mCursor != null) {
550 mCursor.close();
551 }
Narayan Kamath5119edd2011-02-23 15:49:17 +0000552 SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700553 if (!TextUtils.isEmpty(constraint)) {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700554 if (searchEngine != null && searchEngine.supportsSuggestions()) {
555 mCursor = searchEngine.getSuggestions(mContext, constraint.toString());
556 if (mCursor != null) {
557 mCursor.moveToFirst();
558 }
559 }
560 } else {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000561 if (searchEngine.wantsEmptyQuery()) {
562 mCursor = searchEngine.getSuggestions(mContext, "");
563 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700564 mCursor = null;
565 }
566 }
567
568 }
569
Narayan Kamath5119edd2011-02-23 15:49:17 +0000570 private boolean useInstant() {
571 return BrowserSettings.getInstance().useInstant();
572 }
573
John Reck35defff2010-11-11 14:06:45 -0800574 public void clearCache() {
575 mFilterResults = null;
576 mSuggestResults = null;
Narayan Kamath5119edd2011-02-23 15:49:17 +0000577 notifyDataSetInvalidated();
John Reck35defff2010-11-11 14:06:45 -0800578 }
579
John Reck117f07d2011-01-24 09:39:03 -0800580 public void setIncognitoMode(boolean incognito) {
581 mIncognitoMode = incognito;
582 clearCache();
583 }
Narayan Kamath5119edd2011-02-23 15:49:17 +0000584
585 static String getSuggestionTitle(SuggestItem item) {
586 // There must be a better way to strip HTML from things.
587 // This method is used in multiple places. It is also more
588 // expensive than a standard html escaper.
589 return (item.title != null) ? Html.fromHtml(item.title).toString() : null;
590 }
591
592 static String getSuggestionUrl(SuggestItem item) {
593 final String title = SuggestionsAdapter.getSuggestionTitle(item);
594
595 if (TextUtils.isEmpty(item.url)) {
596 return title;
597 }
598
599 return item.url;
600 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700601}