/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.drawee.controller; import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; import java.util.List; import android.graphics.drawable.Animatable; import android.util.Log; import com.facebook.common.internal.Lists; /** * Listener that forwards controller events to multiple listeners. */ @ThreadSafe public class ForwardingControllerListener<INFO> implements ControllerListener<INFO> { private static final String TAG = "ForwardingControllerListener"; private final List<ControllerListener<? super INFO>> mListeners = Lists.newArrayListWithCapacity(2); public ForwardingControllerListener() { } public static <INFO> ForwardingControllerListener<INFO> create() { return new ForwardingControllerListener<INFO>(); } public static <INFO> ForwardingControllerListener<INFO> of( ControllerListener<? super INFO> listener) { ForwardingControllerListener<INFO> forwarder = create(); forwarder.addListener(listener); return forwarder; } public static <INFO> ForwardingControllerListener<INFO> of( ControllerListener<? super INFO> listener1, ControllerListener<? super INFO> listener2) { ForwardingControllerListener<INFO> forwarder = create(); forwarder.addListener(listener1); forwarder.addListener(listener2); return forwarder; } public synchronized void addListener(ControllerListener<? super INFO> listener) { mListeners.add(listener); } public synchronized void removeListener(ControllerListener<? super INFO> listener) { mListeners.remove(listener); } public synchronized void clearListeners() { mListeners.clear(); } private synchronized void onException(String message, Throwable t) { Log.e(TAG, message, t); } @Override public synchronized void onSubmit(String id, Object callerContext) { final int numberOfListeners = mListeners.size(); for (int i = 0; i < numberOfListeners; ++i) { ControllerListener<? super INFO> listener = mListeners.get(i); try { listener.onSubmit(id, callerContext); } catch (Exception exception) { // Don't punish the other listeners if we're given a bad one. onException("InternalListener exception in onSubmit", exception); } } } @Override public synchronized void onFinalImageSet( String id, @Nullable INFO imageInfo, @Nullable Animatable animatable) { final int numberOfListeners = mListeners.size(); for (int i = 0; i < numberOfListeners; ++i) { ControllerListener<? super INFO> listener = mListeners.get(i); try { listener.onFinalImageSet(id, imageInfo, animatable); } catch (Exception exception) { // Don't punish the other listeners if we're given a bad one. onException("InternalListener exception in onFinalImageSet", exception); } } } @Override public void onIntermediateImageSet(String id, @Nullable INFO imageInfo) { final int numberOfListeners = mListeners.size(); for (int i = 0; i < numberOfListeners; ++i) { ControllerListener<? super INFO> listener = mListeners.get(i); try { listener.onIntermediateImageSet(id, imageInfo); } catch (Exception exception) { // Don't punish the other listeners if we're given a bad one. onException("InternalListener exception in onIntermediateImageSet", exception); } } } @Override public void onIntermediateImageFailed(String id, Throwable throwable) { final int numberOfListeners = mListeners.size(); for (int i = 0; i < numberOfListeners; ++i) { ControllerListener<? super INFO> listener = mListeners.get(i); try { listener.onIntermediateImageFailed(id, throwable); } catch (Exception exception) { // Don't punish the other listeners if we're given a bad one. onException("InternalListener exception in onIntermediateImageFailed", exception); } } } @Override public synchronized void onFailure(String id, Throwable throwable) { final int numberOfListeners = mListeners.size(); for (int i = 0; i < numberOfListeners; ++i) { ControllerListener<? super INFO> listener = mListeners.get(i); try { listener.onFailure(id, throwable); } catch (Exception exception) { // Don't punish the other listeners if we're given a bad one. onException("InternalListener exception in onFailure", exception); } } } @Override public synchronized void onRelease(String id) { final int numberOfListeners = mListeners.size(); for (int i = 0; i < numberOfListeners; ++i) { ControllerListener<? super INFO> listener = mListeners.get(i); try { listener.onRelease(id); } catch (Exception exception) { // Don't punish the other listeners if we're given a bad one. onException("InternalListener exception in onRelease", exception); } } } }