Index: mobile/android/thirdparty/org/adblockplus/browser/SubscriptionContainer.java |
=================================================================== |
--- a/mobile/android/thirdparty/org/adblockplus/browser/SubscriptionContainer.java |
+++ b/mobile/android/thirdparty/org/adblockplus/browser/SubscriptionContainer.java |
@@ -14,36 +14,40 @@ |
* You should have received a copy of the GNU General Public License |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
package org.adblockplus.browser; |
import java.io.IOException; |
import java.io.StringReader; |
+import java.lang.ref.WeakReference; |
import java.util.ArrayList; |
import java.util.HashMap; |
+import java.util.Iterator; |
import java.util.List; |
import java.util.concurrent.ConcurrentHashMap; |
import java.util.concurrent.Semaphore; |
import org.mozilla.gecko.util.NativeJSObject; |
+import org.mozilla.gecko.util.ThreadUtils; |
import org.xmlpull.v1.XmlPullParser; |
import org.xmlpull.v1.XmlPullParserException; |
import android.util.Log; |
import android.util.Xml; |
final class SubscriptionContainer implements AdblockPlusApiCallback |
{ |
private static final String TAG = SubscriptionContainer.class.getName(); |
- private final ConcurrentHashMap<String, Boolean> enableState = new ConcurrentHashMap<String, Boolean>(); |
+ private final ConcurrentHashMap<String, Boolean> enableState = new ConcurrentHashMap<>(); |
private final Semaphore entriesReady = new Semaphore(0); |
- private final List<SubscriptionContainer.Subscription> entries = new ArrayList<SubscriptionContainer.Subscription>(); |
- private final HashMap<String, SubscriptionContainer.Subscription> urlMap = new HashMap<String, SubscriptionContainer.Subscription>(); |
+ private final List<SubscriptionContainer.Subscription> entries = new ArrayList<>(); |
+ private final HashMap<String, SubscriptionContainer.Subscription> urlMap = new HashMap<>(); |
+ private final List<WeakReference<SubscriptionListener>> subscriptionListeners = new ArrayList<>(); |
private SubscriptionContainer() |
{ |
// prevent external instantiation |
} |
public final static SubscriptionContainer create() |
{ |
@@ -82,17 +86,17 @@ final class SubscriptionContainer implem |
} |
this.entriesReady.acquireUninterruptibly(this.entries.size()); |
} |
} |
public List<SubscriptionContainer.Subscription> getSubscriptions(boolean enabled) |
{ |
- final List<SubscriptionContainer.Subscription> ret = new ArrayList<SubscriptionContainer.Subscription>(); |
+ final List<SubscriptionContainer.Subscription> ret = new ArrayList<>(); |
for (final SubscriptionContainer.Subscription e : this.entries) |
{ |
if (this.isSubscriptionListed(e.url) == enabled) |
{ |
ret.add(e); |
} |
} |
return ret; |
@@ -116,16 +120,48 @@ final class SubscriptionContainer implem |
else |
{ |
SubscriptionChangeAction.post(e, SubscriptionPreferenceCategory.subscriptionContainer, |
SubscriptionChangeAction.Mode.DISABLE_SUBSCRIPTION); |
} |
} |
} |
+ public void addSubscriptionListener(SubscriptionListener listener) |
+ { |
+ final Iterator<WeakReference<SubscriptionListener>> iterator = this.subscriptionListeners.iterator(); |
+ boolean shouldAddListener = true; |
+ |
+ while (iterator.hasNext()) |
+ { |
+ final SubscriptionListener subscriptionListener = iterator.next().get(); |
+ if (subscriptionListener != null) |
+ { |
+ if (subscriptionListener.equals(listener)) |
+ { |
+ shouldAddListener = false; |
+ } |
+ } |
+ else |
+ { |
+ iterator.remove(); |
+ } |
+ } |
+ |
+ if (shouldAddListener) |
+ { |
+ this.subscriptionListeners.add(new WeakReference<>(listener)); |
+ } |
+ } |
+ |
+ public void removeSubscriptionListener(SubscriptionListener listener) |
+ { |
+ this.subscriptionListeners.remove(listener); |
+ } |
+ |
@Override |
public void onApiRequestSucceeded(NativeJSObject jsObject) |
{ |
final XmlPullParser parser = Xml.newPullParser(); |
try |
{ |
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); |
parser.setInput(new StringReader(AddOnBridge.getStringFromJsObject(jsObject, "value", ""))); |
@@ -229,16 +265,41 @@ final class SubscriptionContainer implem |
this.parent.enableState.put(this.subscription.url, |
Boolean.valueOf(AddOnBridge.getBooleanFromJsObject(jsObject, "value", false))); |
} |
finally |
{ |
this.parent.entriesReady.release(); |
} |
break; |
+ case ENABLE_SUBSCRIPTION: |
+ case DISABLE_SUBSCRIPTION: |
+ this.parent.enableState.put(this.subscription.url, this.mode == Mode.ENABLE_SUBSCRIPTION); |
+ final Iterator<WeakReference<SubscriptionListener>> iterator = this.parent.subscriptionListeners.iterator(); |
+ |
+ while (iterator.hasNext()) |
+ { |
+ final SubscriptionListener listener = iterator.next().get(); |
+ if (listener != null) |
+ { |
+ ThreadUtils.postToUiThread(new Runnable() |
+ { |
+ @Override |
+ public void run() |
+ { |
+ listener.onSubscriptionUpdated(); |
+ } |
+ }); |
+ } |
+ else |
+ { |
+ iterator.remove(); |
+ } |
+ } |
+ break; |
default: |
break; |
} |
} |
@Override |
public void onApiRequestFailed(String errorMessage) |
{ |
@@ -272,9 +333,13 @@ final class SubscriptionContainer implem |
} |
@Override |
public String toString() |
{ |
return this.specialization + " (" + this.title + ") @ " + this.url; |
} |
} |
+ |
+ public interface SubscriptionListener { |
+ void onSubscriptionUpdated(); |
+ } |
} |