| 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 |