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-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 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.sbrowser.contentblocker.engine; | 18 package org.adblockplus.sbrowser.contentblocker.engine; |
19 | 19 |
20 import java.io.BufferedReader; | 20 import java.io.BufferedReader; |
21 import java.io.BufferedWriter; | 21 import java.io.BufferedWriter; |
22 import java.io.File; | 22 import java.io.File; |
23 import java.io.FileOutputStream; | 23 import java.io.FileOutputStream; |
24 import java.io.IOException; | 24 import java.io.IOException; |
25 import java.io.InputStream; | 25 import java.io.InputStream; |
26 import java.io.InputStreamReader; | 26 import java.io.InputStreamReader; |
27 import java.io.OutputStreamWriter; | 27 import java.io.OutputStreamWriter; |
28 import java.io.Writer; | 28 import java.io.Writer; |
| 29 import java.net.URI; |
| 30 import java.net.URISyntaxException; |
29 import java.net.URL; | 31 import java.net.URL; |
30 import java.net.URLEncoder; | 32 import java.net.URLEncoder; |
31 import java.util.ArrayList; | 33 import java.util.ArrayList; |
| 34 import java.util.Collections; |
32 import java.util.HashMap; | 35 import java.util.HashMap; |
33 import java.util.List; | 36 import java.util.List; |
34 import java.util.Map; | 37 import java.util.Map; |
| 38 import java.util.Set; |
| 39 import java.util.TreeSet; |
35 import java.util.concurrent.LinkedBlockingQueue; | 40 import java.util.concurrent.LinkedBlockingQueue; |
36 import java.util.concurrent.TimeUnit; | 41 import java.util.concurrent.TimeUnit; |
37 import java.util.concurrent.locks.ReentrantLock; | 42 import java.util.concurrent.locks.ReentrantLock; |
38 import java.util.regex.Pattern; | 43 import java.util.regex.Pattern; |
39 | 44 |
40 import org.adblockplus.adblockplussbrowser.R; | 45 import org.adblockplus.adblockplussbrowser.R; |
41 | 46 |
42 import android.content.Context; | 47 import android.content.Context; |
43 import android.content.Intent; | 48 import android.content.Intent; |
44 import android.content.SharedPreferences; | 49 import android.content.SharedPreferences; |
(...skipping 25 matching lines...) Expand all Loading... |
70 | 75 |
71 public static final String USER_FILTERS_TITLE = "__filters"; | 76 public static final String USER_FILTERS_TITLE = "__filters"; |
72 public static final String USER_EXCEPTIONS_TITLE = "__exceptions"; | 77 public static final String USER_EXCEPTIONS_TITLE = "__exceptions"; |
73 | 78 |
74 public static final String ACTION_OPEN_SETTINGS = "com.samsung.android.sbrowse
r.contentBlocker.ACTION_SETTING"; | 79 public static final String ACTION_OPEN_SETTINGS = "com.samsung.android.sbrowse
r.contentBlocker.ACTION_SETTING"; |
75 public static final String ACTION_UPDATE = "com.samsung.android.sbrowser.conte
ntBlocker.ACTION_UPDATE"; | 80 public static final String ACTION_UPDATE = "com.samsung.android.sbrowser.conte
ntBlocker.ACTION_UPDATE"; |
76 public static final String EASYLIST_URL = "https://easylist-downloads.adblockp
lus.org/easylist.txt"; | 81 public static final String EASYLIST_URL = "https://easylist-downloads.adblockp
lus.org/easylist.txt"; |
77 | 82 |
78 public static final String SUBSCRIPTIONS_EXCEPTIONSURL = "subscriptions_except
ionsurl"; | 83 public static final String SUBSCRIPTIONS_EXCEPTIONSURL = "subscriptions_except
ionsurl"; |
79 | 84 |
80 private static final String URL_ENCODE_CHARSET = "UTF-8"; | 85 public static final String CHARSET_UTF_8 = "UTF-8"; |
81 private static final String PREFS_KEY_PREVIOUS_VERSION = "key_previous_version
"; | 86 private static final String PREFS_KEY_PREVIOUS_VERSION = "key_previous_version
"; |
82 | 87 |
83 // The value below specifies an interval of [x, 2*x[, where x = | 88 // The value below specifies an interval of [x, 2*x[, where x = |
84 // INITIAL_UPDATE_CHECK_DELAY_SECONDS | 89 // INITIAL_UPDATE_CHECK_DELAY_SECONDS |
85 private static final long INITIAL_UPDATE_CHECK_DELAY_SECONDS = 5; | 90 private static final long INITIAL_UPDATE_CHECK_DELAY_SECONDS = 5; |
86 private static final long UPDATE_CHECK_INTERVAL_MINUTES = 30; | 91 private static final long UPDATE_CHECK_INTERVAL_MINUTES = 30; |
87 private static final long BROADCAST_COMBINATION_DELAY_MILLIS = 2500; | 92 private static final long BROADCAST_COMBINATION_DELAY_MILLIS = 2500; |
88 | 93 |
89 public static final long MILLIS_PER_SECOND = 1000; | 94 public static final long MILLIS_PER_SECOND = 1000; |
90 public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND; | 95 public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 { | 151 { |
147 return activityContext.getPackageManager() | 152 return activityContext.getPackageManager() |
148 .queryIntentActivities(new Intent(ACTION_OPEN_SETTINGS), 0).size() > 0
; | 153 .queryIntentActivities(new Intent(ACTION_OPEN_SETTINGS), 0).size() > 0
; |
149 } | 154 } |
150 catch (final Throwable t) | 155 catch (final Throwable t) |
151 { | 156 { |
152 return false; | 157 return false; |
153 } | 158 } |
154 } | 159 } |
155 | 160 |
156 void requestUpdateBroadcast() | 161 public void requestUpdateBroadcast() |
157 { | 162 { |
158 this.lock(); | 163 this.lock(); |
159 try | 164 try |
160 { | 165 { |
161 this.nextUpdateBroadcast = System.currentTimeMillis() + BROADCAST_COMBINAT
ION_DELAY_MILLIS; | 166 this.nextUpdateBroadcast = System.currentTimeMillis() + BROADCAST_COMBINAT
ION_DELAY_MILLIS; |
162 } | 167 } |
163 finally | 168 finally |
164 { | 169 { |
165 this.unlock(); | 170 this.unlock(); |
166 } | 171 } |
167 } | 172 } |
168 | 173 |
169 private void sendUpdateBroadcast() | 174 private void writeFileAndSendUpdateBroadcast() |
170 { | 175 { |
171 createAndWriteFile(); | 176 createAndWriteFile(); |
172 | 177 |
173 runOnUiThread(new Runnable() | 178 runOnUiThread(new Runnable() |
174 { | 179 { |
175 @Override | 180 @Override |
176 public void run() | 181 public void run() |
177 { | 182 { |
178 final Intent intent = new Intent(); | 183 final Intent intent = new Intent(); |
179 intent.setAction(ACTION_UPDATE); | 184 intent.setAction(ACTION_UPDATE); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 { | 240 { |
236 this.engineEvents.add(new ChangeEnabledStateEvent(id, enabled)); | 241 this.engineEvents.add(new ChangeEnabledStateEvent(id, enabled)); |
237 } | 242 } |
238 | 243 |
239 void downloadFinished(final String id, final int responseCode, final String re
sponse, | 244 void downloadFinished(final String id, final int responseCode, final String re
sponse, |
240 final Map<String, String> headers) | 245 final Map<String, String> headers) |
241 { | 246 { |
242 this.engineEvents.add(new DownloadFinishedEvent(id, responseCode, response,
headers)); | 247 this.engineEvents.add(new DownloadFinishedEvent(id, responseCode, response,
headers)); |
243 } | 248 } |
244 | 249 |
245 public void createAndWriteFile() | 250 private void createAndWriteFile() |
246 { | 251 { |
247 this.lock(); | 252 this.lock(); |
248 try | 253 try |
249 { | 254 { |
250 Log.d(TAG, "Writing filters..."); | 255 Log.d(TAG, "Writing filters..."); |
251 final File filterFile = this.subscriptions.createAndWriteFile(); | 256 final File filterFile = this.subscriptions.createAndWriteFile(); |
| 257 writeWhitelistedWebsites(this.serviceContext, filterFile); |
252 | 258 |
253 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferen
ces(this.serviceContext); | 259 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferen
ces(this.serviceContext); |
254 final String key = this.serviceContext.getString(R.string.key_cached_filte
r_path); | 260 final String key = this.serviceContext.getString(R.string.key_cached_filte
r_path); |
255 prefs.edit().putString(key, filterFile.getAbsolutePath()).commit(); | 261 prefs.edit().putString(key, filterFile.getAbsolutePath()).commit(); |
256 | 262 |
257 Log.d(TAG, "Cleaning up cache..."); | 263 Log.d(TAG, "Cleaning up cache..."); |
258 final File dummyFile = getDummyFilterFile(this.serviceContext); | 264 final File dummyFile = getDummyFilterFile(this.serviceContext); |
259 final File[] cacheDirFiles = getFilterCacheDir(this.serviceContext).listFi
les(); | 265 final File[] cacheDirFiles = getFilterCacheDir(this.serviceContext).listFi
les(); |
260 if (cacheDirFiles != null) | 266 if (cacheDirFiles != null) |
261 { | 267 { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 424 } |
419 } | 425 } |
420 | 426 |
421 Log.d(TAG, "Added " + additional + " additional default/built-in subscript
ions"); | 427 Log.d(TAG, "Added " + additional + " additional default/built-in subscript
ions"); |
422 engine.subscriptions.persistSubscriptions(); | 428 engine.subscriptions.persistSubscriptions(); |
423 } | 429 } |
424 | 430 |
425 final File cachedFilterFile = getCachedFilterFile(context); | 431 final File cachedFilterFile = getCachedFilterFile(context); |
426 if (cachedFilterFile == null || !cachedFilterFile.exists()) | 432 if (cachedFilterFile == null || !cachedFilterFile.exists()) |
427 { | 433 { |
428 engine.sendUpdateBroadcast(); | 434 engine.writeFileAndSendUpdateBroadcast(); |
429 } | 435 } |
430 | 436 |
431 engine.handlerThread = new Thread(new EventHandler(engine)); | 437 engine.handlerThread = new Thread(new EventHandler(engine)); |
432 engine.handlerThread.setDaemon(true); | 438 engine.handlerThread.setDaemon(true); |
433 engine.handlerThread.start(); | 439 engine.handlerThread.start(); |
434 | 440 |
435 engine.downloader = Downloader.create(context, engine); | 441 engine.downloader = Downloader.create(context, engine); |
436 | 442 |
437 return engine; | 443 return engine; |
438 } | 444 } |
439 | 445 |
440 public static String readFileAsString(InputStream instream) throws IOException | 446 public static String readFileAsString(InputStream instream) throws IOException |
441 { | 447 { |
442 final StringBuilder sb = new StringBuilder(); | 448 final StringBuilder sb = new StringBuilder(); |
443 final BufferedReader r = new BufferedReader(new InputStreamReader(instream,
"UTF-8")); | 449 final BufferedReader r = new BufferedReader(new InputStreamReader(instream,
CHARSET_UTF_8)); |
444 for (int ch = r.read(); ch != -1; ch = r.read()) | 450 for (int ch = r.read(); ch != -1; ch = r.read()) |
445 { | 451 { |
446 sb.append((char) ch); | 452 sb.append((char) ch); |
447 } | 453 } |
448 return sb.toString(); | 454 return sb.toString(); |
449 } | 455 } |
450 | 456 |
451 public static List<String> readLines(InputStream instream) throws IOException | 457 public static List<String> readLines(InputStream instream) throws IOException |
452 { | 458 { |
453 final ArrayList<String> list = new ArrayList<String>(); | 459 final ArrayList<String> list = new ArrayList<String>(); |
454 final BufferedReader r = new BufferedReader(new InputStreamReader(instream,
"UTF-8")); | 460 final BufferedReader r = new BufferedReader(new InputStreamReader(instream,
CHARSET_UTF_8)); |
455 for (String line = r.readLine(); line != null; line = r.readLine()) | 461 for (String line = r.readLine(); line != null; line = r.readLine()) |
456 { | 462 { |
457 list.add(line); | 463 list.add(line); |
458 } | 464 } |
459 return list; | 465 return list; |
460 } | 466 } |
461 | 467 |
462 public static File getOrCreateCachedFilterFile(Context context) throws IOExcep
tion | 468 public static File getOrCreateCachedFilterFile(Context context) throws IOExcep
tion |
463 { | 469 { |
464 final File cachedFilterFile = getCachedFilterFile(context); | 470 final File cachedFilterFile = getCachedFilterFile(context); |
465 if (cachedFilterFile != null && cachedFilterFile.exists()) | 471 if (cachedFilterFile != null && cachedFilterFile.exists()) |
466 { | 472 { |
467 Log.d(TAG, "Cached filter file found: " + cachedFilterFile); | 473 Log.d(TAG, "Cached filter file found: " + cachedFilterFile); |
468 return cachedFilterFile; | 474 return cachedFilterFile; |
469 } | 475 } |
470 | 476 |
471 Log.d(TAG, "Cached filter file not found. Using dummy filter file"); | 477 Log.d(TAG, "Cached filter file not found. Using dummy filter file"); |
472 final File dummyFilterFile = getDummyFilterFile(context); | 478 final File dummyFilterFile = getDummyFilterFile(context); |
473 if (!dummyFilterFile.exists()) | 479 if (!dummyFilterFile.exists()) |
474 { | 480 { |
475 Log.d(TAG, "Creating dummy filter file..."); | 481 Log.d(TAG, "Creating dummy filter file..."); |
476 dummyFilterFile.getParentFile().mkdirs(); | 482 dummyFilterFile.getParentFile().mkdirs(); |
477 final BufferedWriter writer = new BufferedWriter( | 483 final BufferedWriter writer = new BufferedWriter( |
478 new OutputStreamWriter(new FileOutputStream(dummyFilterFile), "UTF-8")
); | 484 new OutputStreamWriter(new FileOutputStream(dummyFilterFile), CHARSET_
UTF_8)); |
479 try | 485 try |
480 { | 486 { |
481 writeFilterHeaders(writer); | 487 writeFilterHeaders(writer); |
482 } | 488 } |
483 finally | 489 finally |
484 { | 490 { |
485 writer.close(); | 491 writer.close(); |
486 } | 492 } |
487 } | 493 } |
488 return dummyFilterFile; | 494 return dummyFilterFile; |
489 } | 495 } |
490 | 496 |
491 public static void writeFilterHeaders(Writer writer) throws IOException | 497 public static void writeFilterHeaders(Writer writer) throws IOException |
492 { | 498 { |
493 writer.write("[Adblock Plus 2.0]\n"); | 499 writer.write("[Adblock Plus 2.0]\n"); |
494 writer.write("! This file was automatically created.\n"); | 500 writer.write("! This file was automatically created.\n"); |
495 } | 501 } |
496 | 502 |
| 503 private static void writeWhitelistedWebsites(Context context, File filterFile)
throws IOException |
| 504 { |
| 505 Log.d(TAG, "Writing whitelisted websites..."); |
| 506 final SharedPreferences prefs = |
| 507 PreferenceManager.getDefaultSharedPreferences(context.getApplicationCont
ext()); |
| 508 final String key = context.getString(R.string.key_whitelisted_websites); |
| 509 |
| 510 final Set<String> whitelistedWebsites = new TreeSet<String>(); |
| 511 whitelistedWebsites.addAll(prefs.getStringSet(key, Collections.<String>empty
Set())); |
| 512 |
| 513 final BufferedWriter w = new BufferedWriter( |
| 514 new OutputStreamWriter(new FileOutputStream(filterFile, true), CHARSET_U
TF_8)); |
| 515 try |
| 516 { |
| 517 for (final String url : whitelistedWebsites) |
| 518 { |
| 519 try |
| 520 { |
| 521 final URI uri = new URI(url); |
| 522 final String host = uri.getHost() != null ? uri.getHost() : uri.getPat
h(); |
| 523 w.write("@@||" + host + "^$document"); |
| 524 w.write('\n'); |
| 525 } |
| 526 catch (URISyntaxException e) |
| 527 { |
| 528 Log.w(TAG, "Failed to parse whitelisted website: " + url); |
| 529 continue; |
| 530 } |
| 531 } |
| 532 } |
| 533 finally |
| 534 { |
| 535 w.close(); |
| 536 } |
| 537 } |
| 538 |
497 private static File getCachedFilterFile(Context context) | 539 private static File getCachedFilterFile(Context context) |
498 { | 540 { |
499 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreference
s(context); | 541 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreference
s(context); |
500 final String cachedFilterPath = prefs.getString(context.getString(R.string.k
ey_cached_filter_path), null); | 542 final String cachedFilterPath = prefs.getString(context.getString(R.string.k
ey_cached_filter_path), null); |
501 if (cachedFilterPath != null) | 543 if (cachedFilterPath != null) |
502 { | 544 { |
503 return new File(cachedFilterPath); | 545 return new File(cachedFilterPath); |
504 } | 546 } |
505 | 547 |
506 return null; | 548 return null; |
(...skipping 22 matching lines...) Expand all Loading... |
529 if (sub.getURL().getQuery() != null) | 571 if (sub.getURL().getQuery() != null) |
530 { | 572 { |
531 sb.append('&'); | 573 sb.append('&'); |
532 } | 574 } |
533 else | 575 else |
534 { | 576 { |
535 sb.append('?'); | 577 sb.append('?'); |
536 } | 578 } |
537 | 579 |
538 sb.append("addonName="); | 580 sb.append("addonName="); |
539 sb.append(URLEncoder.encode(this.appInfo.addonName, URL_ENCODE_CHARSET)); | 581 sb.append(URLEncoder.encode(this.appInfo.addonName, CHARSET_UTF_8)); |
540 sb.append("&addonVersion="); | 582 sb.append("&addonVersion="); |
541 sb.append(URLEncoder.encode(this.appInfo.addonVersion, URL_ENCODE_CHARSET)); | 583 sb.append(URLEncoder.encode(this.appInfo.addonVersion, CHARSET_UTF_8)); |
542 sb.append("&application="); | 584 sb.append("&application="); |
543 sb.append(URLEncoder.encode(this.appInfo.application, URL_ENCODE_CHARSET)); | 585 sb.append(URLEncoder.encode(this.appInfo.application, CHARSET_UTF_8)); |
544 sb.append("&applicationVersion="); | 586 sb.append("&applicationVersion="); |
545 sb.append(URLEncoder.encode(this.appInfo.applicationVersion, URL_ENCODE_CHAR
SET)); | 587 sb.append(URLEncoder.encode(this.appInfo.applicationVersion, CHARSET_UTF_8))
; |
546 sb.append("&platform="); | 588 sb.append("&platform="); |
547 sb.append(URLEncoder.encode(this.appInfo.platform, URL_ENCODE_CHARSET)); | 589 sb.append(URLEncoder.encode(this.appInfo.platform, CHARSET_UTF_8)); |
548 sb.append("&platformVersion="); | 590 sb.append("&platformVersion="); |
549 sb.append(URLEncoder.encode(this.appInfo.platformVersion, URL_ENCODE_CHARSET
)); | 591 sb.append(URLEncoder.encode(this.appInfo.platformVersion, CHARSET_UTF_8)); |
550 sb.append("&lastVersion="); | 592 sb.append("&lastVersion="); |
551 sb.append(sub.getVersion()); | 593 sb.append(sub.getVersion()); |
552 sb.append("&downloadCount="); | 594 sb.append("&downloadCount="); |
553 final long downloadCount = sub.getDownloadCount(); | 595 final long downloadCount = sub.getDownloadCount(); |
554 if (downloadCount < 5) | 596 if (downloadCount < 5) |
555 { | 597 { |
556 sb.append(downloadCount); | 598 sb.append(downloadCount); |
557 } | 599 } |
558 else | 600 else |
559 { | 601 { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 { | 661 { |
620 nextUpdateCheck = currentTime + UPDATE_CHECK_INTERVAL_MINUTES * MI
LLIS_PER_MINUTE; | 662 nextUpdateCheck = currentTime + UPDATE_CHECK_INTERVAL_MINUTES * MI
LLIS_PER_MINUTE; |
621 | 663 |
622 this.engine.subscriptions.checkForUpdates(); | 664 this.engine.subscriptions.checkForUpdates(); |
623 } | 665 } |
624 | 666 |
625 if (currentTime > this.engine.nextUpdateBroadcast) | 667 if (currentTime > this.engine.nextUpdateBroadcast) |
626 { | 668 { |
627 this.engine.nextUpdateBroadcast = Long.MAX_VALUE; | 669 this.engine.nextUpdateBroadcast = Long.MAX_VALUE; |
628 Log.d(TAG, "Sending update broadcast"); | 670 Log.d(TAG, "Sending update broadcast"); |
629 this.engine.sendUpdateBroadcast(); | 671 this.engine.writeFileAndSendUpdateBroadcast(); |
630 } | 672 } |
631 } | 673 } |
632 finally | 674 finally |
633 { | 675 { |
634 engine.unlock(); | 676 engine.unlock(); |
635 } | 677 } |
636 } | 678 } |
637 catch (final InterruptedException e) | 679 catch (final InterruptedException e) |
638 { | 680 { |
639 Log.d(TAG, "Handler interrupted", e); | 681 Log.d(TAG, "Handler interrupted", e); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 Log.d(TAG, headers.toString()); | 766 Log.d(TAG, headers.toString()); |
725 this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(),
headers); | 767 this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(),
headers); |
726 } | 768 } |
727 } | 769 } |
728 | 770 |
729 public void connectivityChanged() | 771 public void connectivityChanged() |
730 { | 772 { |
731 this.downloader.connectivityChanged(); | 773 this.downloader.connectivityChanged(); |
732 } | 774 } |
733 } | 775 } |
OLD | NEW |