OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |