Lightning browser with I2P configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

169 lines
5.8 KiB

package acr.browser.lightning.search;
import android.app.Application;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import javax.net.ssl.HttpsURLConnection;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.Utils;
abstract class BaseSuggestionsTask {
private static final String TAG = BaseSuggestionsTask.class.getSimpleName();
private static final long INTERVAL_DAY = TimeUnit.DAYS.toMillis(1);
private static final String DEFAULT_LANGUAGE = "en";
@Nullable private static String sLanguage;
@NonNull private final SuggestionsResult mResultCallback;
@NonNull private final Application mApplication;
@NonNull private String mQuery;
protected abstract String getQueryUrl(@NonNull String query, @NonNull String language);
protected abstract void parseResults(FileInputStream inputStream, List<HistoryItem> results) throws Exception;
protected abstract String getEncoding();
BaseSuggestionsTask(@NonNull String query,
@NonNull Application application,
@NonNull SuggestionsResult callback) {
mQuery = query;
mResultCallback = callback;
mApplication = application;
}
@NonNull
private static synchronized String getLanguage() {
if (sLanguage == null) {
sLanguage = Locale.getDefault().getLanguage();
}
if (TextUtils.isEmpty(sLanguage)) {
sLanguage = DEFAULT_LANGUAGE;
}
return sLanguage;
}
void run() {
List<HistoryItem> filter = new ArrayList<>(5);
try {
mQuery = URLEncoder.encode(mQuery, getEncoding());
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unable to encode the URL", e);
}
File cache = downloadSuggestionsForQuery(mQuery, getLanguage(), mApplication);
if (!cache.exists()) {
post(filter);
return;
}
FileInputStream fileInput = null;
try {
fileInput = new FileInputStream(cache);
parseResults(fileInput, filter);
} catch (Exception e) {
post(filter);
Log.e(TAG, "Unable to parse results", e);
return;
} finally {
Utils.close(fileInput);
}
post(filter);
}
private void post(@NonNull List<HistoryItem> result) {
mResultCallback.resultReceived(result);
}
/**
* This method downloads the search suggestions for the specific query.
* NOTE: This is a blocking operation, do not run on the UI thread.
*
* @param query the query to get suggestions for
* @return the cache file containing the suggestions
*/
@NonNull
private File downloadSuggestionsForQuery(@NonNull String query, String language, @NonNull Application app) {
String queryUrl = getQueryUrl(query, language);
File cacheFile = new File(app.getCacheDir(), queryUrl.hashCode() + Suggestions.CACHE_FILE_TYPE);
if (System.currentTimeMillis() - INTERVAL_DAY < cacheFile.lastModified()) {
return cacheFile;
}
if (!isNetworkConnected(app)) {
return cacheFile;
}
InputStream in = null;
FileOutputStream fos = null;
try {
URL url = new URL(queryUrl);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setRequestProperty("Accept-Charset", getEncoding());
connection.connect();
if (connection.getResponseCode() >= HttpURLConnection.HTTP_MULT_CHOICE ||
connection.getResponseCode() < HttpURLConnection.HTTP_OK) {
Log.e(TAG, "Search API Responded with code: " + connection.getResponseCode());
connection.disconnect();
return cacheFile;
}
in = connection.getInputStream();
if (in != null) {
in = new GZIPInputStream(in);
//noinspection IOResourceOpenedButNotSafelyClosed
fos = new FileOutputStream(cacheFile);
int buffer;
while ((buffer = in.read()) != -1) {
fos.write(buffer);
}
fos.flush();
}
connection.disconnect();
cacheFile.setLastModified(System.currentTimeMillis());
} catch (Exception e) {
Log.w(TAG, "Problem getting search suggestions", e);
} finally {
Utils.close(in);
Utils.close(fos);
}
return cacheFile;
}
private static boolean isNetworkConnected(@NonNull Context context) {
NetworkInfo networkInfo = getActiveNetworkInfo(context);
return networkInfo != null && networkInfo.isConnected();
}
@Nullable
private static NetworkInfo getActiveNetworkInfo(@NonNull Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context
.getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
return null;
}
return connectivity.getActiveNetworkInfo();
}
}