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