| Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/DownloadJobService.java |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/DownloadJobService.java |
| @@ -0,0 +1,199 @@ |
| +/* |
| + * This file is part of Adblock Plus <https://adblockplus.org/>, |
| + * Copyright (C) 2006-present eyeo GmbH |
| + * |
| + * Adblock Plus is free software: you can redistribute it and/or modify |
| + * it under the terms of the GNU General Public License version 3 as |
| + * published by the Free Software Foundation. |
| + * |
| + * Adblock Plus is distributed in the hope that it will be useful, |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + * GNU General Public License for more details. |
| + * |
| + * You should have received a copy of the GNU General Public License |
| + * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| + */ |
| + |
| +package org.adblockplus.sbrowser.contentblocker.engine; |
| + |
| +import java.io.BufferedReader; |
| +import java.io.IOException; |
| +import java.io.InputStreamReader; |
| +import java.net.MalformedURLException; |
| +import java.net.URL; |
| +import java.nio.charset.StandardCharsets; |
| +import java.util.HashMap; |
| +import java.util.Map; |
| + |
| +import android.app.job.JobParameters; |
| +import android.app.job.JobService; |
| +import android.content.Intent; |
| +import android.os.AsyncTask; |
| +import android.os.PersistableBundle; |
| +import android.util.Log; |
| + |
| +import javax.net.ssl.HttpsURLConnection; |
| + |
| +/** |
| + * JobService that handles download jobs |
| + */ |
| +public class DownloadJobService extends JobService implements EngineManager.OnEngineCreatedCallback |
| +{ |
| + private static final String TAG = DownloadJobService.class.getSimpleName(); |
| + private DownloadJobAsyncTask downloadJobAsyncTask = null; |
| + private Engine engine = null; |
| + |
| + @Override |
| + public void onCreate() |
| + { |
| + super.onCreate(); |
| + Log.i(TAG, "DownloadJobService created."); |
| + EngineManager.getInstance().retrieveEngine(this, this); |
| + } |
| + |
| + @Override |
| + public int onStartCommand(final Intent intent, final int flags, final int startId) |
| + { |
| + return START_NOT_STICKY; |
| + } |
| + |
| + @Override |
| + public boolean onStartJob(final JobParameters params) |
| + { |
| + Log.i(TAG, "Job with id " + params.getJobId() + " started."); |
| + this.downloadJobAsyncTask = new DownloadJobAsyncTask() |
| + { |
| + @Override |
| + protected void onPostExecute(final DownloadJob job) |
| + { |
| + Log.i(DownloadJobService.TAG, "Job with id " + params.getJobId() + " finished."); |
| + jobFinished(params, false); |
| + if (engine != null && job != null) |
| + { |
| + engine.downloadFinished(job.id, job.responseCode, job.responseText, job.headers); |
| + } |
| + } |
| + }; |
| + try |
| + { |
| + this.downloadJobAsyncTask.execute(createDownloadJobFromExtras(params.getExtras())); |
| + } |
| + catch (final MalformedURLException e) |
| + { |
| + Log.e(TAG, "Malformed URL, cannot create download.", e); |
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + @Override |
| + public boolean onStopJob(JobParameters params) |
| + { |
| + if (downloadJobAsyncTask != null) |
| + { |
| + downloadJobAsyncTask.cancel(true); |
| + } |
| + return true; |
| + } |
| + |
| + @Override |
| + public void onDestroy() |
| + { |
| + EngineManager.getInstance().removeOnEngineCreatedCallback(this); |
| + Log.i(TAG, "DownloadJobService destroyed."); |
| + super.onDestroy(); |
| + } |
| + |
| + private DownloadJob createDownloadJobFromExtras(final PersistableBundle extras) throws MalformedURLException |
| + { |
| + return new DownloadJob( |
| + new URL(extras.getString(Notification.KEY_EXTRA_URL)), |
| + extras.getString(Notification.KEY_EXTRA_ID), |
| + null); |
| + } |
| + |
| + @Override |
| + public void onEngineCreated(final Engine engine) |
| + { |
| + this.engine = engine; |
| + } |
| + |
| + private static class DownloadJobAsyncTask extends AsyncTask<DownloadJob, Void, DownloadJob> |
| + { |
| + public static final String TAG = DownloadJobAsyncTask.class.getSimpleName(); |
| + |
| + @Override |
| + protected DownloadJob doInBackground(final DownloadJob... downloadJob) |
| + { |
| + final DownloadJob job = downloadJob[0]; |
| + try |
| + { |
| + return download(job); |
| + } |
| + catch (Exception e) |
| + { |
| + Log.e(TAG, "Error at download: ", e); |
| + return null; |
| + } |
| + } |
| + |
| + private DownloadJob download(final DownloadJob job) throws IOException |
| + { |
| + final HttpsURLConnection connection = (HttpsURLConnection) job.url.openConnection(); |
| + connection.setRequestMethod("GET"); |
| + for (final Map.Entry<String, String> e : job.headers.entrySet()) |
| + { |
| + connection.addRequestProperty(e.getKey(), e.getValue()); |
| + } |
| + connection.connect(); |
| + job.responseCode = connection.getResponseCode(); |
| + job.responseHeaders.clear(); |
| + job.responseText = null; |
| + |
| + for (int i = 1; ; i++) |
| + { |
| + final String key = connection.getHeaderFieldKey(i); |
| + if (key == null) |
| + { |
| + break; |
| + } |
| + final String value = connection.getHeaderField(i); |
| + job.responseHeaders.put(key.toLowerCase(), value); |
| + } |
| + |
| + final StringBuilder sb = new StringBuilder(); |
| + try (final BufferedReader r = new BufferedReader(new InputStreamReader( |
| + connection.getInputStream(), StandardCharsets.UTF_8))) |
| + { |
| + for (int ch = r.read(); ch != -1; ch = r.read()) |
| + { |
| + sb.append((char) ch); |
| + } |
| + job.responseText = sb.toString(); |
| + } |
| + return job; |
| + } |
| + } |
| + |
| + private static class DownloadJob |
| + { |
| + private final URL url; |
| + private final String id; |
| + private final HashMap<String, String> headers = new HashMap<>(); |
| + |
| + private int responseCode; |
| + private final HashMap<String, String> responseHeaders = new HashMap<>(); |
| + private String responseText; |
| + |
| + DownloadJob(final URL url, final String id, final Map<String, String> headers) |
| + { |
| + this.url = url; |
| + this.id = id; |
| + if (headers != null) |
| + { |
| + this.headers.putAll(headers); |
| + } |
| + } |
| + } |
| +} |