mobile/android/base/home/SuggestClient.java

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.home;
michael@0 6
michael@0 7 import org.mozilla.gecko.GeckoAppShell;
michael@0 8 import org.mozilla.gecko.mozglue.RobocopTarget;
michael@0 9
michael@0 10 import org.json.JSONArray;
michael@0 11
michael@0 12 import android.content.Context;
michael@0 13 import android.net.ConnectivityManager;
michael@0 14 import android.net.NetworkInfo;
michael@0 15 import android.text.TextUtils;
michael@0 16 import android.util.Log;
michael@0 17
michael@0 18 import java.io.BufferedInputStream;
michael@0 19 import java.io.IOException;
michael@0 20 import java.io.InputStream;
michael@0 21 import java.net.HttpURLConnection;
michael@0 22 import java.net.URL;
michael@0 23 import java.net.URLEncoder;
michael@0 24 import java.util.ArrayList;
michael@0 25
michael@0 26 /**
michael@0 27 * Use network-based search suggestions.
michael@0 28 */
michael@0 29 public class SuggestClient {
michael@0 30 private static final String LOGTAG = "GeckoSuggestClient";
michael@0 31 private static final String USER_AGENT = GeckoAppShell.getGeckoInterface().getDefaultUAString();
michael@0 32
michael@0 33 private final Context mContext;
michael@0 34 private final int mTimeout;
michael@0 35
michael@0 36 // should contain the string "__searchTerms__", which is replaced with the query
michael@0 37 private final String mSuggestTemplate;
michael@0 38
michael@0 39 // the maximum number of suggestions to return
michael@0 40 private final int mMaxResults;
michael@0 41
michael@0 42 // used by robocop for testing
michael@0 43 private boolean mCheckNetwork;
michael@0 44
michael@0 45 // used to make suggestions appear instantly after opt-in
michael@0 46 private String mPrevQuery;
michael@0 47 private ArrayList<String> mPrevResults;
michael@0 48
michael@0 49 public SuggestClient(Context context, String suggestTemplate, int timeout, int maxResults) {
michael@0 50 mContext = context;
michael@0 51 mMaxResults = maxResults;
michael@0 52 mSuggestTemplate = suggestTemplate;
michael@0 53 mTimeout = timeout;
michael@0 54 mCheckNetwork = true;
michael@0 55 }
michael@0 56
michael@0 57 /**
michael@0 58 * This constructor is used exclusively by Robocop.
michael@0 59 */
michael@0 60 @RobocopTarget
michael@0 61 public SuggestClient(Context context, String suggestTemplate, int timeout) {
michael@0 62 this(context, suggestTemplate, timeout, Integer.MAX_VALUE);
michael@0 63 mCheckNetwork = false;
michael@0 64 }
michael@0 65
michael@0 66 /**
michael@0 67 * Queries for a given search term and returns an ArrayList of suggestions.
michael@0 68 */
michael@0 69 public ArrayList<String> query(String query) {
michael@0 70 if (query.equals(mPrevQuery))
michael@0 71 return mPrevResults;
michael@0 72
michael@0 73 ArrayList<String> suggestions = new ArrayList<String>();
michael@0 74 if (TextUtils.isEmpty(mSuggestTemplate) || TextUtils.isEmpty(query)) {
michael@0 75 return suggestions;
michael@0 76 }
michael@0 77
michael@0 78 if (!isNetworkConnected() && mCheckNetwork) {
michael@0 79 Log.i(LOGTAG, "Not connected to network");
michael@0 80 return suggestions;
michael@0 81 }
michael@0 82
michael@0 83 try {
michael@0 84 String encoded = URLEncoder.encode(query, "UTF-8");
michael@0 85 String suggestUri = mSuggestTemplate.replace("__searchTerms__", encoded);
michael@0 86
michael@0 87 URL url = new URL(suggestUri);
michael@0 88 String json = null;
michael@0 89 HttpURLConnection urlConnection = null;
michael@0 90 InputStream in = null;
michael@0 91 try {
michael@0 92 urlConnection = (HttpURLConnection) url.openConnection();
michael@0 93 urlConnection.setConnectTimeout(mTimeout);
michael@0 94 urlConnection.setRequestProperty("User-Agent", USER_AGENT);
michael@0 95 in = new BufferedInputStream(urlConnection.getInputStream());
michael@0 96 json = convertStreamToString(in);
michael@0 97 } finally {
michael@0 98 if (urlConnection != null)
michael@0 99 urlConnection.disconnect();
michael@0 100 if (in != null) {
michael@0 101 try {
michael@0 102 in.close();
michael@0 103 } catch (IOException e) {
michael@0 104 Log.e(LOGTAG, "error", e);
michael@0 105 }
michael@0 106 }
michael@0 107 }
michael@0 108
michael@0 109 if (json != null) {
michael@0 110 /*
michael@0 111 * Sample result:
michael@0 112 * ["foo",["food network","foothill college","foot locker",...]]
michael@0 113 */
michael@0 114 JSONArray results = new JSONArray(json);
michael@0 115 JSONArray jsonSuggestions = results.getJSONArray(1);
michael@0 116
michael@0 117 int added = 0;
michael@0 118 for (int i = 0; (i < jsonSuggestions.length()) && (added < mMaxResults); i++) {
michael@0 119 String suggestion = jsonSuggestions.getString(i);
michael@0 120 if (!suggestion.equalsIgnoreCase(query)) {
michael@0 121 suggestions.add(suggestion);
michael@0 122 added++;
michael@0 123 }
michael@0 124 }
michael@0 125 } else {
michael@0 126 Log.e(LOGTAG, "Suggestion query failed");
michael@0 127 }
michael@0 128 } catch (Exception e) {
michael@0 129 Log.e(LOGTAG, "Error", e);
michael@0 130 }
michael@0 131
michael@0 132 mPrevQuery = query;
michael@0 133 mPrevResults = suggestions;
michael@0 134 return suggestions;
michael@0 135 }
michael@0 136
michael@0 137 private boolean isNetworkConnected() {
michael@0 138 NetworkInfo networkInfo = getActiveNetworkInfo();
michael@0 139 return networkInfo != null && networkInfo.isConnected();
michael@0 140 }
michael@0 141
michael@0 142 private NetworkInfo getActiveNetworkInfo() {
michael@0 143 ConnectivityManager connectivity = (ConnectivityManager) mContext
michael@0 144 .getSystemService(Context.CONNECTIVITY_SERVICE);
michael@0 145 if (connectivity == null)
michael@0 146 return null;
michael@0 147 return connectivity.getActiveNetworkInfo();
michael@0 148 }
michael@0 149
michael@0 150 private String convertStreamToString(java.io.InputStream is) {
michael@0 151 try {
michael@0 152 return new java.util.Scanner(is).useDelimiter("\\A").next();
michael@0 153 } catch (java.util.NoSuchElementException e) {
michael@0 154 return "";
michael@0 155 }
michael@0 156 }
michael@0 157 }

mercurial