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 29 matching lines...) Expand all Loading... |
40 import java.util.TreeSet; | 40 import java.util.TreeSet; |
41 import java.util.concurrent.LinkedBlockingQueue; | 41 import java.util.concurrent.LinkedBlockingQueue; |
42 import java.util.concurrent.TimeUnit; | 42 import java.util.concurrent.TimeUnit; |
43 import java.util.concurrent.locks.ReentrantLock; | 43 import java.util.concurrent.locks.ReentrantLock; |
44 | 44 |
45 import org.adblockplus.adblockplussbrowser.R; | 45 import org.adblockplus.adblockplussbrowser.R; |
46 import org.adblockplus.sbrowser.contentblocker.util.ConnectivityUtils; | 46 import org.adblockplus.sbrowser.contentblocker.util.ConnectivityUtils; |
47 import org.adblockplus.sbrowser.contentblocker.util.SharedPrefsUtils; | 47 import org.adblockplus.sbrowser.contentblocker.util.SharedPrefsUtils; |
48 import org.adblockplus.sbrowser.contentblocker.util.SubscriptionUtils; | 48 import org.adblockplus.sbrowser.contentblocker.util.SubscriptionUtils; |
49 | 49 |
| 50 import android.app.job.JobInfo; |
| 51 import android.app.job.JobScheduler; |
| 52 import android.content.ComponentName; |
50 import android.content.Context; | 53 import android.content.Context; |
51 import android.content.Intent; | 54 import android.content.Intent; |
52 import android.content.pm.PackageInfo; | 55 import android.content.pm.PackageInfo; |
53 import android.content.pm.PackageManager; | 56 import android.content.pm.PackageManager; |
54 import android.content.pm.ResolveInfo; | 57 import android.content.pm.ResolveInfo; |
55 import android.net.Uri; | 58 import android.net.Uri; |
56 import android.os.Handler; | 59 import android.os.Handler; |
57 import android.os.Looper; | 60 import android.os.Looper; |
| 61 import android.os.PersistableBundle; |
58 import android.text.TextUtils; | 62 import android.text.TextUtils; |
59 import android.text.format.DateUtils; | 63 import android.text.format.DateUtils; |
60 import android.util.Log; | 64 import android.util.Log; |
61 import android.widget.Toast; | 65 import android.widget.Toast; |
62 | 66 |
63 public final class Engine | 67 public final class Engine |
64 { | 68 { |
65 private static final String TAG = Engine.class.getSimpleName(); | 69 private static final String TAG = Engine.class.getSimpleName(); |
66 | 70 |
67 public static final String USER_FILTERS_TITLE = "__filters"; | 71 public static final String USER_FILTERS_TITLE = "__filters"; |
(...skipping 17 matching lines...) Expand all Loading... |
85 private final ReentrantLock accessLock = new ReentrantLock(); | 89 private final ReentrantLock accessLock = new ReentrantLock(); |
86 private DefaultSubscriptions defaultSubscriptions; | 90 private DefaultSubscriptions defaultSubscriptions; |
87 private Subscriptions subscriptions; | 91 private Subscriptions subscriptions; |
88 private JSONPrefs jsonPrefs; | 92 private JSONPrefs jsonPrefs; |
89 private AppInfo appInfo; | 93 private AppInfo appInfo; |
90 private final LinkedBlockingQueue<EngineEvent> engineEvents = new LinkedBlocki
ngQueue<>(); | 94 private final LinkedBlockingQueue<EngineEvent> engineEvents = new LinkedBlocki
ngQueue<>(); |
91 private Thread handlerThread; | 95 private Thread handlerThread; |
92 private Downloader downloader; | 96 private Downloader downloader; |
93 private SubscriptionUpdateCallback subscriptionUpdateCallback; | 97 private SubscriptionUpdateCallback subscriptionUpdateCallback; |
94 private final Context context; | 98 private final Context context; |
| 99 private ComponentName componentName; |
95 private boolean wasFirstRun = false; | 100 private boolean wasFirstRun = false; |
96 private long nextUpdateBroadcast = Long.MAX_VALUE; | 101 private long nextUpdateBroadcast = Long.MAX_VALUE; |
| 102 private int jobId = 0; |
97 | 103 |
98 private Engine(final Context context) | 104 private Engine(final Context context) |
99 { | 105 { |
100 this.context = context; | 106 this.context = context; |
| 107 this.componentName = new ComponentName(context, DownloadJobService.class); |
101 } | 108 } |
102 | 109 |
103 public String getPrefsDefault(final String key) | 110 public String getPrefsDefault(final String key) |
104 { | 111 { |
105 return this.jsonPrefs.getDefaults(key); | 112 return this.jsonPrefs.getDefaults(key); |
106 } | 113 } |
107 | 114 |
108 DefaultSubscriptionInfo getDefaultSubscriptionInfo(final Subscription sub) | 115 DefaultSubscriptionInfo getDefaultSubscriptionInfo(final Subscription sub) |
109 { | 116 { |
110 return this.defaultSubscriptions.getForUrl(sub.getURL()); | 117 return this.defaultSubscriptions.getForUrl(sub.getURL()); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 .openRawResource(R.raw.exceptionrules)) | 425 .openRawResource(R.raw.exceptionrules)) |
419 { | 426 { |
420 final Subscription exceptions = engine.subscriptions.add(Subscription | 427 final Subscription exceptions = engine.subscriptions.add(Subscription |
421 .create(engine.getPrefsDefault(SUBSCRIPTIONS_EXCEPTIONSURL)) | 428 .create(engine.getPrefsDefault(SUBSCRIPTIONS_EXCEPTIONSURL)) |
422 .parseLines(readLines(exceptionsTxt))); | 429 .parseLines(readLines(exceptionsTxt))); |
423 exceptions.putMeta(Subscription.KEY_UPDATE_TIMESTAMP, "0"); | 430 exceptions.putMeta(Subscription.KEY_UPDATE_TIMESTAMP, "0"); |
424 exceptions.setEnabled(true); | 431 exceptions.setEnabled(true); |
425 } | 432 } |
426 Log.d(TAG, "Added and enabled bundled exceptionslist"); | 433 Log.d(TAG, "Added and enabled bundled exceptionslist"); |
427 | 434 |
| 435 // The Notification should be download regularly. |
| 436 // See https://issues.adblockplus.org/ticket/6238 |
| 437 final Subscription notification = engine.subscriptions.add(Subscription |
| 438 .create(Notification.NOTIFICATION_URL)); |
| 439 notification.setEnabled(true); |
| 440 |
428 int additional = 0; | 441 int additional = 0; |
429 for (final Subscription sub : engine.defaultSubscriptions.createSubscripti
ons()) | 442 for (final Subscription sub : engine.defaultSubscriptions.createSubscripti
ons()) |
430 { | 443 { |
431 if (!engine.subscriptions.hasSubscription(sub.getId())) | 444 if (!engine.subscriptions.hasSubscription(sub.getId())) |
432 { | 445 { |
433 additional++; | 446 additional++; |
434 engine.subscriptions.add(sub); | 447 engine.subscriptions.add(sub); |
435 } | 448 } |
436 } | 449 } |
437 | 450 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 final ChangeEnabledStateEvent cese = (ChangeEnabledStateEvent)
event; | 661 final ChangeEnabledStateEvent cese = (ChangeEnabledStateEvent)
event; |
649 Log.d(TAG, "Changing " + cese.id + " to enabled: " + cese.enab
led); | 662 Log.d(TAG, "Changing " + cese.id + " to enabled: " + cese.enab
led); |
650 engine.subscriptions.changeSubscriptionState(cese.id, cese.ena
bled); | 663 engine.subscriptions.changeSubscriptionState(cese.id, cese.ena
bled); |
651 break; | 664 break; |
652 } | 665 } |
653 case DOWNLOAD_FINISHED: | 666 case DOWNLOAD_FINISHED: |
654 { | 667 { |
655 final DownloadFinishedEvent dfe = (DownloadFinishedEvent) even
t; | 668 final DownloadFinishedEvent dfe = (DownloadFinishedEvent) even
t; |
656 Log.d(TAG, "Download finished for '" + dfe.id + "' with respon
se code " | 669 Log.d(TAG, "Download finished for '" + dfe.id + "' with respon
se code " |
657 + dfe.responseCode); | 670 + dfe.responseCode); |
658 this.engine.subscriptions.updateSubscription(dfe.id, dfe.respo
nseCode, | 671 if (SubscriptionUtils.isNotificationSubscription(dfe.id)) |
659 dfe.response, dfe.headers); | 672 { |
| 673 Notification.update(engine.context, dfe.responseCode, dfe.re
sponse, |
| 674 engine.subscriptions.getNotificationDataFile()); |
| 675 } |
| 676 else |
| 677 { |
| 678 this.engine.subscriptions.updateSubscription(dfe.id, dfe.res
ponseCode, |
| 679 dfe.response, dfe.headers); |
| 680 } |
660 break; | 681 break; |
661 } | 682 } |
662 default: | 683 default: |
663 Log.d(TAG, "Unhandled type: " + event.getType()); | 684 Log.d(TAG, "Unhandled type: " + event.getType()); |
664 break; | 685 break; |
665 } | 686 } |
666 } | 687 } |
667 | 688 |
668 final long currentTime = System.currentTimeMillis(); | 689 final long currentTime = System.currentTimeMillis(); |
669 if (currentTime > nextUpdateCheck) | 690 if (currentTime > nextUpdateCheck) |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 if (headers != null) | 774 if (headers != null) |
754 { | 775 { |
755 this.headers.putAll(headers); | 776 this.headers.putAll(headers); |
756 } | 777 } |
757 } | 778 } |
758 } | 779 } |
759 | 780 |
760 public void enqueueDownload(final Subscription sub, final boolean forced, | 781 public void enqueueDownload(final Subscription sub, final boolean forced, |
761 final boolean allowMetered) throws IOException | 782 final boolean allowMetered) throws IOException |
762 { | 783 { |
763 if (sub.getURL() != null && sub.shouldUpdate(forced)) | 784 // For now we want to use JobScheduler only for the Notification download. |
| 785 // See https://issues.adblockplus.org/ticket/6238. |
| 786 if (SubscriptionUtils.isNotificationSubscription(sub.getId())) |
764 { | 787 { |
765 final HashMap<String, String> headers = new HashMap<>(); | 788 if (Notification.shouldUpdate(context)) |
766 if (sub.isMetaDataValid() && sub.isFiltersValid()) | |
767 { | 789 { |
768 final String lastModified = sub.getMeta(Subscription.KEY_HTTP_LAST_MODIF
IED); | 790 scheduleJob(this.createDownloadURL(sub), sub.getId(), allowMetered); |
769 if (!TextUtils.isEmpty(lastModified)) | 791 } |
| 792 } |
| 793 else |
| 794 { |
| 795 if (sub.getURL() != null && sub.shouldUpdate(forced)) |
| 796 { |
| 797 final HashMap<String, String> headers = new HashMap<>(); |
| 798 if (sub.isMetaDataValid() && sub.isFiltersValid()) |
770 { | 799 { |
771 headers.put("If-Modified-Since", lastModified); | 800 final String lastModified = sub.getMeta(Subscription.KEY_HTTP_LAST_MOD
IFIED); |
| 801 if (!TextUtils.isEmpty(lastModified)) |
| 802 { |
| 803 headers.put("If-Modified-Since", lastModified); |
| 804 } |
| 805 final String etag = sub.getMeta(Subscription.KEY_HTTP_ETAG); |
| 806 if (!TextUtils.isEmpty(etag)) |
| 807 { |
| 808 headers.put("If-None-Match", etag); |
| 809 } |
772 } | 810 } |
773 final String etag = sub.getMeta(Subscription.KEY_HTTP_ETAG); | 811 this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId()
, headers, allowMetered); |
774 if (!TextUtils.isEmpty(etag)) | |
775 { | |
776 headers.put("If-None-Match", etag); | |
777 } | |
778 } | 812 } |
779 Log.d(TAG, headers.toString()); | 813 } |
780 this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(),
headers, allowMetered); | 814 } |
| 815 |
| 816 private void scheduleJob(final URL url, final String id, final boolean allowMe
tered) |
| 817 { |
| 818 final JobInfo.Builder builder = new JobInfo.Builder(jobId++, componentName); |
| 819 builder.setRequiredNetworkType(allowMetered |
| 820 ? JobInfo.NETWORK_TYPE_UNMETERED |
| 821 : JobInfo.NETWORK_TYPE_ANY); |
| 822 |
| 823 final PersistableBundle extras = new PersistableBundle(); |
| 824 extras.putString(Notification.KEY_EXTRA_ID, id); |
| 825 extras.putString(Notification.KEY_EXTRA_URL, url.toString()); |
| 826 builder.setExtras(extras); |
| 827 |
| 828 final JobScheduler scheduler = (JobScheduler) context.getSystemService(Conte
xt.JOB_SCHEDULER_SERVICE); |
| 829 if (scheduler != null) |
| 830 { |
| 831 scheduler.schedule(builder.build()); |
781 } | 832 } |
782 } | 833 } |
783 | 834 |
784 public void connectivityChanged() | 835 public void connectivityChanged() |
785 { | 836 { |
786 this.downloader.connectivityChanged(); | 837 this.downloader.connectivityChanged(); |
787 } | 838 } |
788 | 839 |
789 public interface SubscriptionUpdateCallback | 840 public interface SubscriptionUpdateCallback |
790 { | 841 { |
791 void subscriptionUpdateRequested(boolean enabled); | 842 void subscriptionUpdateRequested(boolean enabled); |
792 void subscriptionUpdatedApplied(); | 843 void subscriptionUpdatedApplied(); |
793 } | 844 } |
794 | 845 |
795 public interface SubscriptionAddedCallback | 846 public interface SubscriptionAddedCallback |
796 { | 847 { |
797 void subscriptionAdded(); | 848 void subscriptionAdded(); |
798 } | 849 } |
799 } | 850 } |
OLD | NEW |