| 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..3b790799b428e6638231c321a43dc2da4653caa7 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,171 @@ 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 AndroidWebRequestResourceWrapper.Listener resourceWrapperListener = |
| + new AndroidWebRequestResourceWrapper.Listener() |
|
diegocarloslima
2017/03/30 09:42:07
Since this member variable never changes, you shou
anton
2017/03/30 10:27:16
Acknowledged.
|
| + { |
| + private static final int UPDATE_DELAY_MS = 1 * 1000; |
| + |
| + private Handler handler = new Handler(Looper.getMainLooper()); |
|
diegocarloslima
2017/03/30 09:42:07
Since this member variable never changes, you shou
anton
2017/03/30 10:27:16
Acknowledged.
|
| + |
| + private Runnable forceUpdateRunnable = new Runnable() |
|
diegocarloslima
2017/03/30 09:42:07
Since this member variable never changes, you shou
|
| + { |
| + public void run() { |
| + // Filter Engine can be already disposed |
| + if (filterEngine != null) |
| + { |
| + Log.d(TAG, "Force update subscriptions"); |
| + filterEngine.forceUpdateCheck(updateCheckDoneCallback); |
| + } |
| + } |
| + }; |
| + |
| + @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"); |