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

Side by Side Diff: libadblockplus-android-webview/src/org/adblockplus/libadblockplus/android/webview/AdblockWebView.java

Issue 29671734: Issue 6265 - Create shared AdblockEngine instance in AdblockWebView in background (Closed)
Patch Set: addressed Diego's comments Created Jan. 19, 2018, 12:23 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 import android.webkit.WebResourceRequest; // makes android min version to be 21 42 import android.webkit.WebResourceRequest; // makes android min version to be 21
43 import android.webkit.WebResourceResponse; 43 import android.webkit.WebResourceResponse;
44 import android.webkit.WebStorage; 44 import android.webkit.WebStorage;
45 import android.webkit.WebView; 45 import android.webkit.WebView;
46 import android.webkit.WebViewClient; 46 import android.webkit.WebViewClient;
47 47
48 import org.adblockplus.libadblockplus.FilterEngine; 48 import org.adblockplus.libadblockplus.FilterEngine;
49 import org.adblockplus.libadblockplus.Subscription; 49 import org.adblockplus.libadblockplus.Subscription;
50 import org.adblockplus.libadblockplus.android.AdblockEngine; 50 import org.adblockplus.libadblockplus.android.AdblockEngine;
51 import org.adblockplus.libadblockplus.android.AdblockEngineProvider; 51 import org.adblockplus.libadblockplus.android.AdblockEngineProvider;
52 import org.adblockplus.libadblockplus.android.SingletonEngineProvider; 52 import org.adblockplus.libadblockplus.android.SingleInstanceEngineProvider;
53 import org.adblockplus.libadblockplus.android.Utils; 53 import org.adblockplus.libadblockplus.android.Utils;
54 54
55 import java.io.IOException; 55 import java.io.IOException;
56 import java.util.Collections; 56 import java.util.Collections;
57 import java.util.HashMap; 57 import java.util.HashMap;
58 import java.util.List; 58 import java.util.List;
59 import java.util.Map; 59 import java.util.Map;
60 import java.util.concurrent.CountDownLatch; 60 import java.util.concurrent.CountDownLatch;
61 import java.util.concurrent.atomic.AtomicBoolean; 61 import java.util.concurrent.atomic.AtomicBoolean;
62 import java.util.regex.Pattern; 62 import java.util.regex.Pattern;
(...skipping 27 matching lines...) Expand all
90 90
91 private static final Pattern RE_JS = Pattern.compile("\\.js$", Pattern.CASE_IN SENSITIVE); 91 private static final Pattern RE_JS = Pattern.compile("\\.js$", Pattern.CASE_IN SENSITIVE);
92 private static final Pattern RE_CSS = Pattern.compile("\\.css$", Pattern.CASE_ INSENSITIVE); 92 private static final Pattern RE_CSS = Pattern.compile("\\.css$", Pattern.CASE_ INSENSITIVE);
93 private static final Pattern RE_IMAGE = Pattern.compile("\\.(?:gif|png|jpe?g|b mp|ico)$", Pattern.CASE_INSENSITIVE); 93 private static final Pattern RE_IMAGE = Pattern.compile("\\.(?:gif|png|jpe?g|b mp|ico)$", Pattern.CASE_INSENSITIVE);
94 private static final Pattern RE_FONT = Pattern.compile("\\.(?:ttf|woff)$", Pat tern.CASE_INSENSITIVE); 94 private static final Pattern RE_FONT = Pattern.compile("\\.(?:ttf|woff)$", Pat tern.CASE_INSENSITIVE);
95 private static final Pattern RE_HTML = Pattern.compile("\\.html?$", Pattern.CA SE_INSENSITIVE); 95 private static final Pattern RE_HTML = Pattern.compile("\\.html?$", Pattern.CA SE_INSENSITIVE);
96 96
97 private volatile boolean addDomListener = true; 97 private volatile boolean addDomListener = true;
98 private boolean adblockEnabled = true; 98 private boolean adblockEnabled = true;
99 private boolean debugMode; 99 private boolean debugMode;
100 private AdblockEngineProvider adblockEngineProvider; 100 private AdblockEngineProvider provider;
101 private Integer loadError; 101 private Integer loadError;
102 private int allowDrawDelay = ALLOW_DRAW_DELAY; 102 private int allowDrawDelay = ALLOW_DRAW_DELAY;
103 private WebChromeClient extWebChromeClient; 103 private WebChromeClient extWebChromeClient;
104 private WebViewClient extWebViewClient; 104 private WebViewClient extWebViewClient;
105 private WebViewClient intWebViewClient; 105 private WebViewClient intWebViewClient;
106 private Map<String, String> url2Referrer = Collections.synchronizedMap(new Has hMap<String, String>()); 106 private Map<String, String> url2Referrer = Collections.synchronizedMap(new Has hMap<String, String>());
107 private String url; 107 private String url;
108 private String domain; 108 private String domain;
109 private String injectJs; 109 private String injectJs;
110 private CountDownLatch elemHideLatch; 110 private CountDownLatch elemHideLatch;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 .replace(DEBUG_TOKEN, (debugMode ? "" : "//")); 227 .replace(DEBUG_TOKEN, (debugMode ? "" : "//"));
228 } 228 }
229 229
230 private void runScript(String script) 230 private void runScript(String script)
231 { 231 {
232 d("runScript started"); 232 d("runScript started");
233 evaluateJavascript(script, null); 233 evaluateJavascript(script, null);
234 d("runScript finished"); 234 d("runScript finished");
235 } 235 }
236 236
237 public void setAdblockEngineProvider(final AdblockEngineProvider adblockEngine Provider) 237 public void setProvider(final AdblockEngineProvider provider)
238 { 238 {
239 if (this.adblockEngineProvider != null && adblockEngineProvider != null && t his.adblockEngineProvider == adblockEngineProvider) 239 if (this.provider != null && provider != null && this.provider == provider)
240 { 240 {
241 return; 241 return;
242 } 242 }
243 243
244 final Runnable setRunnable = new Runnable() 244 final Runnable setRunnable = new Runnable()
245 { 245 {
246 @Override 246 @Override
247 public void run() 247 public void run()
248 { 248 {
249 AdblockWebView.this.adblockEngineProvider = adblockEngineProvider; 249 AdblockWebView.this.provider = provider;
250 AdblockWebView.this.adblockEngineProvider.retain(true); // asynchronousl y 250 AdblockWebView.this.provider.retain(true); // asynchronously
251 } 251 }
252 }; 252 };
253 253
254 if (this.adblockEngineProvider != null) 254 if (this.provider != null)
255 { 255 {
256 // as adblockEngine can be busy with elemhide thread we need to use callba ck 256 // as adblockEngine can be busy with elemhide thread we need to use callba ck
257 this.dispose(setRunnable); 257 this.dispose(setRunnable);
258 } 258 }
259 else 259 else
260 { 260 {
261 setRunnable.run(); 261 setRunnable.run();
262 } 262 }
263 } 263 }
264 264
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 { 810 {
811 super.onReceivedLoginRequest(view, realm, account, args); 811 super.onReceivedLoginRequest(view, realm, account, args);
812 } 812 }
813 } 813 }
814 814
815 protected WebResourceResponse shouldInterceptRequest( 815 protected WebResourceResponse shouldInterceptRequest(
816 WebView webview, String url, boolean isMainFrame, 816 WebView webview, String url, boolean isMainFrame,
817 boolean isXmlHttpRequest, String[] referrerChainArray) 817 boolean isXmlHttpRequest, String[] referrerChainArray)
818 { 818 {
819 // if dispose() was invoke, but the page is still loading then just let it go 819 // if dispose() was invoke, but the page is still loading then just let it go
820 if (adblockEngineProvider.getAdblockEngine() == null) 820 if (provider.getCounter() == 0)
821 { 821 {
822 e("FilterEngine already disposed, allow loading"); 822 e("FilterEngine already disposed, allow loading");
823 823
824 // allow loading by returning null 824 // allow loading by returning null
825 return null; 825 return null;
826 } 826 }
827 827
828 if (isMainFrame) 828 if (isMainFrame)
829 { 829 {
830 // never blocking main frame requests, just subrequests 830 // never blocking main frame requests, just subrequests
831 w(url + " is main frame, allow loading"); 831 w(url + " is main frame, allow loading");
832 832
833 // allow loading by returning null 833 // allow loading by returning null
834 return null; 834 return null;
835 } 835 }
836 836
837 // whitelisted 837 // whitelisted
838 if (adblockEngineProvider.getAdblockEngine().isDomainWhitelisted(url, refe rrerChainArray)) 838 if (provider.getEngine().isDomainWhitelisted(url, referrerChainArray))
839 { 839 {
840 w(url + " domain is whitelisted, allow loading"); 840 w(url + " domain is whitelisted, allow loading");
841 841
842 // allow loading by returning null 842 // allow loading by returning null
843 return null; 843 return null;
844 } 844 }
845 845
846 if (adblockEngineProvider.getAdblockEngine().isDocumentWhitelisted(url, re ferrerChainArray)) 846 if (provider.getEngine().isDocumentWhitelisted(url, referrerChainArray))
847 { 847 {
848 w(url + " document is whitelisted, allow loading"); 848 w(url + " document is whitelisted, allow loading");
849 849
850 // allow loading by returning null 850 // allow loading by returning null
851 return null; 851 return null;
852 } 852 }
853 853
854 // determine the content 854 // determine the content
855 FilterEngine.ContentType contentType; 855 FilterEngine.ContentType contentType;
856 if (isXmlHttpRequest) 856 if (isXmlHttpRequest)
(...skipping 22 matching lines...) Expand all
879 { 879 {
880 contentType = FilterEngine.ContentType.SUBDOCUMENT; 880 contentType = FilterEngine.ContentType.SUBDOCUMENT;
881 } 881 }
882 else 882 else
883 { 883 {
884 contentType = FilterEngine.ContentType.OTHER; 884 contentType = FilterEngine.ContentType.OTHER;
885 } 885 }
886 } 886 }
887 887
888 // check if we should block 888 // check if we should block
889 if (adblockEngineProvider.getAdblockEngine().matches(url, contentType, ref errerChainArray)) 889 if (provider.getEngine().matches(url, contentType, referrerChainArray))
890 { 890 {
891 w("Blocked loading " + url); 891 w("Blocked loading " + url);
892 892
893 // if we should block, return empty response which results in 'errorLoad ing' callback 893 // if we should block, return empty response which results in 'errorLoad ing' callback
894 return new WebResourceResponse("text/plain", "UTF-8", null); 894 return new WebResourceResponse("text/plain", "UTF-8", null);
895 } 895 }
896 896
897 d("Allowed loading " + url); 897 d("Allowed loading " + url);
898 898
899 // continue by returning null 899 // continue by returning null
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 { 958 {
959 this.finishedLatch = finishedLatch; 959 this.finishedLatch = finishedLatch;
960 isCancelled = new AtomicBoolean(false); 960 isCancelled = new AtomicBoolean(false);
961 } 961 }
962 962
963 @Override 963 @Override
964 public void run() 964 public void run()
965 { 965 {
966 try 966 try
967 { 967 {
968 if (adblockEngineProvider.getAdblockEngine() == null) 968 if (provider.getCounter() == 0)
969 { 969 {
970 w("FilterEngine already disposed"); 970 w("FilterEngine already disposed");
971 selectorsString = EMPTY_ELEMHIDE_ARRAY_STRING; 971 selectorsString = EMPTY_ELEMHIDE_ARRAY_STRING;
972 } 972 }
973 else 973 else
974 { 974 {
975 String[] referrers = new String[] 975 String[] referrers = new String[]
976 { 976 {
977 url 977 url
978 }; 978 };
979 979
980 List<Subscription> subscriptions = adblockEngineProvider 980 List<Subscription> subscriptions = provider
981 .getAdblockEngine() 981 .getEngine()
982 .getFilterEngine() 982 .getFilterEngine()
983 .getListedSubscriptions(); 983 .getListedSubscriptions();
984 984
985 try 985 try
986 { 986 {
987 d("Listed subscriptions: " + subscriptions.size()); 987 d("Listed subscriptions: " + subscriptions.size());
988 if (debugMode) 988 if (debugMode)
989 { 989 {
990 for (Subscription eachSubscription : subscriptions) 990 for (Subscription eachSubscription : subscriptions)
991 { 991 {
992 d("Subscribed to " 992 d("Subscribed to "
993 + (eachSubscription.isDisabled() ? "disabled" : "enabled") 993 + (eachSubscription.isDisabled() ? "disabled" : "enabled")
994 + " " + eachSubscription); 994 + " " + eachSubscription);
995 } 995 }
996 } 996 }
997 } 997 }
998 finally 998 finally
999 { 999 {
1000 for (Subscription eachSubscription : subscriptions) 1000 for (Subscription eachSubscription : subscriptions)
1001 { 1001 {
1002 eachSubscription.dispose(); 1002 eachSubscription.dispose();
1003 } 1003 }
1004 } 1004 }
1005 1005
1006 d("Requesting elemhide selectors from AdblockEngine for " + url + " in " + this); 1006 d("Requesting elemhide selectors from AdblockEngine for " + url + " in " + this);
1007 List<String> selectors = adblockEngineProvider 1007 List<String> selectors = provider
1008 .getAdblockEngine() 1008 .getEngine()
1009 .getElementHidingSelectors(url, domain, referrers); 1009 .getElementHidingSelectors(url, domain, referrers);
1010 1010
1011 d("Finished requesting elemhide selectors, got " + selectors.size() + " in " + this); 1011 d("Finished requesting elemhide selectors, got " + selectors.size() + " in " + this);
1012 selectorsString = Utils.stringListToJsonArray(selectors); 1012 selectorsString = Utils.stringListToJsonArray(selectors);
1013 } 1013 }
1014 } 1014 }
1015 finally 1015 finally
1016 { 1016 {
1017 if (!isCancelled.get()) 1017 if (!isCancelled.get())
1018 { 1018 {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 w("elemHideThread set to null"); 1074 w("elemHideThread set to null");
1075 elemHideThread = null; 1075 elemHideThread = null;
1076 } 1076 }
1077 } 1077 }
1078 }; 1078 };
1079 1079
1080 private void initAbpLoading() 1080 private void initAbpLoading()
1081 { 1081 {
1082 getSettings().setJavaScriptEnabled(true); 1082 getSettings().setJavaScriptEnabled(true);
1083 buildInjectJs(); 1083 buildInjectJs();
1084 initEngineProvider(); 1084 initProvider();
1085 } 1085 }
1086 1086
1087 private void initEngineProvider() 1087 private void initProvider()
1088 { 1088 {
1089 // if AdblockWebView works as drop-in replacement for WebView 'adblockEngine Provider' is not set. 1089 // if AdblockWebView works as drop-in replacement for WebView 'provider' is not set.
1090 // Thus AdblockWebView is using SingletonEngineProvider instance 1090 // Thus AdblockWebView is using SingleInstanceEngineProvider instance
1091 if (adblockEngineProvider == null) 1091 if (provider == null)
1092 { 1092 {
1093 setAdblockEngineProvider(new SingletonEngineProvider( 1093 setProvider(new SingleInstanceEngineProvider(
1094 getContext(), AdblockEngine.BASE_PATH_DIRECTORY, debugMode)); 1094 getContext(), AdblockEngine.BASE_PATH_DIRECTORY, debugMode));
1095 } 1095 }
1096 } 1096 }
1097 1097
1098 private void startAbpLoading(String newUrl) 1098 private void startAbpLoading(String newUrl)
1099 { 1099 {
1100 d("Start loading " + newUrl); 1100 d("Start loading " + newUrl);
1101 1101
1102 loading = true; 1102 loading = true;
1103 addDomListener = true; 1103 addDomListener = true;
1104 elementsHidden = false; 1104 elementsHidden = false;
1105 loadError = null; 1105 loadError = null;
1106 url = newUrl; 1106 url = newUrl;
1107 1107
1108 if (url != null) 1108 if (url != null)
1109 { 1109 {
1110 try 1110 try
1111 { 1111 {
1112 adblockEngineProvider.waitForReady(); 1112 d("Waiting for adblock engine");
1113 domain = adblockEngineProvider.getAdblockEngine().getFilterEngine().getH ostFromURL(url); 1113 provider.waitForReady();
1114
1115 domain = provider.getEngine().getFilterEngine().getHostFromURL(url);
1114 if (domain == null) 1116 if (domain == null)
1115 { 1117 {
1116 throw new RuntimeException("Failed to extract domain from " + url); 1118 throw new RuntimeException("Failed to extract domain from " + url);
1117 } 1119 }
1118 1120
1119 d("Extracted domain " + domain + " from " + url); 1121 d("Extracted domain " + domain + " from " + url);
1120 } 1122 }
1121 catch (Throwable t) 1123 catch (Throwable t)
1122 { 1124 {
1123 e("Failed to extract domain from " + url, t); 1125 e("Failed to extract domain from " + url, t);
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1365 catch (InterruptedException e) 1367 catch (InterruptedException e)
1366 { 1368 {
1367 w("Interrupted, returning empty selectors list"); 1369 w("Interrupted, returning empty selectors list");
1368 return EMPTY_ELEMHIDE_ARRAY_STRING; 1370 return EMPTY_ELEMHIDE_ARRAY_STRING;
1369 } 1371 }
1370 } 1372 }
1371 } 1373 }
1372 1374
1373 private void doDispose() 1375 private void doDispose()
1374 { 1376 {
1375 adblockEngineProvider.release(); 1377 w("Disposing AdblockEngine");
1378 provider.release();
1376 } 1379 }
1377 1380
1378 private class DisposeRunnable implements Runnable 1381 private class DisposeRunnable implements Runnable
1379 { 1382 {
1380 private Runnable disposeFinished; 1383 private Runnable disposeFinished;
1381 1384
1382 private DisposeRunnable(Runnable disposeFinished) 1385 private DisposeRunnable(Runnable disposeFinished)
1383 { 1386 {
1384 this.disposeFinished = disposeFinished; 1387 this.disposeFinished = disposeFinished;
1385 } 1388 }
(...skipping 13 matching lines...) Expand all
1399 /** 1402 /**
1400 * Dispose AdblockWebView and internal adblockEngine if it was created 1403 * Dispose AdblockWebView and internal adblockEngine if it was created
1401 * If external AdblockEngine was passed using `setAdblockEngine()` it should b e disposed explicitly 1404 * If external AdblockEngine was passed using `setAdblockEngine()` it should b e disposed explicitly
1402 * Warning: runnable can be invoked from background thread 1405 * Warning: runnable can be invoked from background thread
1403 * @param disposeFinished runnable to run when AdblockWebView is disposed 1406 * @param disposeFinished runnable to run when AdblockWebView is disposed
1404 */ 1407 */
1405 public void dispose(final Runnable disposeFinished) 1408 public void dispose(final Runnable disposeFinished)
1406 { 1409 {
1407 d("Dispose invoked"); 1410 d("Dispose invoked");
1408 1411
1409 if (adblockEngineProvider == null) 1412 if (provider == null)
1410 { 1413 {
1411 d("No internal AdblockEngineProvider created"); 1414 d("No internal AdblockEngineProvider created");
1412 return; 1415 return;
1413 } 1416 }
1414 1417
1415 stopLoading(); 1418 stopLoading();
1416 1419
1417 DisposeRunnable disposeRunnable = new DisposeRunnable(disposeFinished); 1420 DisposeRunnable disposeRunnable = new DisposeRunnable(disposeFinished);
1418 synchronized (elemHideThreadLockObject) 1421 synchronized (elemHideThreadLockObject)
1419 { 1422 {
1420 if (elemHideThread != null) 1423 if (elemHideThread != null)
1421 { 1424 {
1422 w("Busy with elemhide selectors, delayed disposing scheduled"); 1425 w("Busy with elemhide selectors, delayed disposing scheduled");
1423 elemHideThread.setFinishedRunnable(disposeRunnable); 1426 elemHideThread.setFinishedRunnable(disposeRunnable);
1424 } 1427 }
1425 else 1428 else
1426 { 1429 {
1427 disposeRunnable.run(); 1430 disposeRunnable.run();
1428 } 1431 }
1429 } 1432 }
1430 } 1433 }
1431 } 1434 }
OLDNEW

Powered by Google App Engine
This is Rietveld