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

     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 }

mercurial