| 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 | 
| 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.browser; | 18 package org.adblockplus.browser; | 
| 19 | 19 | 
|  | 20 import java.io.BufferedReader; | 
|  | 21 import java.io.InputStreamReader; | 
| 20 import java.io.IOException; | 22 import java.io.IOException; | 
| 21 import java.io.StringReader; |  | 
| 22 import java.lang.ref.WeakReference; | 23 import java.lang.ref.WeakReference; | 
| 23 import java.util.ArrayList; | 24 import java.util.ArrayList; | 
| 24 import java.util.HashMap; | 25 import java.util.HashMap; | 
| 25 import java.util.Iterator; | 26 import java.util.Iterator; | 
| 26 import java.util.List; | 27 import java.util.List; | 
| 27 import java.util.concurrent.ConcurrentHashMap; | 28 import java.util.concurrent.ConcurrentHashMap; | 
| 28 import java.util.concurrent.Semaphore; | 29 import java.util.concurrent.Semaphore; | 
| 29 | 30 | 
| 30 import org.mozilla.gecko.util.GeckoBundle; | 31 import org.mozilla.gecko.util.GeckoBundle; | 
| 31 import org.mozilla.gecko.util.ThreadUtils; | 32 import org.mozilla.gecko.util.ThreadUtils; | 
| 32 import org.xmlpull.v1.XmlPullParser; | 33 import org.xmlpull.v1.XmlPullParser; | 
| 33 import org.xmlpull.v1.XmlPullParserException; | 34 import org.xmlpull.v1.XmlPullParserException; | 
| 34 | 35 | 
|  | 36 import android.content.Context; | 
| 35 import android.util.Log; | 37 import android.util.Log; | 
| 36 import android.util.Xml; | 38 import android.util.Xml; | 
| 37 | 39 | 
| 38 final class SubscriptionContainer implements AdblockPlusApiCallback | 40 final class SubscriptionContainer | 
| 39 { | 41 { | 
| 40   private static final String TAG = SubscriptionContainer.class.getName(); | 42   private static final String TAG = SubscriptionContainer.class.getName(); | 
| 41   private final ConcurrentHashMap<String, Boolean> enableState = new ConcurrentH
     ashMap<>(); | 43   private final ConcurrentHashMap<String, Boolean> enableState = new ConcurrentH
     ashMap<>(); | 
| 42   private final Semaphore entriesReady = new Semaphore(0); | 44   private final Semaphore entriesReady = new Semaphore(0); | 
| 43   private final List<SubscriptionContainer.Subscription> entries = new ArrayList
     <>(); | 45   private final List<SubscriptionContainer.Subscription> entries = new ArrayList
     <>(); | 
| 44   private final HashMap<String, SubscriptionContainer.Subscription> urlMap = new
      HashMap<>(); | 46   private final HashMap<String, SubscriptionContainer.Subscription> urlMap = new
      HashMap<>(); | 
| 45   private final List<WeakReference<SubscriptionListener>> subscriptionListeners 
     = new ArrayList<>(); | 47   private final List<WeakReference<SubscriptionListener>> subscriptionListeners 
     = new ArrayList<>(); | 
| 46 | 48 | 
| 47   private SubscriptionContainer() | 49   // prevent external instantiation | 
|  | 50   private SubscriptionContainer(final Context context) | 
| 48   { | 51   { | 
| 49     // prevent external instantiation | 52       loadSubscriptions(context); | 
| 50   } | 53   } | 
| 51 | 54 | 
| 52   public final static SubscriptionContainer create() | 55   public final static SubscriptionContainer create(Context context) | 
| 53   { | 56   { | 
| 54     return create(true); | 57     return create(context, true); | 
| 55   } | 58   } | 
| 56 | 59 | 
| 57   public final static SubscriptionContainer create(final boolean refresh) | 60   public final static SubscriptionContainer create(Context context, final boolea
     n refresh) | 
| 58   { | 61   { | 
| 59     final SubscriptionContainer sc = new SubscriptionContainer(); | 62     final SubscriptionContainer sc = new SubscriptionContainer(context); | 
| 60     AddOnBridge.queryValue("subscriptionsXml", sc); |  | 
| 61     sc.entriesReady.acquireUninterruptibly(); |  | 
| 62 | 63 | 
| 63     for (final SubscriptionContainer.Subscription e : sc.entries) | 64     for (final SubscriptionContainer.Subscription e : sc.entries) | 
| 64     { | 65     { | 
| 65       sc.urlMap.put(e.url, e); | 66       sc.urlMap.put(e.url, e); | 
| 66       sc.enableState.put(e.url, Boolean.FALSE); | 67       sc.enableState.put(e.url, Boolean.FALSE); | 
| 67     } | 68     } | 
| 68 | 69 | 
| 69     if (refresh) | 70     if (refresh) | 
| 70     { | 71     { | 
| 71       sc.refresh(); | 72       sc.refresh(); | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 145         iterator.remove(); | 146         iterator.remove(); | 
| 146       } | 147       } | 
| 147     } | 148     } | 
| 148 | 149 | 
| 149     if (shouldAddListener) | 150     if (shouldAddListener) | 
| 150     { | 151     { | 
| 151       this.subscriptionListeners.add(new WeakReference<>(listener)); | 152       this.subscriptionListeners.add(new WeakReference<>(listener)); | 
| 152     } | 153     } | 
| 153   } | 154   } | 
| 154 | 155 | 
| 155   @Override | 156   private void loadSubscriptions(Context context) | 
| 156   public void onApiRequestSucceeded(GeckoBundle bundle) |  | 
| 157   { | 157   { | 
|  | 158 | 
| 158     final XmlPullParser parser = Xml.newPullParser(); | 159     final XmlPullParser parser = Xml.newPullParser(); | 
| 159     try | 160     try | 
| 160     { | 161     { | 
|  | 162       final BufferedReader reader = new BufferedReader(new InputStreamReader( | 
|  | 163               context.getAssets().open("extensions/subscriptions.xml"))); | 
|  | 164 | 
| 161       parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); | 165       parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); | 
| 162       parser.setInput(new StringReader(bundle.getString("value", ""))); | 166       parser.setInput(reader); | 
| 163       parser.nextTag(); | 167       parser.nextTag(); | 
| 164       parser.require(XmlPullParser.START_TAG, null, "subscriptions"); | 168       parser.require(XmlPullParser.START_TAG, null, "subscriptions"); | 
| 165       while (parser.next() != XmlPullParser.END_TAG) | 169       while (parser.next() != XmlPullParser.END_TAG) | 
| 166       { | 170       { | 
| 167         if (parser.getEventType() != XmlPullParser.START_TAG) | 171         if (parser.getEventType() != XmlPullParser.START_TAG) | 
| 168         { | 172         { | 
| 169           continue; | 173           continue; | 
| 170         } | 174         } | 
| 171         if ("subscription".equals(parser.getName())) | 175         if ("subscription".equals(parser.getName())) | 
| 172         { | 176         { | 
| 173           final String title = parser.getAttributeValue(null, "title"); | 177           final String title = parser.getAttributeValue(null, "title"); | 
| 174           final String specialization = parser.getAttributeValue(null, "speciali
     zation"); | 178           final String specialization = parser.getAttributeValue(null, "speciali
     zation"); | 
| 175           final String url = parser.getAttributeValue(null, "url"); | 179           final String url = parser.getAttributeValue(null, "url"); | 
| 176           this.entries.add(new Subscription(title, specialization, url)); | 180           this.entries.add(new Subscription(title, specialization, url)); | 
| 177         } | 181         } | 
| 178         parser.next(); | 182         parser.next(); | 
| 179       } | 183       } | 
| 180     } | 184     } | 
| 181     catch (XmlPullParserException e) | 185     catch (XmlPullParserException e) | 
| 182     { | 186     { | 
| 183       Log.e(TAG, "Failed to parse subscriptions.xml: " + e.getMessage(), e); | 187       Log.e(TAG, "Failed to parse subscriptions.xml: " + e.getMessage(), e); | 
| 184     } | 188     } | 
| 185     catch (IOException e) | 189     catch (IOException e) | 
| 186     { | 190     { | 
| 187       Log.e(TAG, "Failed to parse subscriptions.xml: " + e.getMessage(), e); | 191       Log.e(TAG, "Failed to parse subscriptions.xml: " + e.getMessage(), e); | 
| 188     } | 192     } | 
| 189     finally |  | 
| 190     { |  | 
| 191       this.entriesReady.release(); |  | 
| 192     } |  | 
| 193   } |  | 
| 194 |  | 
| 195   @Override |  | 
| 196   public void onApiRequestFailed(String errorMessage) |  | 
| 197   { |  | 
| 198     Log.e(TAG, "Error: " + errorMessage); |  | 
| 199     this.entriesReady.release(); |  | 
| 200   } | 193   } | 
| 201 | 194 | 
| 202   private static class SubscriptionChangeAction implements AdblockPlusApiCallbac
     k | 195   private static class SubscriptionChangeAction implements AdblockPlusApiCallbac
     k | 
