Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java

Issue 29389555: Issue 5010 - Allow to preload subscription files (Closed)
Patch Set: force downloading actually Created March 30, 2017, 10:12 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java
diff --git a/libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java b/libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java
index 2b6138245dddd39e780ee5c851f7b584956c9681..56e403c81eb9e2e90e3701a4158581ebd82ca93e 100644
--- a/libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java
+++ b/libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import org.adblockplus.libadblockplus.AppInfo;
@@ -36,15 +37,21 @@ import org.adblockplus.libadblockplus.ShowNotificationCallback;
import org.adblockplus.libadblockplus.Subscription;
import org.adblockplus.libadblockplus.UpdateAvailableCallback;
import org.adblockplus.libadblockplus.UpdateCheckDoneCallback;
+import org.adblockplus.libadblockplus.WebRequest;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build.VERSION;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
public final class AdblockEngine
{
+ // default base path to store subscription files in android app
+ public static final String BASE_PATH_DIRECTORY = "adblock";
+
private static final String TAG = Utils.getTag(AdblockEngine.class);
/*
@@ -61,19 +68,14 @@ public final class AdblockEngine
private volatile JsEngine jsEngine;
private volatile FilterEngine filterEngine;
private volatile LogSystem logSystem;
- private volatile AndroidWebRequest webRequest;
+ private volatile WebRequest webRequest;
private volatile UpdateAvailableCallback updateAvailableCallback;
private volatile UpdateCheckDoneCallback updateCheckDoneCallback;
private volatile FilterChangeCallback filterChangeCallback;
private volatile ShowNotificationCallback showNotificationCallback;
- private final boolean elemhideEnabled;
+ private volatile boolean elemhideEnabled;
private volatile boolean enabled = true;
- private List<String> whitelistedDomains;
-
- private AdblockEngine(final boolean enableElemhide)
- {
- this.elemhideEnabled = enableElemhide;
- }
+ private volatile List<String> whitelistedDomains;
public static AppInfo generateAppInfo(final Context context, boolean developmentBuild)
{
@@ -100,59 +102,182 @@ public final class AdblockEngine
.build();
}
- public static AdblockEngine create(final AppInfo appInfo,
- final String basePath, boolean enableElemhide,
- UpdateAvailableCallback updateAvailableCallback,
- UpdateCheckDoneCallback updateCheckDoneCallback,
- ShowNotificationCallback showNotificationCallback,
- FilterChangeCallback filterChangeCallback)
+ /**
+ * Builds Adblock engine
+ */
+ public static class Builder
{
- Log.w(TAG, "Create");
+ private Context context;
+ private Map<String, Integer> URLtoResourceIdMap;
+ private AndroidWebRequestResourceWrapper.Storage resourceStorage;
+ private AndroidWebRequest androidWebRequest;
+ private AppInfo appInfo;
+ private String basePath;
- final AdblockEngine engine = new AdblockEngine(enableElemhide);
+ private AdblockEngine engine;
- engine.jsEngine = new JsEngine(appInfo);
- engine.jsEngine.setDefaultFileSystem(basePath);
+ protected Builder(final AppInfo appInfo, final String basePath)
+ {
+ engine = new AdblockEngine();
+ engine.elemhideEnabled = true;
- engine.logSystem = new AndroidLogSystem();
- engine.jsEngine.setLogSystem(engine.logSystem);
+ // we can't create JsEngine and FilterEngine right now as it starts to download subscriptions
+ // and requests (AndroidWebRequest and probbaly wrappers) are not specified yet
+ this.appInfo = appInfo;
+ this.basePath = basePath;
+ }
- engine.webRequest = new AndroidWebRequest(enableElemhide);
- engine.jsEngine.setWebRequest(engine.webRequest);
+ public Builder enableElementHiding(boolean enable)
+ {
+ engine.elemhideEnabled = enable;
+ return this;
+ }
- engine.filterEngine = new FilterEngine(engine.jsEngine);
+ public Builder preloadSubscriptions(Context context,
+ Map<String, Integer> URLtoResourceIdMap,
+ AndroidWebRequestResourceWrapper.Storage storage)
+ {
+ this.context = context;
+ this.URLtoResourceIdMap = URLtoResourceIdMap;
+ this.resourceStorage = storage;
+ return this;
+ }
- engine.updateAvailableCallback = updateAvailableCallback;
- if (engine.updateAvailableCallback != null)
+ public Builder setUpdateAvailableCallback(UpdateAvailableCallback callback)
{
- engine.filterEngine.setUpdateAvailableCallback(updateAvailableCallback);
+ engine.updateAvailableCallback = callback;
+ return this;
}
- engine.updateCheckDoneCallback = updateCheckDoneCallback;
+ public Builder setUpdateCheckDoneCallback(UpdateCheckDoneCallback callback)
+ {
+ engine.updateCheckDoneCallback = callback;
+ return this;
+ }
- engine.showNotificationCallback = showNotificationCallback;
- if (engine.showNotificationCallback != null)
+ public Builder setShowNotificationCallback(ShowNotificationCallback callback)
{
- engine.filterEngine.setShowNotificationCallback(showNotificationCallback);
+ engine.showNotificationCallback = callback;
+ return this;
}
- engine.filterChangeCallback = filterChangeCallback;
- if (engine.filterChangeCallback != null)
+ public Builder setFilterChangeCallback(FilterChangeCallback callback)
{
- engine.filterEngine.setFilterChangeCallback(filterChangeCallback);
+ engine.filterChangeCallback = callback;
+ return this;
}
- engine.webRequest.updateSubscriptionURLs(engine.filterEngine);
+ private void initRequests()
+ {
+ androidWebRequest = new AndroidWebRequest(engine.elemhideEnabled);
+ engine.webRequest = androidWebRequest;
- return engine;
+ if (URLtoResourceIdMap != null)
+ {
+ AndroidWebRequestResourceWrapper wrapper = new AndroidWebRequestResourceWrapper(
+ context, engine.webRequest, URLtoResourceIdMap, resourceStorage);
+ wrapper.setListener(engine.resourceWrapperListener);
+
+ engine.webRequest = wrapper;
+ }
+ }
+
+ private void initCallbacks()
+ {
+ if (engine.updateAvailableCallback != null)
+ {
+ engine.filterEngine.setUpdateAvailableCallback(engine.updateAvailableCallback);
+ }
+
+ if (engine.showNotificationCallback != null)
+ {
+ engine.filterEngine.setShowNotificationCallback(engine.showNotificationCallback);
+ }
+
+ if (engine.filterChangeCallback != null)
+ {
+ engine.filterEngine.setFilterChangeCallback(engine.filterChangeCallback);
+ }
+ }
+
+ public AdblockEngine build()
+ {
+ initRequests();
+
+ // webRequest should be ready to be used passed right after JsEngine is created
+ createEngines();
+
+ initCallbacks();
+
+ androidWebRequest.updateSubscriptionURLs(engine.filterEngine);
+
+ return engine;
+ }
+
+ private void createEngines()
+ {
+ engine.jsEngine = new JsEngine(appInfo);
+ engine.jsEngine.setDefaultFileSystem(basePath);
+
+ engine.jsEngine.setWebRequest(engine.webRequest);
+
+ engine.logSystem = new AndroidLogSystem();
+ engine.jsEngine.setLogSystem(engine.logSystem);
+
+ engine.filterEngine = new FilterEngine(engine.jsEngine);
+ }
}
- public static AdblockEngine create(final AppInfo appInfo,
- final String basePath, boolean elemhideEnabled)
+ public static Builder builder(AppInfo appInfo, String basePath)
{
- return create(appInfo, basePath, elemhideEnabled, null, null, null, null);
+ return new Builder(appInfo, basePath);
}
+ private final AndroidWebRequestResourceWrapper.Listener resourceWrapperListener =
+ new AndroidWebRequestResourceWrapper.Listener()
+ {
+ private static final int UPDATE_DELAY_MS = 1 * 1000;
+
+ private final Handler handler = new Handler(Looper.getMainLooper());
+
+ private final Runnable forceUpdateRunnable = new Runnable()
+ {
+ public void run() {
+ // Filter Engine can be already disposed
+ if (filterEngine != null)
+ {
+ Log.d(TAG, "Force update subscriptions");
+ List<Subscription> subscriptions = filterEngine.getListedSubscriptions();
+ for (Subscription eachSubscription : subscriptions)
sergei 2017/03/30 22:14:37 Nit: I would remove "each".
+ {
+ try
+ {
+ eachSubscription.updateFilters();
+ }
+ finally
+ {
+ eachSubscription.dispose();
+ }
+ }
+ }
+ }
+ };
+
+ @Override
+ public void onIntercepted(String url, int resourceId)
+ {
+ // we need to force update subscriptions ASAP after preloaded one is returned
+ // but we should note that multiple interceptions (for main easylist and AA) and force update once only
+
+ // adding into main thread queue to avoid concurrency issues (start update while updating)
+ // as usually onIntercepted() is invoked in background thread
+ handler.removeCallbacks(forceUpdateRunnable);
+ handler.postDelayed(forceUpdateRunnable, UPDATE_DELAY_MS);
+
+ Log.d(TAG, "Scheduled force update in " + UPDATE_DELAY_MS);
+ }
+ };
+
public void dispose()
{
Log.w(TAG, "Dispose");

Powered by Google App Engine
This is Rietveld