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-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 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.IOException; | 20 import java.io.IOException; |
21 import java.io.StringReader; | 21 import java.io.StringReader; |
| 22 import java.lang.ref.WeakReference; |
22 import java.util.ArrayList; | 23 import java.util.ArrayList; |
23 import java.util.HashMap; | 24 import java.util.HashMap; |
| 25 import java.util.Iterator; |
24 import java.util.List; | 26 import java.util.List; |
25 import java.util.concurrent.ConcurrentHashMap; | 27 import java.util.concurrent.ConcurrentHashMap; |
26 import java.util.concurrent.Semaphore; | 28 import java.util.concurrent.Semaphore; |
27 | 29 |
28 import org.mozilla.gecko.util.NativeJSObject; | 30 import org.mozilla.gecko.util.NativeJSObject; |
| 31 import org.mozilla.gecko.util.ThreadUtils; |
29 import org.xmlpull.v1.XmlPullParser; | 32 import org.xmlpull.v1.XmlPullParser; |
30 import org.xmlpull.v1.XmlPullParserException; | 33 import org.xmlpull.v1.XmlPullParserException; |
31 | 34 |
32 import android.util.Log; | 35 import android.util.Log; |
33 import android.util.Xml; | 36 import android.util.Xml; |
34 | 37 |
35 final class SubscriptionContainer implements AdblockPlusApiCallback | 38 final class SubscriptionContainer implements AdblockPlusApiCallback |
36 { | 39 { |
37 private static final String TAG = SubscriptionContainer.class.getName(); | 40 private static final String TAG = SubscriptionContainer.class.getName(); |
38 private final ConcurrentHashMap<String, Boolean> enableState = new ConcurrentH
ashMap<String, Boolean>(); | 41 private final ConcurrentHashMap<String, Boolean> enableState = new ConcurrentH
ashMap<>(); |
39 private final Semaphore entriesReady = new Semaphore(0); | 42 private final Semaphore entriesReady = new Semaphore(0); |
40 private final List<SubscriptionContainer.Subscription> entries = new ArrayList
<SubscriptionContainer.Subscription>(); | 43 private final List<SubscriptionContainer.Subscription> entries = new ArrayList
<>(); |
41 private final HashMap<String, SubscriptionContainer.Subscription> urlMap = new
HashMap<String, SubscriptionContainer.Subscription>(); | 44 private final HashMap<String, SubscriptionContainer.Subscription> urlMap = new
HashMap<>(); |
| 45 private final List<WeakReference<SubscriptionListener>> subscriptionListeners
= new ArrayList<>(); |
42 | 46 |
43 private SubscriptionContainer() | 47 private SubscriptionContainer() |
44 { | 48 { |
45 // prevent external instantiation | 49 // prevent external instantiation |
46 } | 50 } |
47 | 51 |
48 public final static SubscriptionContainer create() | 52 public final static SubscriptionContainer create() |
49 { | 53 { |
50 return create(true); | 54 return create(true); |
51 } | 55 } |
(...skipping 28 matching lines...) Expand all Loading... |
80 this, | 84 this, |
81 SubscriptionChangeAction.Mode.QUERY_SUBSCRIPTION_ENABLED); | 85 SubscriptionChangeAction.Mode.QUERY_SUBSCRIPTION_ENABLED); |
82 } | 86 } |
83 | 87 |
84 this.entriesReady.acquireUninterruptibly(this.entries.size()); | 88 this.entriesReady.acquireUninterruptibly(this.entries.size()); |
85 } | 89 } |
86 } | 90 } |
87 | 91 |
88 public List<SubscriptionContainer.Subscription> getSubscriptions(boolean enabl
ed) | 92 public List<SubscriptionContainer.Subscription> getSubscriptions(boolean enabl
ed) |
89 { | 93 { |
90 final List<SubscriptionContainer.Subscription> ret = new ArrayList<Subscript
ionContainer.Subscription>(); | 94 final List<SubscriptionContainer.Subscription> ret = new ArrayList<>(); |
91 for (final SubscriptionContainer.Subscription e : this.entries) | 95 for (final SubscriptionContainer.Subscription e : this.entries) |
92 { | 96 { |
93 if (this.isSubscriptionListed(e.url) == enabled) | 97 if (this.isSubscriptionListed(e.url) == enabled) |
94 { | 98 { |
95 ret.add(e); | 99 ret.add(e); |
96 } | 100 } |
97 } | 101 } |
98 return ret; | 102 return ret; |
99 } | 103 } |
100 | 104 |
(...skipping 13 matching lines...) Expand all Loading... |
114 SubscriptionChangeAction.Mode.ENABLE_SUBSCRIPTION); | 118 SubscriptionChangeAction.Mode.ENABLE_SUBSCRIPTION); |
115 } | 119 } |
116 else | 120 else |
117 { | 121 { |
118 SubscriptionChangeAction.post(e, SubscriptionPreferenceCategory.subscrip
tionContainer, | 122 SubscriptionChangeAction.post(e, SubscriptionPreferenceCategory.subscrip
tionContainer, |
119 SubscriptionChangeAction.Mode.DISABLE_SUBSCRIPTION); | 123 SubscriptionChangeAction.Mode.DISABLE_SUBSCRIPTION); |
120 } | 124 } |
121 } | 125 } |
122 } | 126 } |
123 | 127 |
| 128 public void addSubscriptionListener(SubscriptionListener listener) |
| 129 { |
| 130 final Iterator<WeakReference<SubscriptionListener>> iterator = this.subscrip
tionListeners.iterator(); |
| 131 boolean shouldAddListener = true; |
| 132 |
| 133 while (iterator.hasNext()) |
| 134 { |
| 135 final SubscriptionListener subscriptionListener = iterator.next().get(); |
| 136 if (subscriptionListener != null) |
| 137 { |
| 138 if (subscriptionListener.equals(listener)) |
| 139 { |
| 140 shouldAddListener = false; |
| 141 } |
| 142 } |
| 143 else |
| 144 { |
| 145 iterator.remove(); |
| 146 } |
| 147 } |
| 148 |
| 149 if (shouldAddListener) |
| 150 { |
| 151 this.subscriptionListeners.add(new WeakReference<>(listener)); |
| 152 } |
| 153 } |
| 154 |
| 155 public void removeSubscriptionListener(SubscriptionListener listener) |
| 156 { |
| 157 this.subscriptionListeners.remove(listener); |
| 158 } |
| 159 |
124 @Override | 160 @Override |
125 public void onApiRequestSucceeded(NativeJSObject jsObject) | 161 public void onApiRequestSucceeded(NativeJSObject jsObject) |
126 { | 162 { |
127 final XmlPullParser parser = Xml.newPullParser(); | 163 final XmlPullParser parser = Xml.newPullParser(); |
128 try | 164 try |
129 { | 165 { |
130 parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); | 166 parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); |
131 parser.setInput(new StringReader(AddOnBridge.getStringFromJsObject(jsObjec
t, "value", ""))); | 167 parser.setInput(new StringReader(AddOnBridge.getStringFromJsObject(jsObjec
t, "value", ""))); |
132 parser.nextTag(); | 168 parser.nextTag(); |
133 parser.require(XmlPullParser.START_TAG, null, "subscriptions"); | 169 parser.require(XmlPullParser.START_TAG, null, "subscriptions"); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 try | 263 try |
228 { | 264 { |
229 this.parent.enableState.put(this.subscription.url, | 265 this.parent.enableState.put(this.subscription.url, |
230 Boolean.valueOf(AddOnBridge.getBooleanFromJsObject(jsObject, "va
lue", false))); | 266 Boolean.valueOf(AddOnBridge.getBooleanFromJsObject(jsObject, "va
lue", false))); |
231 } | 267 } |
232 finally | 268 finally |
233 { | 269 { |
234 this.parent.entriesReady.release(); | 270 this.parent.entriesReady.release(); |
235 } | 271 } |
236 break; | 272 break; |
| 273 case ENABLE_SUBSCRIPTION: |
| 274 case DISABLE_SUBSCRIPTION: |
| 275 this.parent.enableState.put(this.subscription.url, this.mode == Mode.E
NABLE_SUBSCRIPTION); |
| 276 final Iterator<WeakReference<SubscriptionListener>> iterator = this.pa
rent.subscriptionListeners.iterator(); |
| 277 |
| 278 while (iterator.hasNext()) |
| 279 { |
| 280 final SubscriptionListener listener = iterator.next().get(); |
| 281 if (listener != null) |
| 282 { |
| 283 ThreadUtils.postToUiThread(new Runnable() |
| 284 { |
| 285 @Override |
| 286 public void run() |
| 287 { |
| 288 listener.onSubscriptionUpdated(); |
| 289 } |
| 290 }); |
| 291 } |
| 292 else |
| 293 { |
| 294 iterator.remove(); |
| 295 } |
| 296 } |
| 297 break; |
237 default: | 298 default: |
238 break; | 299 break; |
239 } | 300 } |
240 } | 301 } |
241 | 302 |
242 @Override | 303 @Override |
243 public void onApiRequestFailed(String errorMessage) | 304 public void onApiRequestFailed(String errorMessage) |
244 { | 305 { |
245 switch (this.mode) | 306 switch (this.mode) |
246 { | 307 { |
(...skipping 23 matching lines...) Expand all Loading... |
270 this.specialization = specialization; | 331 this.specialization = specialization; |
271 this.url = url; | 332 this.url = url; |
272 } | 333 } |
273 | 334 |
274 @Override | 335 @Override |
275 public String toString() | 336 public String toString() |
276 { | 337 { |
277 return this.specialization + " (" + this.title + ") @ " + this.url; | 338 return this.specialization + " (" + this.title + ") @ " + this.url; |
278 } | 339 } |
279 } | 340 } |
| 341 |
| 342 public interface SubscriptionListener |
| 343 { |
| 344 void onSubscriptionUpdated(); |
| 345 } |
280 } | 346 } |
OLD | NEW |