| 203   { | 196   { | 
| 204     private static final String TAG = SubscriptionContainer.SubscriptionChangeAc
     tion.class.getName(); | 197     private static final String TAG = SubscriptionContainer.SubscriptionChangeAc
     tion.class.getName(); | 
| 205 | 198 | 
| 206     private final SubscriptionContainer.Subscription subscription; | 199     private final SubscriptionContainer.Subscription subscription; | 
| 207     private final SubscriptionContainer parent; | 200     private final SubscriptionContainer parent; | 
| 208     private final SubscriptionChangeAction.Mode mode; | 201     private final SubscriptionChangeAction.Mode mode; | 
| 209 | 202 | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 228         final SubscriptionChangeAction.Mode mode) | 221         final SubscriptionChangeAction.Mode mode) | 
| 229     { | 222     { | 
| 230       return new SubscriptionChangeAction(subscription, parent, mode).post(); | 223       return new SubscriptionChangeAction(subscription, parent, mode).post(); | 
| 231     } | 224     } | 
| 232 | 225 | 
| 233     public SubscriptionContainer.SubscriptionChangeAction post() | 226     public SubscriptionContainer.SubscriptionChangeAction post() | 
| 234     { | 227     { | 
| 235       switch (this.mode) | 228       switch (this.mode) | 
| 236       { | 229       { | 
| 237         case QUERY_SUBSCRIPTION_ENABLED: | 230         case QUERY_SUBSCRIPTION_ENABLED: | 
| 238           AddOnBridge.querySubscriptionListStatus(this.subscription.url, this); | 231           ExtensionBridge.querySubscriptionListStatus(this.subscription.url, thi
     s); | 
| 239           break; | 232           break; | 
| 240         case ENABLE_SUBSCRIPTION: | 233         case ENABLE_SUBSCRIPTION: | 
| 241           AddOnBridge.addSubscription(this.subscription.url, this.subscription.t
     itle, this); | 234           ExtensionBridge.addSubscription(this.subscription.url, this.subscripti
     on.title, this); | 
| 242           break; | 235           break; | 
| 243         case DISABLE_SUBSCRIPTION: | 236         case DISABLE_SUBSCRIPTION: | 
| 244           AddOnBridge.removeSubscription(this.subscription.url, this); | 237           ExtensionBridge.removeSubscription(this.subscription.url, this); | 
| 245           break; | 238           break; | 
| 246         default: | 239         default: | 
| 247           break; | 240           break; | 
| 248       } | 241       } | 
| 249       return this; | 242       return this; | 
| 250     } | 243     } | 
| 251 | 244 | 
| 252     @Override | 245     @Override | 
| 253     public void onApiRequestSucceeded(GeckoBundle bundle) | 246     public void onApiRequestSucceeded(GeckoBundle bundle) | 
| 254     { | 247     { | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 330     public String toString() | 323     public String toString() | 
| 331     { | 324     { | 
| 332       return this.specialization + " (" + this.title + ") @ " + this.url; | 325       return this.specialization + " (" + this.title + ") @ " + this.url; | 
| 333     } | 326     } | 
| 334   } | 327   } | 
| 335 | 328 | 
| 336   public interface SubscriptionListener | 329   public interface SubscriptionListener | 
| 337   { | 330   { | 
| 338     void onSubscriptionUpdated(); | 331     void onSubscriptionUpdated(); | 
| 339   } | 332   } | 
| 340 } | 333 } | 
| OLD | NEW | 
|---|