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

Delta Between Two Patch Sets: libadblockplus-android/src/org/adblockplus/libadblockplus/android/AdblockEngine.java

Issue 29351744: Issue 4399 - Add WebView inheritor with ad blocking (Closed)
Left Patch Set: added Maven build configuration files for -webview and -webviewapp modules Created Oct. 5, 2016, 11:19 a.m.
Right Patch Set: changed packages, now using AdblockEngine (original ABPEngine), improved demo app Created Oct. 25, 2016, 11:20 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Right: Side by side diff | Download
LEFTRIGHT
(no file at all)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package org.adblockplus.libadblockplus.android;
19
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Locale;
23
24 import org.adblockplus.libadblockplus.AppInfo;
25 import org.adblockplus.libadblockplus.Filter;
26 import org.adblockplus.libadblockplus.FilterChangeCallback;
27 import org.adblockplus.libadblockplus.FilterEngine;
28 import org.adblockplus.libadblockplus.FilterEngine.ContentType;
29 import org.adblockplus.libadblockplus.JsEngine;
30 import org.adblockplus.libadblockplus.LogSystem;
31 import org.adblockplus.libadblockplus.ShowNotificationCallback;
32 import org.adblockplus.libadblockplus.Subscription;
33 import org.adblockplus.libadblockplus.UpdateAvailableCallback;
34 import org.adblockplus.libadblockplus.UpdateCheckDoneCallback;
35
36 import android.content.Context;
37 import android.content.pm.PackageInfo;
38 import android.content.pm.PackageManager.NameNotFoundException;
39 import android.os.Build.VERSION;
40 import android.util.Log;
41
42 public final class AdblockEngine
43 {
44 private static final String TAG = Utils.getTag(AdblockEngine.class);
45
46 private final Context context;
47
48 /*
49 * The fields below are volatile because:
50 *
51 * I encountered JNI related bugs/crashes caused by JNI backed Java objects. I t seemed that under
52 * certain conditions the objects were optimized away which resulted in crashe s when trying to
53 * release the object, sometimes even on access.
54 *
55 * The only solution that really worked was to declare the variables holding t he references
56 * volatile, this seems to prevent the JNI from 'optimizing away' those object s (as a volatile
57 * variable might be changed at any time from any thread).
58 */
59 private volatile JsEngine jsEngine;
60 private volatile FilterEngine filterEngine;
61 private volatile LogSystem logSystem;
62 private volatile AndroidWebRequest webRequest;
63 private volatile UpdateAvailableCallback updateAvailableCallback;
64 private volatile UpdateCheckDoneCallback updateCheckDoneCallback;
65 private volatile FilterChangeCallback filterChangeCallback;
66 private volatile ShowNotificationCallback showNotificationCallback;
67 private final boolean elemhideEnabled;
68
69 private AdblockEngine(final Context context, final boolean enableElemhide)
70 {
71 this.context = context;
72 this.elemhideEnabled = enableElemhide;
73 }
74
75 public static AppInfo generateAppInfo(final Context context, boolean developme ntBuild)
76 {
77 String version = "0";
78 try
79 {
80 final PackageInfo info = context.getPackageManager().getPackageInfo(contex t.getPackageName(), 0);
81 version = info.versionName;
82 if (developmentBuild)
83 version += "." + info.versionCode;
84 }
85 catch (final NameNotFoundException e)
86 {
87 Log.e(TAG, "Failed to get the application version number", e);
88 }
89 final String sdkVersion = String.valueOf(VERSION.SDK_INT);
90 final String locale = Locale.getDefault().toString().replace('_', '-');
91
92 return AppInfo.builder()
93 .setVersion(version)
94 .setApplicationVersion(sdkVersion)
95 .setLocale(locale)
96 .setDevelopmentBuild(developmentBuild)
97 .build();
98 }
99
100 public static AdblockEngine create(final Context context, final AppInfo appInf o, final String basePath)
101 {
102 return create(context, appInfo, basePath, false);
103 }
104
105 public static AdblockEngine create(final Context context, final AppInfo appInf o, final String basePath, boolean enableElemhide)
106 {
107 final AdblockEngine engine = new AdblockEngine(context, enableElemhide);
108
109 engine.jsEngine = new JsEngine(appInfo);
110 engine.jsEngine.setDefaultFileSystem(basePath);
111
112 engine.logSystem = new AndroidLogSystem();
113 engine.jsEngine.setLogSystem(engine.logSystem);
114
115 engine.webRequest = new AndroidWebRequest(enableElemhide);
116 engine.jsEngine.setWebRequest(engine.webRequest);
117
118 engine.filterEngine = new FilterEngine(engine.jsEngine);
119
120 engine.webRequest.updateSubscriptionURLs(engine.filterEngine);
121
122 return engine;
123 }
124
125 public void dispose()
126 {
127 // Safe disposing (just in case)
128 if (this.filterEngine != null)
129 {
130 this.filterEngine.dispose();
131 this.filterEngine = null;
132 }
133
134 if (this.jsEngine != null)
135 {
136 this.jsEngine.dispose();
137 this.jsEngine = null;
138 }
139
140 if (this.logSystem != null)
141 {
142 this.logSystem.dispose();
143 this.logSystem = null;
144 }
145
146 if (this.webRequest != null)
147 {
148 this.webRequest.dispose();
149 this.webRequest = null;
150 }
151
152 if (this.updateAvailableCallback != null)
153 {
154 this.updateAvailableCallback.dispose();
155 this.updateAvailableCallback = null;
156 }
157
158 if (this.updateCheckDoneCallback != null)
159 {
160 this.updateCheckDoneCallback.dispose();
161 this.updateCheckDoneCallback = null;
162 }
163
164 if (this.filterChangeCallback != null)
165 {
166 this.filterChangeCallback.dispose();
167 this.filterChangeCallback = null;
168 }
169
170 if (this.showNotificationCallback != null)
171 {
172 this.showNotificationCallback.dispose();
173 this.showNotificationCallback = null;
174 }
175 }
176
177 public boolean isFirstRun()
178 {
179 return this.filterEngine.isFirstRun();
180 }
181
182 public boolean isElemhideEnabled()
183 {
184 return this.elemhideEnabled;
185 }
186
187 public void setSubscription(final String url)
188 {
189 for (final Subscription s : this.filterEngine.getListedSubscriptions())
190 {
191 s.removeFromList();
192 }
193
194 final Subscription sub = this.filterEngine.getSubscription(url);
195 if (sub != null)
196 {
197 sub.addToList();
198 }
199 }
200
201 public void refreshSubscriptions()
202 {
203 for (final Subscription s : this.filterEngine.getListedSubscriptions())
204 {
205 s.updateFilters();
206 }
207 }
208
209 public boolean isAcceptableAdsEnabled()
210 {
211 final String url = this.filterEngine.getPref("subscriptions_exceptionsurl"). toString();
212 List<Subscription> subscriptions = this.filterEngine.getListedSubscriptions( );
213 for (Subscription eachSubscription : subscriptions)
214 {
215 if (eachSubscription.getProperty("url").toString().equals(url))
216 {
217 return true;
218 }
219 }
220 return false;
221 }
222
223 public void setAcceptableAdsEnabled(final boolean enabled)
224 {
225 final String url = this.filterEngine.getPref("subscriptions_exceptionsurl"). toString();
226 final Subscription sub = this.filterEngine.getSubscription(url);
227 if (sub != null)
228 {
229 if (enabled)
230 {
231 sub.addToList();
232 }
233 else
234 {
235 sub.removeFromList();
236 }
237 }
238 }
239
240 public String getDocumentationLink()
241 {
242 return this.filterEngine.getPref("documentation_link").toString();
243 }
244
245 public boolean matches(final String fullUrl, final ContentType contentType, fi nal String[] referrerChainArray)
246 {
247 final Filter filter = this.filterEngine.matches(fullUrl, contentType, referr erChainArray);
248
249 if (filter == null)
250 {
251 return false;
252 }
253
254 // hack: if there is no referrer, block only if filter is domain-specific
255 // (to re-enable in-app ads blocking, proposed on 12.11.2012 Monday meeting)
256 // (documentUrls contains the referrers on Android)
257 try
258 {
259 if (referrerChainArray.length == 0 && (filter.getProperty("text").toString ()).contains("||"))
260 {
261 return false;
262 }
263 } catch (NullPointerException e) {
264 }
265
266 return filter.getType() != Filter.Type.EXCEPTION;
267 }
268
269 public boolean isDocumentWhitelisted(final String url, final String[] referrer ChainArray)
270 {
271 return this.filterEngine.isDocumentWhitelisted(url, referrerChainArray);
272 }
273
274 public boolean isElemhideWhitelisted(final String url, final String[] referrer ChainArray)
275 {
276 return this.filterEngine.isElemhideWhitelisted(url, referrerChainArray);
277 }
278
279 public List<String> getElementHidingSelectors(final String url, final String d omain, final String[] referrerChainArray)
280 {
281 /*
282 * Issue 3364 (https://issues.adblockplus.org/ticket/3364) introduced the
283 * feature to re-enabled element hiding.
284 *
285 * Nothing changes for Adblock Plus for Android, as `this.elemhideEnabled`
286 * is `false`, which results in an empty list being returned and converted
287 * into a `(String[])null` in AdblockPlus.java, which is the only place
288 * this function here is called from Adblock Plus for Android.
289 *
290 * If element hiding is enabled, then this function now first checks for
291 * possible whitelisting of either the document or element hiding for
292 * the given URL and returns an empty list if so. This is needed to
293 * ensure correct functioning of e.g. acceptable ads.
294 */
295 if (!this.elemhideEnabled
296 || this.isDocumentWhitelisted(url, referrerChainArray)
297 || this.isElemhideWhitelisted(url, referrerChainArray))
298 {
299 return new ArrayList<String>();
300 }
301 return this.filterEngine.getElementHidingSelectors(domain);
302 }
303
304 public void checkForUpdates()
305 {
306 this.filterEngine.forceUpdateCheck(this.updateCheckDoneCallback);
307 }
308
309 public FilterEngine getFilterEngine()
310 {
311 return this.filterEngine;
312 }
313 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld