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

Delta Between Two Patch Sets: src/org/adblockplus/android/AdblockPlus.java

Issue 5172657418928128: Determine the frame structure (Closed)
Left Patch Set: Created Nov. 23, 2013, 12:03 a.m.
Right Patch Set: Build referrer chains iteratively and limit their length Created Nov. 27, 2013, 2:47 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/org/adblockplus/android/ABPEngine.java ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 package org.adblockplus.android; 18 package org.adblockplus.android;
19 19
20 import java.io.BufferedReader; 20 import java.io.BufferedReader;
21 import java.io.File; 21 import java.io.File;
22 import java.io.FileNotFoundException; 22 import java.io.FileNotFoundException;
23 import java.io.IOException; 23 import java.io.IOException;
24 import java.io.InputStream; 24 import java.io.InputStream;
25 import java.io.InputStreamReader; 25 import java.io.InputStreamReader;
26 import java.util.ArrayList; 26 import java.util.ArrayList;
27 import java.util.Calendar; 27 import java.util.Calendar;
28 import java.util.Collections; 28 import java.util.LinkedHashMap;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List; 29 import java.util.List;
32 import java.util.Map; 30 import java.util.Map;
33 import java.util.Set;
34 import java.util.TimeZone; 31 import java.util.TimeZone;
35 import java.util.regex.Pattern; 32 import java.util.regex.Pattern;
36 33
37 import org.adblockplus.android.updater.AlarmReceiver; 34 import org.adblockplus.android.updater.AlarmReceiver;
38 35
39 import android.app.ActivityManager; 36 import android.app.ActivityManager;
40 import android.app.ActivityManager.RunningServiceInfo; 37 import android.app.ActivityManager.RunningServiceInfo;
41 import android.app.AlarmManager; 38 import android.app.AlarmManager;
42 import android.app.Application; 39 import android.app.Application;
43 import android.app.PendingIntent; 40 import android.app.PendingIntent;
44 import android.content.Context; 41 import android.content.Context;
45 import android.content.Intent; 42 import android.content.Intent;
43 import android.content.SharedPreferences;
44 import android.content.SharedPreferences.Editor;
46 import android.content.pm.PackageInfo; 45 import android.content.pm.PackageInfo;
47 import android.content.pm.PackageManager; 46 import android.content.pm.PackageManager;
48 import android.content.pm.PackageManager.NameNotFoundException; 47 import android.content.pm.PackageManager.NameNotFoundException;
49 import android.net.ConnectivityManager; 48 import android.net.ConnectivityManager;
50 import android.net.NetworkInfo; 49 import android.net.NetworkInfo;
51 import android.net.Uri; 50 import android.net.Uri;
52 import android.os.Build; 51 import android.os.Build;
52 import android.preference.PreferenceManager;
53 import android.provider.Settings; 53 import android.provider.Settings;
54 import android.util.Log; 54 import android.util.Log;
55 55
56 public class AdblockPlus extends Application 56 public class AdblockPlus extends Application
57 { 57 {
58 private final static String TAG = "Application"; 58 private final static String TAG = "Application";
59 59
60 private final static Pattern RE_JS = Pattern.compile(".*\\.js$", Pattern.CASE_ INSENSITIVE); 60 private final static Pattern RE_JS = Pattern.compile(".*\\.js$", Pattern.CASE_ INSENSITIVE);
61 private final static Pattern RE_CSS = Pattern.compile(".*\\.css$", Pattern.CAS E_INSENSITIVE); 61 private final static Pattern RE_CSS = Pattern.compile(".*\\.css$", Pattern.CAS E_INSENSITIVE);
62 private final static Pattern RE_IMAGE = Pattern.compile(".*\\.(?:gif|png|jpe?g |bmp|ico)$", Pattern.CASE_INSENSITIVE); 62 private final static Pattern RE_IMAGE = Pattern.compile(".*\\.(?:gif|png|jpe?g |bmp|ico)$", Pattern.CASE_INSENSITIVE);
(...skipping 18 matching lines...) Expand all
81 private Subscription[] subscriptions; 81 private Subscription[] subscriptions;
82 82
83 /** 83 /**
84 * Indicates whether filtering is enabled or not. 84 * Indicates whether filtering is enabled or not.
85 */ 85 */
86 private boolean filteringEnabled = false; 86 private boolean filteringEnabled = false;
87 87
88 private ABPEngine abpEngine; 88 private ABPEngine abpEngine;
89 89
90 private static AdblockPlus instance; 90 private static AdblockPlus instance;
91 91
92 private Map<String, Set<String>> referrerMapping = new HashMap<String, Set<Str ing>>(); 92 private static class ReferrerMappingCache extends LinkedHashMap<String, String >
93 {
94 private static final long serialVersionUID = 1L;
95 private static final int MAX_SIZE = 5000;
96
97 public ReferrerMappingCache()
98 {
99 super(MAX_SIZE + 1, 0.75f, true);
100 }
101
102 @Override
103 protected boolean removeEldestEntry(Map.Entry<String, String> eldest)
104 {
105 return size() > MAX_SIZE;
106 }
107 };
108
109 private ReferrerMappingCache referrerMapping = new ReferrerMappingCache();
93 110
94 /** 111 /**
95 * Returns pointer to itself (singleton pattern). 112 * Returns pointer to itself (singleton pattern).
96 */ 113 */
97 public static AdblockPlus getApplication() 114 public static AdblockPlus getApplication()
98 { 115 {
99 return instance; 116 return instance;
100 } 117 }
101 118
102 public int getBuildNumber() 119 public int getBuildNumber()
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 abpEngine.actualizeSubscriptionStatus(url); 301 abpEngine.actualizeSubscriptionStatus(url);
285 } 302 }
286 303
287 304
288 /** 305 /**
289 * Enables or disables Acceptable Ads 306 * Enables or disables Acceptable Ads
290 */ 307 */
291 public void setAcceptableAdsEnabled(boolean enabled) 308 public void setAcceptableAdsEnabled(boolean enabled)
292 { 309 {
293 abpEngine.setAcceptableAdsEnabled(enabled); 310 abpEngine.setAcceptableAdsEnabled(enabled);
311 }
312
313 public String getAcceptableAdsUrl()
314 {
315 final String documentationLink = abpEngine.getDocumentationLink();
316 final String locale = getResources().getConfiguration().locale.toString().re place("_", "-");
317 return documentationLink.replace("%LINK%", "acceptable_ads").replace("%LANG% ", locale);
318 }
319
320 public void setNotifiedAboutAcceptableAds(boolean notified)
321 {
322 final SharedPreferences preferences = PreferenceManager.getDefaultSharedPref erences(this);
323 final Editor editor = preferences.edit();
324 editor.putBoolean("notified_about_acceptable_ads", notified);
325 editor.commit();
326 }
327
328 public boolean isNotifiedAboutAcceptableAds()
329 {
330 final SharedPreferences preferences = PreferenceManager.getDefaultSharedPref erences(this);
331 return preferences.getBoolean("notified_about_acceptable_ads", false);
294 } 332 }
295 333
296 /** 334 /**
297 * Returns ElemHide selectors for domain. 335 * Returns ElemHide selectors for domain.
298 * 336 *
299 * @param domain The domain 337 * @param domain The domain
300 * @return A list of CSS selectors 338 * @return A list of CSS selectors
301 */ 339 */
302 public String[] getSelectorsForDomain(final String domain) 340 public String[] getSelectorsForDomain(final String domain)
303 { 341 {
(...skipping 13 matching lines...) Expand all
317 * @param referrer 355 * @param referrer
318 * Request referrer header 356 * Request referrer header
319 * @param accept 357 * @param accept
320 * Request accept header 358 * Request accept header
321 * @return true if matched filter was found 359 * @return true if matched filter was found
322 * @throws Exception 360 * @throws Exception
323 */ 361 */
324 public boolean matches(String url, String query, String referrer, String accep t) 362 public boolean matches(String url, String query, String referrer, String accep t)
325 { 363 {
326 if (referrer != null) 364 if (referrer != null)
327 recordReferrer(url, referrer); 365 referrerMapping.put(url, referrer);
328 366
329 if (!filteringEnabled) 367 if (!filteringEnabled)
330 return false; 368 return false;
331 369
332 String contentType = null; 370 String contentType = null;
333 371
334 if (accept != null) 372 if (accept != null)
335 { 373 {
336 if (accept.contains("text/css")) 374 if (accept.contains("text/css"))
337 contentType = "STYLESHEET"; 375 contentType = "STYLESHEET";
(...skipping 11 matching lines...) Expand all
349 contentType = "IMAGE"; 387 contentType = "IMAGE";
350 else if (RE_FONT.matcher(url).matches()) 388 else if (RE_FONT.matcher(url).matches())
351 contentType = "FONT"; 389 contentType = "FONT";
352 } 390 }
353 if (contentType == null) 391 if (contentType == null)
354 contentType = "OTHER"; 392 contentType = "OTHER";
355 393
356 if (!"".equals(query)) 394 if (!"".equals(query))
357 url = url + "?" + query; 395 url = url + "?" + query;
358 396
359 final List<List<String>> referrerChains = referrer != null 397 final List<String> referrerChain = buildReferrerChain(referrer);
360 ? buildReferrerChains(referrer) 398 Log.d("Referrer chain", url + ": " + referrerChain.toString());
361 : Collections.singletonList(Collections.<String>emptyList()); 399 String[] referrerChainArray = referrerChain.toArray(new String[referrerChain .size()]);
362 for (List<String> referrerChain : referrerChains) 400 return abpEngine.matches(url, contentType, referrerChainArray);
363 { 401 }
364 Log.d("Referrer chain", url + ": " + referrerChain.toString()); 402
365 String[] referrerChainArray = referrerChain.toArray(new String[referrerCha in.size()]); 403 private List<String> buildReferrerChain(String url)
366 if (abpEngine.matches(url, contentType, referrerChainArray)) 404 {
367 return true; 405 final List<String> referrerChain = new ArrayList<String>();
368 } 406 // We need to limit the chain length to ensure we don't block indefinitely i f there's
369 return false; 407 // a referrer loop.
370 } 408 final int maxChainLength = 10;
371 409 for (int i = 0; i < maxChainLength && url != null; i++)
372 private void recordReferrer(String url, String referrer) 410 {
373 {
374 // TODO: Garbage collect the mapping - currently it will grow out of control .
375 // In addition, we might have to persist mappings, because clients are
376 // likely to cache some requests in the chain.
377 if (!referrerMapping.containsKey(url))
378 referrerMapping.put(url, new HashSet<String>());
379 Set<String> referrers = referrerMapping.get(url);
380 referrers.add(referrer);
Wladimir Palant 2013/11/25 10:24:41 Do you think that this is really necessary? We are
Felix Dahlke 2013/11/27 12:19:32 Yes, I think it makes sense to not have a single c
Wladimir Palant 2013/11/27 12:59:01 Not with the same parameters - they have to know s
Felix Dahlke 2013/11/27 13:38:59 Alright, didn't think of that. Makes the code much
381 }
382
383 private List<List<String>> buildReferrerChains(String url)
384 {
385 List<List<String>> referrerChains = new ArrayList<List<String>>();
386 Set<String> referrers = referrerMapping.get(url);
387 if (referrers == null)
388 {
389 List<String> referrerChain = new ArrayList<String>();
390 referrerChain.add(url); 411 referrerChain.add(url);
391 referrerChains.add(referrerChain); 412 url = referrerMapping.get(url);
392 return referrerChains; 413 }
393 } 414 return referrerChain;
394
395 for (String referrer : referrers) {
396 List<List<String>> currentReferrerChains = buildReferrerChains(referrer);
397 for (List<String> referrerChain : currentReferrerChains)
398 {
399 referrerChain.add(0, url);
400 referrerChains.add(referrerChain);
401 }
402 }
403 return referrerChains;
404 } 415 }
405 416
406 /** 417 /**
407 * Checks if filtering is enabled. 418 * Checks if filtering is enabled.
408 */ 419 */
409 public boolean isFilteringEnabled() 420 public boolean isFilteringEnabled()
410 { 421 {
411 return filteringEnabled; 422 return filteringEnabled;
412 } 423 }
413 424
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 Log.e(TAG, e.getMessage(), e); 539 Log.e(TAG, e.getMessage(), e);
529 } 540 }
530 541
531 // Set crash handler 542 // Set crash handler
532 Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(this)); 543 Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(this));
533 544
534 // Initiate update check 545 // Initiate update check
535 scheduleUpdater(0); 546 scheduleUpdater(0);
536 } 547 }
537 } 548 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld