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 |