1d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert/* 2d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Copyright (C) 2010 The Android Open Source Project 3d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * 4d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 5d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * you may not use this file except in compliance with the License. 6d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * You may obtain a copy of the License at 7d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * 8d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 9d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * 10d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Unless required by applicable law or agreed to in writing, software 11d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 12d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * See the License for the specific language governing permissions and 14d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * limitations under the License. 15d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert */ 16d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertpackage com.android.browser.search; 17d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 18d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport com.android.browser.R; 19d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 20d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.apache.http.HttpResponse; 21d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.apache.http.client.HttpClient; 22d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.apache.http.client.methods.HttpGet; 23d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.apache.http.params.HttpParams; 24d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.apache.http.util.EntityUtils; 25d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.json.JSONArray; 26d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport org.json.JSONException; 27d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 28d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.app.SearchManager; 29d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.Context; 30d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.Intent; 31d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.database.AbstractCursor; 32d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.database.Cursor; 33d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.net.ConnectivityManager; 34d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.net.NetworkInfo; 35d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.net.Uri; 36d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.net.http.AndroidHttpClient; 37d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.os.Bundle; 38d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.provider.Browser; 39d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.text.TextUtils; 40d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.util.Log; 41d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 42d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport java.io.IOException; 43d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 44d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert/** 45d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Provides search suggestions, if any, for a given web search provider. 46d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert */ 47d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertpublic class OpenSearchSearchEngine implements SearchEngine { 48d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 49d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final String TAG = "OpenSearchSearchEngine"; 50d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 51d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final String USER_AGENT = "Android/1.0"; 52d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final int HTTP_TIMEOUT_MS = 1000; 53d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 54d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // TODO: this should be defined somewhere 55d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final String HTTP_TIMEOUT = "http.connection-manager.timeout"; 56d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 57d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // Indices of the columns in the below arrays. 58d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final int COLUMN_INDEX_ID = 0; 59d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final int COLUMN_INDEX_QUERY = 1; 60d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final int COLUMN_INDEX_ICON = 2; 61d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final int COLUMN_INDEX_TEXT_1 = 3; 62d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final int COLUMN_INDEX_TEXT_2 = 4; 63d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 64d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // The suggestion columns used. If you are adding a new entry to these arrays make sure to 65d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // update the list of indices declared above. 66d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final String[] COLUMNS = new String[] { 67d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert "_id", 68d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_QUERY, 69d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_ICON_1, 70d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_TEXT_1, 71d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_TEXT_2, 72d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert }; 73d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 74d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static final String[] COLUMNS_WITHOUT_DESCRIPTION = new String[] { 75d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert "_id", 76d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_QUERY, 77d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_ICON_1, 78d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert SearchManager.SUGGEST_COLUMN_TEXT_1, 79d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert }; 80d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 81d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private final SearchEngineInfo mSearchEngineInfo; 82d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 83d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private final AndroidHttpClient mHttpClient; 84d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 85d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public OpenSearchSearchEngine(Context context, SearchEngineInfo searchEngineInfo) { 86d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert mSearchEngineInfo = searchEngineInfo; 87d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert mHttpClient = AndroidHttpClient.newInstance(USER_AGENT); 88d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert HttpParams params = mHttpClient.getParams(); 89d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert params.setLongParameter(HTTP_TIMEOUT, HTTP_TIMEOUT_MS); 90d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 91d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 92d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public String getName() { 93d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mSearchEngineInfo.getName(); 94d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 95d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 96d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public CharSequence getLabel() { 97d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mSearchEngineInfo.getLabel(); 98d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 99d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 100d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public void startSearch(Context context, String query, Bundle appData, String extraData) { 101d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert String uri = mSearchEngineInfo.getSearchUriForQuery(query); 102d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (uri == null) { 103d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.e(TAG, "Unable to get search URI for " + mSearchEngineInfo); 104d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } else { 105d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); 106d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // Make sure the intent goes to the Browser itself 107d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert intent.setPackage(context.getPackageName()); 108d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert intent.addCategory(Intent.CATEGORY_DEFAULT); 109d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert intent.putExtra(SearchManager.QUERY, query); 110d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (appData != null) { 111d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert intent.putExtra(SearchManager.APP_DATA, appData); 112d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 113d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (extraData != null) { 114d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData); 115d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 116d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); 117d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert context.startActivity(intent); 118d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 119d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 120d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 121d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert /** 122d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Queries for a given search term and returns a cursor containing 123d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * suggestions ordered by best match. 124d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert */ 125d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public Cursor getSuggestions(Context context, String query) { 126d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (TextUtils.isEmpty(query)) { 127d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 128d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 129d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (!isNetworkConnected(context)) { 130d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.i(TAG, "Not connected to network."); 131d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 132d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 133d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 134d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert String suggestUri = mSearchEngineInfo.getSuggestUriForQuery(query); 135d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (TextUtils.isEmpty(suggestUri)) { 136d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // No suggest URI available for this engine 137d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 138d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 139d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 140d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert try { 141d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert String content = readUrl(suggestUri); 142d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (content == null) return null; 143d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert /* The data format is a JSON array with items being regular strings or JSON arrays 144d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * themselves. We are interested in the second and third elements, both of which 145d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * should be JSON arrays. The second element/array contains the suggestions and the 146d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * third element contains the descriptions. Some search engines don't support 147d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * suggestion descriptions so the third element is optional. 148d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert */ 149d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert JSONArray results = new JSONArray(content); 150d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert JSONArray suggestions = results.getJSONArray(1); 151d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert JSONArray descriptions = null; 152d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (results.length() > 2) { 153d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert descriptions = results.getJSONArray(2); 154d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // Some search engines given an empty array "[]" for descriptions instead of 155d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert // not including it in the response. 156d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (descriptions.length() == 0) { 157d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert descriptions = null; 158d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 159d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 160d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return new SuggestionsCursor(suggestions, descriptions); 161d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } catch (JSONException e) { 162d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.w(TAG, "Error", e); 163d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 164d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 165d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 166d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 167d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert /** 168d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Executes a GET request and returns the response content. 169d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * 170d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * @param url Request URI. 171d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * @return The response content. This is the empty string if the response 172d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * contained no content. 173d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert */ 174d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public String readUrl(String url) { 175d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert try { 176d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert HttpGet method = new HttpGet(url); 177d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert HttpResponse response = mHttpClient.execute(method); 178d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (response.getStatusLine().getStatusCode() == 200) { 179d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return EntityUtils.toString(response.getEntity()); 180d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } else { 181d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.i(TAG, "Suggestion request failed"); 182d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 183d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 184d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } catch (IOException e) { 185d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.w(TAG, "Error", e); 186d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 187d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 188d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 189d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 190d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public boolean supportsSuggestions() { 191d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mSearchEngineInfo.supportsSuggestions(); 192d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 193d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 194d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public void close() { 195d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert mHttpClient.close(); 196d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 197430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III 198d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private boolean isNetworkConnected(Context context) { 199d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert NetworkInfo networkInfo = getActiveNetworkInfo(context); 200d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return networkInfo != null && networkInfo.isConnected(); 201d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 202d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 203d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private NetworkInfo getActiveNetworkInfo(Context context) { 204d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert ConnectivityManager connectivity = 205d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 206d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (connectivity == null) { 207d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 208d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 209d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return connectivity.getActiveNetworkInfo(); 210d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 211d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 212d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private static class SuggestionsCursor extends AbstractCursor { 213d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 214d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private final JSONArray mSuggestions; 215d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 216d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert private final JSONArray mDescriptions; 217d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 218d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public SuggestionsCursor(JSONArray suggestions, JSONArray descriptions) { 219d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert mSuggestions = suggestions; 220d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert mDescriptions = descriptions; 221d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 222d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 223d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 224d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public int getCount() { 225d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mSuggestions.length(); 226d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 227d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 228d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 229d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public String[] getColumnNames() { 230d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return (mDescriptions != null ? COLUMNS : COLUMNS_WITHOUT_DESCRIPTION); 231d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 232d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 233d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 234d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public String getString(int column) { 235d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (mPos != -1) { 236d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if ((column == COLUMN_INDEX_QUERY) || (column == COLUMN_INDEX_TEXT_1)) { 237d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert try { 238d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mSuggestions.getString(mPos); 239d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } catch (JSONException e) { 240d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.w(TAG, "Error", e); 241d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 242d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } else if (column == COLUMN_INDEX_TEXT_2) { 243d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert try { 244d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mDescriptions.getString(mPos); 245d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } catch (JSONException e) { 246d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert Log.w(TAG, "Error", e); 247d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 248d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } else if (column == COLUMN_INDEX_ICON) { 249d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return String.valueOf(R.drawable.magnifying_glass); 250d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 251d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 252d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return null; 253d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 254d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 255d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 256d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public double getDouble(int column) { 257d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert throw new UnsupportedOperationException(); 258d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 259d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 260d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 261d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public float getFloat(int column) { 262d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert throw new UnsupportedOperationException(); 263d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 264d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 265d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 266d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public int getInt(int column) { 267d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert throw new UnsupportedOperationException(); 268d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 269d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 270d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 271d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public long getLong(int column) { 272d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert if (column == COLUMN_INDEX_ID) { 273d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return mPos; // use row# as the _Id 274d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 275d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert throw new UnsupportedOperationException(); 276d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 277d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 278d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 279d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public short getShort(int column) { 280d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert throw new UnsupportedOperationException(); 281d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 282d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 283d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 284d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public boolean isNull(int column) { 285d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert throw new UnsupportedOperationException(); 286d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 287d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 288d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 289d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert @Override 290d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert public String toString() { 291d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert return "OpenSearchSearchEngine{" + mSearchEngineInfo + "}"; 292d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert } 293d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert 2945119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath @Override 2955119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath public boolean wantsEmptyQuery() { 2965119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath return false; 2975119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath } 2985119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath 299d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert} 300