/*
* 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.imagepipeline.producers;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
import java.util.List;
import com.facebook.common.internal.Lists;
import com.facebook.common.internal.Preconditions;
import com.facebook.common.internal.VisibleForTesting;
import com.facebook.imagepipeline.common.Priority;
import com.facebook.imagepipeline.request.ImageRequest;
/**
* ProducerContext that allows the client to cancel an image request in-flight.
*/
@ThreadSafe
public class SettableProducerContext implements ProducerContext {
private final ImageRequest mImageRequest;
private final String mId;
private final ProducerListener mProducerListener;
private final Object mCallerContext;
private final ImageRequest.RequestLevel mLowestPermittedRequestLevel;
@GuardedBy("this")
private final List<ProducerContextCallbacks> mCallbacks;
@GuardedBy("this")
private boolean mIsCancelled;
@GuardedBy("this")
private boolean mIsPrefetch;
@GuardedBy("this")
private Priority mPriority;
@GuardedBy("this")
private boolean mIsIntermediateResultExpected;
public SettableProducerContext(
ImageRequest imageRequest,
String id,
ProducerListener producerListener,
Object callerContext,
ImageRequest.RequestLevel lowestPermittedRequestLevel,
boolean isPrefetch,
boolean isIntermediateResultExpected,
Priority priority) {
mImageRequest = Preconditions.checkNotNull(imageRequest);
mId = Preconditions.checkNotNull(id);
mProducerListener = Preconditions.checkNotNull(producerListener);
mCallerContext = callerContext;
mLowestPermittedRequestLevel = Preconditions.checkNotNull(lowestPermittedRequestLevel);
mIsPrefetch = isPrefetch;
mIsIntermediateResultExpected = isIntermediateResultExpected;
mPriority = priority;
mIsCancelled = false;
mCallbacks = Lists.newArrayList();
}
@Override
public ImageRequest getImageRequest() {
return mImageRequest;
}
@Override
public String getId() {
return mId;
}
@Override
public ProducerListener getListener() {
return mProducerListener;
}
@Override
public Object getCallerContext() {
return mCallerContext;
}
@Override
public ImageRequest.RequestLevel getLowestPermittedRequestLevel() {
return mLowestPermittedRequestLevel;
}
@Override
public synchronized boolean isPrefetch() {
return mIsPrefetch;
}
@Override
public synchronized Priority getPriority() {
return mPriority;
}
@Override
public synchronized boolean isIntermediateResultExpected() {
return mIsIntermediateResultExpected;
}
@Override
public void addCallbacks(ProducerContextCallbacks callbacks) {
boolean cancelImmediately = false;
synchronized (this) {
mCallbacks.add(callbacks);
if (mIsCancelled) {
cancelImmediately = true;
}
}
if (cancelImmediately) {
callbacks.onCancellationRequested();
}
}
/**
* Cancels the request processing.
*/
public void cancel() {
List<ProducerContextCallbacks> callbacks = null;
synchronized (this) {
if (!mIsCancelled) {
mIsCancelled = true;
callbacks = Lists.newArrayList(mCallbacks);
}
}
if (callbacks != null) {
for (ProducerContextCallbacks callback : callbacks) {
callback.onCancellationRequested();
}
}
}
/**
* Set whether the request is a prefetch request or not.
* @param isPrefetch
*/
public void setIsPrefetch(boolean isPrefetch) {
List<ProducerContextCallbacks> callbacks = null;
synchronized (this) {
if (mIsPrefetch != isPrefetch) {
mIsPrefetch = isPrefetch;
callbacks = Lists.newArrayList(mCallbacks);
}
}
if (callbacks != null) {
for (ProducerContextCallbacks callback : callbacks) {
callback.onIsPrefetchChanged();
}
}
}
/**
* Set whether intermediate result is expected or not
* @param isIntermediateResultExpected
*/
public void setIsIntermediateResultExpected(boolean isIntermediateResultExpected) {
List<ProducerContextCallbacks> callbacks = null;
synchronized (this) {
if (mIsIntermediateResultExpected != isIntermediateResultExpected) {
mIsIntermediateResultExpected = isIntermediateResultExpected;
callbacks = Lists.newArrayList(mCallbacks);
}
}
if (callbacks != null) {
for (ProducerContextCallbacks callback : callbacks) {
callback.onIsIntermediateResultExpectedChanged();
}
}
}
/**
* Set the priority of the request
* @param priority
*/
public void setPriority(Priority priority) {
List<ProducerContextCallbacks> callbacks = null;
synchronized (this) {
if (mPriority != priority) {
mPriority = priority;
callbacks = Lists.newArrayList(mCallbacks);
}
}
if (callbacks != null) {
for (ProducerContextCallbacks callback : callbacks) {
callback.onPriorityChanged();
}
}
}
@VisibleForTesting
synchronized boolean isCancelled() {
return mIsCancelled;
}
}