Index: adblockplussbrowser/AndroidManifest.xml
===================================================================
--- a/adblockplussbrowser/AndroidManifest.xml
+++ b/adblockplussbrowser/AndroidManifest.xml
@@ -31,11 +31,15 @@
+
+
Index: adblockplussbrowser/res/values/sysstrings.xml
===================================================================
--- a/adblockplussbrowser/res/values/sysstrings.xml
+++ b/adblockplussbrowser/res/values/sysstrings.xml
@@ -14,9 +14,13 @@
previous_version_code
whitelisted_websites
force_update_subscriptions
1
2
+
+ last_tried_notification_update_timestamp
+ last_notification_update_timestamp
+
\ No newline at end of file
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/MainPreferences.java
===================================================================
--- a/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/MainPreferences.java
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/MainPreferences.java
@@ -12,16 +12,17 @@
* 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 .
*/
package org.adblockplus.sbrowser.contentblocker;
+import org.adblockplus.sbrowser.contentblocker.engine.DownloadJobService;
import org.adblockplus.sbrowser.contentblocker.engine.Engine;
import org.adblockplus.sbrowser.contentblocker.engine.EngineManager;
import org.adblockplus.adblockplussbrowser.R;
import org.adblockplus.sbrowser.contentblocker.util.ConnectivityUtils;
import org.adblockplus.sbrowser.contentblocker.util.SharedPrefsUtils;
import android.app.AlertDialog;
import android.app.Fragment;
@@ -66,23 +67,25 @@ public class MainPreferences extends Pre
{
this.dialogTitleResId = R.string.initialization_title;
this.dialog = ProgressDialog.show(this,
this.getString(this.dialogTitleResId),
this.getString(R.string.initialization_message));
super.onStart();
SharedPrefsUtils.registerOnSharedPreferenceChangeListener(this, listener);
EngineManager.getInstance().retrieveEngine(this, this);
+ startService(new Intent(this, DownloadJobService.class));
}
@Override
protected void onStop()
{
super.onStop();
SharedPrefsUtils.unregisterOnSharedPreferenceChangeListener(this, listener);
+ stopService(new Intent(this, DownloadJobService.class));
this.dismissDialog();
}
@Override
protected void onDestroy()
{
EngineManager.getInstance().removeOnEngineCreatedCallback(this);
super.onDestroy();
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/MoreBlockingPreferenceCategory.java
===================================================================
--- a/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/MoreBlockingPreferenceCategory.java
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/MoreBlockingPreferenceCategory.java
@@ -26,16 +26,17 @@ import java.util.List;
import java.util.Map;
import org.adblockplus.sbrowser.contentblocker.engine.DefaultSubscriptionInfo;
import org.adblockplus.sbrowser.contentblocker.engine.Engine;
import org.adblockplus.sbrowser.contentblocker.engine.EngineManager;
import org.adblockplus.sbrowser.contentblocker.engine.SubscriptionInfo;
import org.adblockplus.adblockplussbrowser.R;
import org.adblockplus.sbrowser.contentblocker.preferences.MultilineCheckBoxPreference;
+import org.adblockplus.sbrowser.contentblocker.util.SubscriptionUtils;
import android.content.Context;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.Preference.OnPreferenceChangeListener;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -209,16 +210,21 @@ public class MoreBlockingPreferenceCateg
return moreBlockingPreferenceSubscriptions;
}
for (SubscriptionInfo sub : engine.getListedSubscriptions())
{
final DefaultSubscriptionInfo info = engine.getDefaultSubscriptionInfoForUrl(sub.getUrl());
Integer resInt = URL_TO_RES_ID_MAP.get(sub.getUrl());
+ if (SubscriptionUtils.isNotificationSubscription(sub.getId()))
+ {
+ continue;
+ }
+
if (sub.getType() == SubscriptionInfo.Type.CUSTOM)
{
moreBlockingPreferenceSubscriptions.add(sub);
continue;
}
if (info != null && !info.isComplete() && sub.isEnabled())
{
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 ,
+ * 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 .
+ */
+
+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
+ {
+ 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 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 headers = new HashMap<>();
+
+ private int responseCode;
+ private final HashMap responseHeaders = new HashMap<>();
+ private String responseText;
+
+ DownloadJob(final URL url, final String id, final Map headers)
+ {
+ this.url = url;
+ this.id = id;
+ if (headers != null)
+ {
+ this.headers.putAll(headers);
+ }
+ }
+ }
+}
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Engine.java
===================================================================
--- a/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Engine.java
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Engine.java
@@ -42,24 +42,28 @@ import java.util.concurrent.LinkedBlocki
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import org.adblockplus.adblockplussbrowser.R;
import org.adblockplus.sbrowser.contentblocker.util.ConnectivityUtils;
import org.adblockplus.sbrowser.contentblocker.util.SharedPrefsUtils;
import org.adblockplus.sbrowser.contentblocker.util.SubscriptionUtils;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
+import android.os.PersistableBundle;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.widget.Toast;
public final class Engine
{
private static final String TAG = Engine.class.getSimpleName();
@@ -87,22 +91,25 @@ public final class Engine
private Subscriptions subscriptions;
private JSONPrefs jsonPrefs;
private AppInfo appInfo;
private final LinkedBlockingQueue engineEvents = new LinkedBlockingQueue<>();
private Thread handlerThread;
private Downloader downloader;
private SubscriptionUpdateCallback subscriptionUpdateCallback;
private final Context context;
+ private ComponentName componentName;
private boolean wasFirstRun = false;
private long nextUpdateBroadcast = Long.MAX_VALUE;
+ private int jobId = 0;
private Engine(final Context context)
{
this.context = context;
+ this.componentName = new ComponentName(context, DownloadJobService.class);
}
public String getPrefsDefault(final String key)
{
return this.jsonPrefs.getDefaults(key);
}
DefaultSubscriptionInfo getDefaultSubscriptionInfo(final Subscription sub)
@@ -420,16 +427,22 @@ public final class Engine
final Subscription exceptions = engine.subscriptions.add(Subscription
.create(engine.getPrefsDefault(SUBSCRIPTIONS_EXCEPTIONSURL))
.parseLines(readLines(exceptionsTxt)));
exceptions.putMeta(Subscription.KEY_UPDATE_TIMESTAMP, "0");
exceptions.setEnabled(true);
}
Log.d(TAG, "Added and enabled bundled exceptionslist");
+ // The Notification should be download regularly.
+ // See https://issues.adblockplus.org/ticket/6238
+ final Subscription notification = engine.subscriptions.add(Subscription
+ .create(Notification.NOTIFICATION_URL));
+ notification.setEnabled(true);
+
int additional = 0;
for (final Subscription sub : engine.defaultSubscriptions.createSubscriptions())
{
if (!engine.subscriptions.hasSubscription(sub.getId()))
{
additional++;
engine.subscriptions.add(sub);
}
@@ -650,18 +663,26 @@ public final class Engine
engine.subscriptions.changeSubscriptionState(cese.id, cese.enabled);
break;
}
case DOWNLOAD_FINISHED:
{
final DownloadFinishedEvent dfe = (DownloadFinishedEvent) event;
Log.d(TAG, "Download finished for '" + dfe.id + "' with response code "
+ dfe.responseCode);
- this.engine.subscriptions.updateSubscription(dfe.id, dfe.responseCode,
- dfe.response, dfe.headers);
+ if (SubscriptionUtils.isNotificationSubscription(dfe.id))
+ {
+ Notification.update(engine.context, dfe.responseCode, dfe.response,
+ engine.subscriptions.getNotificationDataFile());
+ }
+ else
+ {
+ this.engine.subscriptions.updateSubscription(dfe.id, dfe.responseCode,
+ dfe.response, dfe.headers);
+ }
break;
}
default:
Log.d(TAG, "Unhandled type: " + event.getType());
break;
}
}
@@ -755,34 +776,64 @@ public final class Engine
this.headers.putAll(headers);
}
}
}
public void enqueueDownload(final Subscription sub, final boolean forced,
final boolean allowMetered) throws IOException
{
- if (sub.getURL() != null && sub.shouldUpdate(forced))
+ // For now we want to use JobScheduler only for the Notification download.
+ // See https://issues.adblockplus.org/ticket/6238.
+ if (SubscriptionUtils.isNotificationSubscription(sub.getId()))
{
- final HashMap headers = new HashMap<>();
- if (sub.isMetaDataValid() && sub.isFiltersValid())
+ if (Notification.shouldUpdate(context))
{
- final String lastModified = sub.getMeta(Subscription.KEY_HTTP_LAST_MODIFIED);
- if (!TextUtils.isEmpty(lastModified))
+ scheduleJob(this.createDownloadURL(sub), sub.getId(), allowMetered);
+ }
+ }
+ else
+ {
+ if (sub.getURL() != null && sub.shouldUpdate(forced))
+ {
+ final HashMap headers = new HashMap<>();
+ if (sub.isMetaDataValid() && sub.isFiltersValid())
{
- headers.put("If-Modified-Since", lastModified);
+ final String lastModified = sub.getMeta(Subscription.KEY_HTTP_LAST_MODIFIED);
+ if (!TextUtils.isEmpty(lastModified))
+ {
+ headers.put("If-Modified-Since", lastModified);
+ }
+ final String etag = sub.getMeta(Subscription.KEY_HTTP_ETAG);
+ if (!TextUtils.isEmpty(etag))
+ {
+ headers.put("If-None-Match", etag);
+ }
}
- final String etag = sub.getMeta(Subscription.KEY_HTTP_ETAG);
- if (!TextUtils.isEmpty(etag))
- {
- headers.put("If-None-Match", etag);
- }
+ this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(), headers, allowMetered);
}
- Log.d(TAG, headers.toString());
- this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(), headers, allowMetered);
+ }
+ }
+
+ private void scheduleJob(final URL url, final String id, final boolean allowMetered)
+ {
+ final JobInfo.Builder builder = new JobInfo.Builder(jobId++, componentName);
+ builder.setRequiredNetworkType(allowMetered
+ ? JobInfo.NETWORK_TYPE_UNMETERED
+ : JobInfo.NETWORK_TYPE_ANY);
+
+ final PersistableBundle extras = new PersistableBundle();
+ extras.putString(Notification.KEY_EXTRA_ID, id);
+ extras.putString(Notification.KEY_EXTRA_URL, url.toString());
+ builder.setExtras(extras);
+
+ final JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ if (scheduler != null)
+ {
+ scheduler.schedule(builder.build());
}
}
public void connectivityChanged()
{
this.downloader.connectivityChanged();
}
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Notification.java
===================================================================
new file mode 100644
--- /dev/null
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Notification.java
@@ -0,0 +1,89 @@
+/*
+ * This file is part of Adblock Plus ,
+ * 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 .
+ */
+
+package org.adblockplus.sbrowser.contentblocker.engine;
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPOutputStream;
+
+import org.adblockplus.adblockplussbrowser.R;
+import org.adblockplus.sbrowser.contentblocker.util.SharedPrefsUtils;
+
+import android.content.Context;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import javax.net.ssl.HttpsURLConnection;
+
+public class Notification
+{
+ private static final String TAG = Notification.class.getSimpleName();
+ public static final String NOTIFICATION_URL = "https://notification.adblockplus.org/notification.json";
+ public static final String NOTIFICATION_DATA_FILE_NAME = "notification.abp";
+ public static final String KEY_EXTRA_ID = "_extra_id";
+ public static final String KEY_EXTRA_URL = "_extra_url";
+
+ private static final long NOTIFICATION_DOWNLOAD_INTERVAL = DateUtils.DAY_IN_MILLIS;
+ private static final long DOWNLOAD_RETRY_INTERVAL = DateUtils.HOUR_IN_MILLIS;
+
+ public static boolean shouldUpdate(final Context context)
+ {
+ final long now = System.currentTimeMillis();
+ final long lastUpdate = SharedPrefsUtils.getLong(context, R.string.key_last_notification_update_timestamp, 0);
+ final long lastTry = SharedPrefsUtils.getLong(context, R.string.key_last_tried_notification_update_timestamp, 0);
+
+ if (lastTry > lastUpdate)
+ {
+ return now - lastTry > DOWNLOAD_RETRY_INTERVAL;
+ }
+ else
+ {
+ return now - lastUpdate > NOTIFICATION_DOWNLOAD_INTERVAL;
+ }
+ }
+
+ public static void update(final Context context, final int responseCode, final String text,
+ final File notificationDataFile)
+ {
+ if (responseCode != HttpsURLConnection.HTTP_OK || text == null)
+ {
+ SharedPrefsUtils.putLong(context, R.string.key_last_tried_notification_update_timestamp, System.currentTimeMillis());
+ }
+ else
+ {
+ SharedPrefsUtils.putLong(context, R.string.key_last_notification_update_timestamp, System.currentTimeMillis());
+ persistData(notificationDataFile, text);
+ }
+ }
+
+ private static void persistData(final File filtersFile, final String text)
+ {
+ try (final DataOutputStream outputStream = new DataOutputStream(new BufferedOutputStream(
+ new GZIPOutputStream(new FileOutputStream(filtersFile)))))
+ {
+ outputStream.write(text.getBytes());
+ }
+ catch (IOException e)
+ {
+ Log.d(TAG, "Failed to write notification data to internal storage.", e);
+ }
+ }
+}
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Subscriptions.java
===================================================================
--- a/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Subscriptions.java
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Subscriptions.java
@@ -26,16 +26,17 @@ import java.nio.charset.StandardCharsets
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.adblockplus.sbrowser.contentblocker.engine.Subscription.Type;
+import org.adblockplus.sbrowser.contentblocker.util.SubscriptionUtils;
import android.util.Log;
/**
* This class holds all listed subscriptions and manages the subscription
* aggregation cache folder.
*/
final class Subscriptions
@@ -139,16 +140,21 @@ final class Subscriptions
else
{
filtersFile = new File(this.subscriptionFolder, "url_"
+ new File(sub.getURL().getPath()).getName() + ".sub");
}
return filtersFile;
}
+ File getNotificationDataFile()
+ {
+ return new File (this.subscriptionFolder, Notification.NOTIFICATION_DATA_FILE_NAME);
+ }
+
File getMetaFile(final Subscription sub)
{
return new File(getFiltersFile(sub).getAbsolutePath() + ".meta");
}
void persistSubscription(final Subscription sub) throws IOException
{
sub.serializeSubscription(this.getMetaFile(sub), this.getFiltersFile(sub));
@@ -169,17 +175,17 @@ final class Subscriptions
* @param output
* @throws IOException
*/
private void writeFile(final File output) throws IOException
{
final HashSet filters = new HashSet<>();
for (final Subscription s : this.subscriptions.values())
{
- if (s.isEnabled())
+ if (s.isEnabled() && !SubscriptionUtils.isNotificationSubscription(s.getId()))
{
Log.d(TAG, "Adding filters for '" + s.getId() + "'");
s.deserializeFilters(this.getFiltersFile(s));
s.copyFilters(filters);
s.clearFilters();
}
if ((!s.isMetaDataValid() || !s.isFiltersValid()) && s.getURL() != null)
{
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/util/SharedPrefsUtils.java
===================================================================
--- a/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/util/SharedPrefsUtils.java
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/util/SharedPrefsUtils.java
@@ -59,16 +59,35 @@ public class SharedPrefsUtils
return preferences.getInt(context.getString(keyResId), defValue);
}
catch (ClassCastException e)
{
return defValue;
}
}
+ public static void putLong(final Context context, final int keyResId, final long value)
+ {
+ final SharedPreferences.Editor editor = getDefaultSharedPreferences(context).edit();
+ editor.putLong(context.getString(keyResId), value).apply();
+ }
+
+ public static long getLong(final Context context, final int keyResId, final long defValue)
+ {
+ final SharedPreferences preferences = getDefaultSharedPreferences(context);
+ try
+ {
+ return preferences.getLong(context.getString(keyResId), defValue);
+ }
+ catch (final ClassCastException e)
+ {
+ return defValue;
+ }
+ }
+
public static void putString(Context context, int keyResId, String value)
{
final SharedPreferences.Editor editor = getDefaultSharedPreferences(context).edit();
editor.putString(context.getString(keyResId), value).apply();
}
public static String getString(Context context, int keyResId, String defValue)
{
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/util/SubscriptionUtils.java
===================================================================
--- a/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/util/SubscriptionUtils.java
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/util/SubscriptionUtils.java
@@ -16,16 +16,17 @@
*/
package org.adblockplus.sbrowser.contentblocker.util;
import java.util.List;
import java.util.Locale;
import org.adblockplus.adblockplussbrowser.BuildConfig;
+import org.adblockplus.sbrowser.contentblocker.engine.Notification;
import org.adblockplus.sbrowser.contentblocker.engine.DefaultSubscriptionInfo;
import org.adblockplus.sbrowser.contentblocker.engine.Engine;
import android.content.res.Resources;
public class SubscriptionUtils
{
@@ -91,9 +92,14 @@ public class SubscriptionUtils
case YIDDISH_OLD:
return YIDDISH_NEW;
case INDONESIAN_OLD:
return INDONESIAN_NEW;
default:
return language;
}
}
+
+ public static boolean isNotificationSubscription(final String id)
+ {
+ return id != null && id.contains(Notification.NOTIFICATION_URL);
+ }
}