blob: 8ab78e242c0543b3928dcfd4abb4e53da07193aa [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
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
Michael Kolb21ce4d22010-09-15 14:55:05 -070018
Michael Kolb21ce4d22010-09-15 14:55:05 -070019import android.app.SearchManager;
20import android.content.Context;
21import android.database.Cursor;
22import android.net.Uri;
John Reck35defff2010-11-11 14:06:45 -080023import android.os.AsyncTask;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080024
Bijan Amirzada41242f22014-03-21 12:12:18 -070025import com.android.browser.R;
26import com.android.browser.platformsupport.BrowserContract;
27import com.android.browser.provider.BrowserProvider2.OmniboxSuggestions;
28import com.android.browser.search.SearchEngine;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080029
Narayan Kamath5119edd2011-02-23 15:49:17 +000030import android.text.Html;
Michael Kolb21ce4d22010-09-15 14:55:05 -070031import android.text.TextUtils;
32import android.view.LayoutInflater;
33import android.view.View;
34import android.view.View.OnClickListener;
35import android.view.ViewGroup;
36import android.widget.BaseAdapter;
37import android.widget.Filter;
38import android.widget.Filterable;
39import android.widget.ImageView;
Michael Kolb21ce4d22010-09-15 14:55:05 -070040import android.widget.TextView;
41
Michael Kolb5ff5c8b2012-05-03 11:37:58 -070042
Michael Kolb21ce4d22010-09-15 14:55:05 -070043import java.util.ArrayList;
44import java.util.List;
Michael Kolb21ce4d22010-09-15 14:55:05 -070045
46/**
47 * adapter to wrap multiple cursors for url/search completions
48 */
Michael Kolbbd2dd642011-01-13 13:01:30 -080049public class SuggestionsAdapter extends BaseAdapter implements Filterable,
50 OnClickListener {
Michael Kolb21ce4d22010-09-15 14:55:05 -070051
Narayan Kamath5119edd2011-02-23 15:49:17 +000052 public static final int TYPE_BOOKMARK = 0;
53 public static final int TYPE_HISTORY = 1;
54 public static final int TYPE_SUGGEST_URL = 2;
55 public static final int TYPE_SEARCH = 3;
56 public static final int TYPE_SUGGEST = 4;
Michael Kolb21ce4d22010-09-15 14:55:05 -070057
John Reck5e8466f2011-07-28 17:48:58 -070058 private static final String[] COMBINED_PROJECTION = {
59 OmniboxSuggestions._ID,
60 OmniboxSuggestions.TITLE,
61 OmniboxSuggestions.URL,
62 OmniboxSuggestions.IS_BOOKMARK
63 };
Michael Kolb21ce4d22010-09-15 14:55:05 -070064
Michael Kolb21ce4d22010-09-15 14:55:05 -070065 private static final String COMBINED_SELECTION =
66 "(url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ? OR title LIKE ?)";
67
Narayan Kamath5119edd2011-02-23 15:49:17 +000068 final Context mContext;
69 final Filter mFilter;
John Reck35defff2010-11-11 14:06:45 -080070 SuggestionResults mMixedResults;
71 List<SuggestItem> mSuggestResults, mFilterResults;
Michael Kolb21ce4d22010-09-15 14:55:05 -070072 List<CursorSource> mSources;
73 boolean mLandscapeMode;
Narayan Kamath5119edd2011-02-23 15:49:17 +000074 final CompletionListener mListener;
75 final int mLinesPortrait;
76 final int mLinesLandscape;
77 final Object mResultsLock = new Object();
John Reck117f07d2011-01-24 09:39:03 -080078 boolean mIncognitoMode;
John Reck35e9dd62011-04-25 09:01:54 -070079 BrowserSettings mSettings;
Michael Kolb21ce4d22010-09-15 14:55:05 -070080
81 interface CompletionListener {
82
83 public void onSearch(String txt);
84
Michael Kolbbd2dd642011-01-13 13:01:30 -080085 public void onSelect(String txt, int type, String extraData);
Michael Kolb21ce4d22010-09-15 14:55:05 -070086
87 }
88
89 public SuggestionsAdapter(Context ctx, CompletionListener listener) {
90 mContext = ctx;
John Reck35e9dd62011-04-25 09:01:54 -070091 mSettings = BrowserSettings.getInstance();
Michael Kolb21ce4d22010-09-15 14:55:05 -070092 mListener = listener;
93 mLinesPortrait = mContext.getResources().
94 getInteger(R.integer.max_suggest_lines_portrait);
95 mLinesLandscape = mContext.getResources().
96 getInteger(R.integer.max_suggest_lines_landscape);
Narayan Kamath5119edd2011-02-23 15:49:17 +000097
Michael Kolb21ce4d22010-09-15 14:55:05 -070098 mFilter = new SuggestFilter();
Michael Kolb21ce4d22010-09-15 14:55:05 -070099 addSource(new CombinedCursor());
100 }
101
102 public void setLandscapeMode(boolean mode) {
103 mLandscapeMode = mode;
John Reck35defff2010-11-11 14:06:45 -0800104 notifyDataSetChanged();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700105 }
106
Michael Kolb21ce4d22010-09-15 14:55:05 -0700107 public void addSource(CursorSource c) {
108 if (mSources == null) {
109 mSources = new ArrayList<CursorSource>(5);
110 }
111 mSources.add(c);
112 }
113
114 @Override
115 public void onClick(View v) {
John Reckad373302010-12-17 15:28:13 -0800116 SuggestItem item = (SuggestItem) ((View) v.getParent()).getTag();
Narayan Kamath5119edd2011-02-23 15:49:17 +0000117
Michael Kolb21ce4d22010-09-15 14:55:05 -0700118 if (R.id.icon2 == v.getId()) {
119 // replace input field text with suggestion text
Narayan Kamath5119edd2011-02-23 15:49:17 +0000120 mListener.onSearch(getSuggestionUrl(item));
Michael Kolb21ce4d22010-09-15 14:55:05 -0700121 } else {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000122 mListener.onSelect(getSuggestionUrl(item), item.type, item.extra);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700123 }
124 }
125
126 @Override
127 public Filter getFilter() {
128 return mFilter;
129 }
130
131 @Override
132 public int getCount() {
John Reck35defff2010-11-11 14:06:45 -0800133 return (mMixedResults == null) ? 0 : mMixedResults.getLineCount();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700134 }
135
136 @Override
137 public SuggestItem getItem(int position) {
John Reck35defff2010-11-11 14:06:45 -0800138 if (mMixedResults == null) {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700139 return null;
140 }
John Reckad373302010-12-17 15:28:13 -0800141 return mMixedResults.items.get(position);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700142 }
143
144 @Override
145 public long getItemId(int position) {
John Reck1605bef2011-01-10 18:11:18 -0800146 return position;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700147 }
148
149 @Override
150 public View getView(int position, View convertView, ViewGroup parent) {
151 final LayoutInflater inflater = LayoutInflater.from(mContext);
John Reck35defff2010-11-11 14:06:45 -0800152 View view = convertView;
153 if (view == null) {
John Reckad373302010-12-17 15:28:13 -0800154 view = inflater.inflate(R.layout.suggestion_item, parent, false);
John Reck35defff2010-11-11 14:06:45 -0800155 }
John Reckad373302010-12-17 15:28:13 -0800156 bindView(view, getItem(position));
157 return view;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700158 }
159
160 private void bindView(View view, SuggestItem item) {
161 // store item for click handling
162 view.setTag(item);
163 TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
164 TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
165 ImageView ic1 = (ImageView) view.findViewById(R.id.icon1);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700166 View ic2 = view.findViewById(R.id.icon2);
Michael Kolb7b20ddd2010-10-14 15:03:28 -0700167 View div = view.findViewById(R.id.divider);
Narayan Kamath5119edd2011-02-23 15:49:17 +0000168 tv1.setText(Html.fromHtml(item.title));
John Reckad373302010-12-17 15:28:13 -0800169 if (TextUtils.isEmpty(item.url)) {
170 tv2.setVisibility(View.GONE);
John Reck6a9afa92011-07-29 10:18:41 -0700171 tv1.setMaxLines(2);
John Reckad373302010-12-17 15:28:13 -0800172 } else {
173 tv2.setVisibility(View.VISIBLE);
174 tv2.setText(item.url);
John Reck6a9afa92011-07-29 10:18:41 -0700175 tv1.setMaxLines(1);
John Reckad373302010-12-17 15:28:13 -0800176 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700177 int id = -1;
178 switch (item.type) {
179 case TYPE_SUGGEST:
180 case TYPE_SEARCH:
Enrico Ros1f5a0952014-11-18 20:15:48 -0800181 id = R.drawable.ic_suggest_search_normal;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700182 break;
183 case TYPE_BOOKMARK:
Enrico Ros1f5a0952014-11-18 20:15:48 -0800184 id = R.drawable.ic_suggest_bookmark_normal;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700185 break;
186 case TYPE_HISTORY:
Enrico Ros1f5a0952014-11-18 20:15:48 -0800187 id = R.drawable.ic_suggest_history_normal;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700188 break;
189 case TYPE_SUGGEST_URL:
Enrico Ros1f5a0952014-11-18 20:15:48 -0800190 id = R.drawable.ic_suggest_browser_normal;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700191 break;
192 default:
193 id = -1;
194 }
195 if (id != -1) {
196 ic1.setImageDrawable(mContext.getResources().getDrawable(id));
197 }
Michael Kolbbd2dd642011-01-13 13:01:30 -0800198 ic2.setVisibility(((TYPE_SUGGEST == item.type)
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700199 || (TYPE_SEARCH == item.type))
Michael Kolb21ce4d22010-09-15 14:55:05 -0700200 ? View.VISIBLE : View.GONE);
Michael Kolb7b20ddd2010-10-14 15:03:28 -0700201 div.setVisibility(ic2.getVisibility());
Michael Kolb21ce4d22010-09-15 14:55:05 -0700202 ic2.setOnClickListener(this);
John Reckad373302010-12-17 15:28:13 -0800203 view.findViewById(R.id.suggestion).setOnClickListener(this);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700204 }
205
John Reck35defff2010-11-11 14:06:45 -0800206 class SlowFilterTask extends AsyncTask<CharSequence, Void, List<SuggestItem>> {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700207
John Reck35defff2010-11-11 14:06:45 -0800208 @Override
209 protected List<SuggestItem> doInBackground(CharSequence... params) {
210 SuggestCursor cursor = new SuggestCursor();
211 cursor.runQuery(params[0]);
212 List<SuggestItem> results = new ArrayList<SuggestItem>();
213 int count = cursor.getCount();
214 for (int i = 0; i < count; i++) {
Tarun Nainanic0cada02015-02-06 17:42:58 -0800215 SuggestItem item = cursor.getItem();
216 if(item != null)
217 results.add(item);
John Reck35defff2010-11-11 14:06:45 -0800218 cursor.moveToNext();
219 }
220 cursor.close();
221 return results;
222 }
223
224 @Override
225 protected void onPostExecute(List<SuggestItem> items) {
226 mSuggestResults = items;
227 mMixedResults = buildSuggestionResults();
228 notifyDataSetChanged();
John Reck35defff2010-11-11 14:06:45 -0800229 }
230 }
231
232 SuggestionResults buildSuggestionResults() {
233 SuggestionResults mixed = new SuggestionResults();
234 List<SuggestItem> filter, suggest;
235 synchronized (mResultsLock) {
236 filter = mFilterResults;
237 suggest = mSuggestResults;
238 }
239 if (filter != null) {
240 for (SuggestItem item : filter) {
241 mixed.addResult(item);
242 }
243 }
244 if (suggest != null) {
245 for (SuggestItem item : suggest) {
246 mixed.addResult(item);
247 }
248 }
249 return mixed;
250 }
251
252 class SuggestFilter extends Filter {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700253
254 @Override
255 public CharSequence convertResultToString(Object item) {
256 if (item == null) {
257 return "";
258 }
259 SuggestItem sitem = (SuggestItem) item;
260 if (sitem.title != null) {
261 return sitem.title;
262 } else {
263 return sitem.url;
264 }
265 }
266
John Reck35defff2010-11-11 14:06:45 -0800267 void startSuggestionsAsync(final CharSequence constraint) {
John Reck117f07d2011-01-24 09:39:03 -0800268 if (!mIncognitoMode) {
269 new SlowFilterTask().execute(constraint);
270 }
John Reck35defff2010-11-11 14:06:45 -0800271 }
272
Narayan Kamath5119edd2011-02-23 15:49:17 +0000273 private boolean shouldProcessEmptyQuery() {
John Reck35e9dd62011-04-25 09:01:54 -0700274 final SearchEngine searchEngine = mSettings.getSearchEngine();
Narayan Kamath5119edd2011-02-23 15:49:17 +0000275 return searchEngine.wantsEmptyQuery();
276 }
277
Michael Kolb21ce4d22010-09-15 14:55:05 -0700278 @Override
279 protected FilterResults performFiltering(CharSequence constraint) {
280 FilterResults res = new FilterResults();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700281 if (TextUtils.isEmpty(constraint) && !shouldProcessEmptyQuery()) {
282 res.count = 0;
283 res.values = null;
284 return res;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700285 }
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700286 startSuggestionsAsync(constraint);
287 List<SuggestItem> filterResults = new ArrayList<SuggestItem>();
288 if (constraint != null) {
289 for (CursorSource sc : mSources) {
290 sc.runQuery(constraint);
291 }
292 mixResults(filterResults);
293 }
294 synchronized (mResultsLock) {
295 mFilterResults = filterResults;
296 }
297 SuggestionResults mixed = buildSuggestionResults();
298 res.count = mixed.getLineCount();
299 res.values = mixed;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700300 return res;
301 }
302
John Reck35defff2010-11-11 14:06:45 -0800303 void mixResults(List<SuggestItem> results) {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000304 int maxLines = getMaxLines();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700305 for (int i = 0; i < mSources.size(); i++) {
306 CursorSource s = mSources.get(i);
John Reck35defff2010-11-11 14:06:45 -0800307 int n = Math.min(s.getCount(), maxLines);
308 maxLines -= n;
Michael Kolb0506f2d2010-10-14 16:20:16 -0700309 boolean more = false;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700310 for (int j = 0; j < n; j++) {
Tarun Nainanic0cada02015-02-06 17:42:58 -0800311 SuggestItem item = s.getItem();
312 if(item != null)
313 results.add(item);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700314 more = s.moveToNext();
315 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700316 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700317 }
318
319 @Override
320 protected void publishResults(CharSequence constraint, FilterResults fresults) {
Michael Kolbcfa3af52010-12-14 10:36:11 -0800321 if (fresults.values instanceof SuggestionResults) {
322 mMixedResults = (SuggestionResults) fresults.values;
John Recka005cd72011-02-01 11:46:53 -0800323 notifyDataSetChanged();
Michael Kolbcfa3af52010-12-14 10:36:11 -0800324 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700325 }
Narayan Kamath5119edd2011-02-23 15:49:17 +0000326 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700327
Narayan Kamath5119edd2011-02-23 15:49:17 +0000328 private int getMaxLines() {
329 int maxLines = mLandscapeMode ? mLinesLandscape : mLinesPortrait;
330 maxLines = (int) Math.ceil(maxLines / 2.0);
331 return maxLines;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700332 }
333
334 /**
335 * sorted list of results of a suggestion query
336 *
337 */
338 class SuggestionResults {
339
340 ArrayList<SuggestItem> items;
341 // count per type
342 int[] counts;
343
344 SuggestionResults() {
345 items = new ArrayList<SuggestItem>(24);
346 // n of types:
347 counts = new int[5];
348 }
349
350 int getTypeCount(int type) {
351 return counts[type];
352 }
353
354 void addResult(SuggestItem item) {
355 int ix = 0;
356 while ((ix < items.size()) && (item.type >= items.get(ix).type))
357 ix++;
358 items.add(ix, item);
359 counts[item.type]++;
360 }
361
362 int getLineCount() {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000363 return Math.min((mLandscapeMode ? mLinesLandscape : mLinesPortrait), items.size());
Michael Kolb21ce4d22010-09-15 14:55:05 -0700364 }
365
John Reck35defff2010-11-11 14:06:45 -0800366 @Override
Michael Kolb21ce4d22010-09-15 14:55:05 -0700367 public String toString() {
368 if (items == null) return null;
369 if (items.size() == 0) return "[]";
370 StringBuilder sb = new StringBuilder();
371 for (int i = 0; i < items.size(); i++) {
372 SuggestItem item = items.get(i);
373 sb.append(item.type + ": " + item.title);
374 if (i < items.size() - 1) {
375 sb.append(", ");
376 }
377 }
378 return sb.toString();
379 }
380 }
381
382 /**
383 * data object to hold suggestion values
384 */
Narayan Kamath80aad8d2011-02-23 12:01:13 +0000385 public class SuggestItem {
386 public String title;
387 public String url;
388 public int type;
389 public String extra;
Michael Kolb21ce4d22010-09-15 14:55:05 -0700390
391 public SuggestItem(String text, String u, int t) {
392 title = text;
393 url = u;
394 type = t;
395 }
Michael Kolbbd2dd642011-01-13 13:01:30 -0800396
Michael Kolb21ce4d22010-09-15 14:55:05 -0700397 }
398
399 abstract class CursorSource {
400
401 Cursor mCursor;
402
403 boolean moveToNext() {
404 return mCursor.moveToNext();
405 }
406
407 public abstract void runQuery(CharSequence constraint);
408
409 public abstract SuggestItem getItem();
410
411 public int getCount() {
412 return (mCursor != null) ? mCursor.getCount() : 0;
413 }
414
415 public void close() {
416 if (mCursor != null) {
417 mCursor.close();
418 }
419 }
420 }
421
422 /**
423 * combined bookmark & history source
424 */
425 class CombinedCursor extends CursorSource {
426
427 @Override
428 public SuggestItem getItem() {
429 if ((mCursor != null) && (!mCursor.isAfterLast())) {
430 String title = mCursor.getString(1);
431 String url = mCursor.getString(2);
432 boolean isBookmark = (mCursor.getInt(3) == 1);
433 return new SuggestItem(getTitle(title, url), getUrl(title, url),
434 isBookmark ? TYPE_BOOKMARK : TYPE_HISTORY);
435 }
436 return null;
437 }
438
439 @Override
440 public void runQuery(CharSequence constraint) {
441 // constraint != null
442 if (mCursor != null) {
443 mCursor.close();
444 }
445 String like = constraint + "%";
446 String[] args = null;
447 String selection = null;
448 if (like.startsWith("http") || like.startsWith("file")) {
449 args = new String[1];
450 args[0] = like;
451 selection = "url LIKE ?";
452 } else {
453 args = new String[5];
454 args[0] = "http://" + like;
455 args[1] = "http://www." + like;
456 args[2] = "https://" + like;
457 args[3] = "https://www." + like;
458 // To match against titles.
459 args[4] = like;
460 selection = COMBINED_SELECTION;
461 }
John Reck5e8466f2011-07-28 17:48:58 -0700462 Uri.Builder ub = OmniboxSuggestions.CONTENT_URI.buildUpon();
Michael Kolb0506f2d2010-10-14 16:20:16 -0700463 ub.appendQueryParameter(BrowserContract.PARAM_LIMIT,
John Reckad373302010-12-17 15:28:13 -0800464 Integer.toString(Math.max(mLinesLandscape, mLinesPortrait)));
Michael Kolb21ce4d22010-09-15 14:55:05 -0700465 mCursor =
Michael Kolb0506f2d2010-10-14 16:20:16 -0700466 mContext.getContentResolver().query(ub.build(), COMBINED_PROJECTION,
John Reck5e8466f2011-07-28 17:48:58 -0700467 selection, (constraint != null) ? args : null, null);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700468 if (mCursor != null) {
469 mCursor.moveToFirst();
470 }
471 }
472
473 /**
474 * Provides the title (text line 1) for a browser suggestion, which should be the
475 * webpage title. If the webpage title is empty, returns the stripped url instead.
476 *
477 * @return the title string to use
478 */
479 private String getTitle(String title, String url) {
480 if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
John Reckfb3017f2010-10-26 19:01:24 -0700481 title = UrlUtils.stripUrl(url);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700482 }
483 return title;
484 }
485
486 /**
487 * Provides the subtitle (text line 2) for a browser suggestion, which should be the
488 * webpage url. If the webpage title is empty, then the url should go in the title
489 * instead, and the subtitle should be empty, so this would return null.
490 *
491 * @return the subtitle string to use, or null if none
492 */
493 private String getUrl(String title, String url) {
John Reck7d132b12010-10-26 15:10:21 -0700494 if (TextUtils.isEmpty(title)
495 || TextUtils.getTrimmedLength(title) == 0
496 || title.equals(url)) {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700497 return null;
498 } else {
John Reckfb3017f2010-10-26 19:01:24 -0700499 return UrlUtils.stripUrl(url);
Michael Kolb21ce4d22010-09-15 14:55:05 -0700500 }
501 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700502 }
503
Michael Kolb21ce4d22010-09-15 14:55:05 -0700504 class SuggestCursor extends CursorSource {
505
506 @Override
507 public SuggestItem getItem() {
508 if (mCursor != null) {
Axesh R. Ajmera2a8ad1f2015-01-14 13:28:41 -0800509
510 String[] colIndexList = {
511 SearchManager.SUGGEST_COLUMN_TEXT_1,
512 SearchManager.SUGGEST_COLUMN_TEXT_2,
513 SearchManager.SUGGEST_COLUMN_TEXT_2_URL,
514 SearchManager.SUGGEST_COLUMN_INTENT_DATA,
515 SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA
516 };
517
518 for (String currentColIndex: colIndexList) {
519 /*
520 * As defined in documentation getColumnIndex can return
521 * a value of -1,
522 * if the column does not exists, so we need to return back
523 */
524 if (mCursor.getColumnIndex(currentColIndex) == -1) {
525 return null;
526 }
527 }
528
Michael Kolb21ce4d22010-09-15 14:55:05 -0700529 String title = mCursor.getString(
530 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
531 String text2 = mCursor.getString(
532 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
533 String url = mCursor.getString(
534 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL));
535 String uri = mCursor.getString(
536 mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA));
Axesh R. Ajmera2a8ad1f2015-01-14 13:28:41 -0800537
Michael Kolb21ce4d22010-09-15 14:55:05 -0700538 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;
Axesh R. Ajmera2a8ad1f2015-01-14 13:28:41 -0800543
Michael Kolb21ce4d22010-09-15 14:55:05 -0700544 }
545 return null;
546 }
547
548 @Override
549 public void runQuery(CharSequence constraint) {
550 if (mCursor != null) {
551 mCursor.close();
552 }
John Reck35e9dd62011-04-25 09:01:54 -0700553 SearchEngine searchEngine = mSettings.getSearchEngine();
Michael Kolb21ce4d22010-09-15 14:55:05 -0700554 if (!TextUtils.isEmpty(constraint)) {
Michael Kolb21ce4d22010-09-15 14:55:05 -0700555 if (searchEngine != null && searchEngine.supportsSuggestions()) {
556 mCursor = searchEngine.getSuggestions(mContext, constraint.toString());
557 if (mCursor != null) {
558 mCursor.moveToFirst();
559 }
560 }
561 } else {
Narayan Kamath5119edd2011-02-23 15:49:17 +0000562 if (searchEngine.wantsEmptyQuery()) {
563 mCursor = searchEngine.getSuggestions(mContext, "");
564 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700565 mCursor = null;
566 }
567 }
568
569 }
570
John Reck35defff2010-11-11 14:06:45 -0800571 public void clearCache() {
572 mFilterResults = null;
573 mSuggestResults = null;
Narayan Kamath5119edd2011-02-23 15:49:17 +0000574 notifyDataSetInvalidated();
John Reck35defff2010-11-11 14:06:45 -0800575 }
576
John Reck117f07d2011-01-24 09:39:03 -0800577 public void setIncognitoMode(boolean incognito) {
578 mIncognitoMode = incognito;
579 clearCache();
580 }
Narayan Kamath5119edd2011-02-23 15:49:17 +0000581
582 static String getSuggestionTitle(SuggestItem item) {
583 // There must be a better way to strip HTML from things.
584 // This method is used in multiple places. It is also more
585 // expensive than a standard html escaper.
586 return (item.title != null) ? Html.fromHtml(item.title).toString() : null;
587 }
588
589 static String getSuggestionUrl(SuggestItem item) {
590 final String title = SuggestionsAdapter.getSuggestionTitle(item);
591
592 if (TextUtils.isEmpty(item.url)) {
593 return title;
594 }
595
596 return item.url;
597 }
Michael Kolb21ce4d22010-09-15 14:55:05 -0700598}