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