/* * 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.request; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import java.io.File; import android.net.Uri; import com.facebook.common.internal.Objects; import com.facebook.common.media.MediaUtils; import com.facebook.common.util.UriUtil; import com.facebook.imagepipeline.common.ImageDecodeOptions; import com.facebook.imagepipeline.common.Priority; import com.facebook.imagepipeline.common.ResizeOptions; import com.facebook.imagepipeline.common.RotationOptions; import com.facebook.imagepipeline.common.SourceUriType; import com.facebook.imagepipeline.listener.RequestListener; import com.facebook.imageutils.BitmapUtil; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_DATA; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_LOCAL_ASSET; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_LOCAL_CONTENT; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_LOCAL_IMAGE_FILE; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_LOCAL_RESOURCE; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_LOCAL_VIDEO_FILE; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_NETWORK; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_QUALIFIED_RESOURCE; import static com.facebook.imagepipeline.common.SourceUriType.SOURCE_TYPE_UNKNOWN; /** * Immutable object encapsulating everything pipeline has to know about requested image to proceed. */ @Immutable public class ImageRequest { /** Cache choice */ private final CacheChoice mCacheChoice; /** Source Uri */ private final Uri mSourceUri; private final @SourceUriType int mSourceUriType; /** Media variations - useful for potentially providing fallback to an alternative cached image */ private final @Nullable MediaVariations mMediaVariations; /** Source File - for local fetches only, lazily initialized */ private File mSourceFile; /** If set - the client will receive intermediate results */ private final boolean mProgressiveRenderingEnabled; /** If set the client will receive thumbnail previews for local images, before the whole image */ private final boolean mLocalThumbnailPreviewsEnabled; private final ImageDecodeOptions mImageDecodeOptions; /** resize options */ private final @Nullable ResizeOptions mResizeOptions; /** rotation options */ private final RotationOptions mRotationOptions; /** Priority levels of this request. */ private final Priority mRequestPriority; /** Lowest level that is permitted to fetch an image from */ private final RequestLevel mLowestPermittedRequestLevel; /** Whether the disk cache should be used for this request */ private final boolean mIsDiskCacheEnabled; /** Postprocessor to run on the output bitmap. */ private final Postprocessor mPostprocessor; /** Request listener to use for this image request */ private final @Nullable RequestListener mRequestListener; public static ImageRequest fromFile(@Nullable File file) { return (file == null) ? null : ImageRequest.fromUri(UriUtil.getUriForFile(file)); } public static ImageRequest fromUri(@Nullable Uri uri) { return (uri == null) ? null : ImageRequestBuilder.newBuilderWithSource(uri).build(); } public static ImageRequest fromUri(@Nullable String uriString) { return (uriString == null || uriString.length() == 0) ? null : fromUri(Uri.parse(uriString)); } protected ImageRequest(ImageRequestBuilder builder) { mCacheChoice = builder.getCacheChoice(); mSourceUri = builder.getSourceUri(); mSourceUriType = getSourceUriType(mSourceUri); mMediaVariations = builder.getMediaVariations(); mProgressiveRenderingEnabled = builder.isProgressiveRenderingEnabled(); mLocalThumbnailPreviewsEnabled = builder.isLocalThumbnailPreviewsEnabled(); mImageDecodeOptions = builder.getImageDecodeOptions(); mResizeOptions = builder.getResizeOptions(); mRotationOptions = builder.getRotationOptions() == null ? RotationOptions.autoRotate() : builder.getRotationOptions(); mRequestPriority = builder.getRequestPriority(); mLowestPermittedRequestLevel = builder.getLowestPermittedRequestLevel(); mIsDiskCacheEnabled = builder.isDiskCacheEnabled(); mPostprocessor = builder.getPostprocessor(); mRequestListener = builder.getRequestListener(); } public CacheChoice getCacheChoice() { return mCacheChoice; } public Uri getSourceUri() { return mSourceUri; } public @SourceUriType int getSourceUriType() { return mSourceUriType; } public @Nullable MediaVariations getMediaVariations() { return mMediaVariations; } public int getPreferredWidth() { return (mResizeOptions != null) ? mResizeOptions.width : (int) BitmapUtil.MAX_BITMAP_SIZE; } public int getPreferredHeight() { return (mResizeOptions != null) ? mResizeOptions.height : (int) BitmapUtil.MAX_BITMAP_SIZE; } public @Nullable ResizeOptions getResizeOptions() { return mResizeOptions; } public RotationOptions getRotationOptions() { return mRotationOptions; } /** * @deprecated Use {@link #getRotationOptions()} */ @Deprecated public boolean getAutoRotateEnabled() { return mRotationOptions.useImageMetadata(); } public ImageDecodeOptions getImageDecodeOptions() { return mImageDecodeOptions; } public boolean getProgressiveRenderingEnabled() { return mProgressiveRenderingEnabled; } public boolean getLocalThumbnailPreviewsEnabled() { return mLocalThumbnailPreviewsEnabled; } public Priority getPriority() { return mRequestPriority; } public RequestLevel getLowestPermittedRequestLevel() { return mLowestPermittedRequestLevel; } public boolean isDiskCacheEnabled() { return mIsDiskCacheEnabled; } public synchronized File getSourceFile() { if (mSourceFile == null) { mSourceFile = new File(mSourceUri.getPath()); } return mSourceFile; } public @Nullable Postprocessor getPostprocessor() { return mPostprocessor; } public @Nullable RequestListener getRequestListener() { return mRequestListener; } @Override public boolean equals(Object o) { if (!(o instanceof ImageRequest)) { return false; } ImageRequest request = (ImageRequest) o; return Objects.equal(mSourceUri, request.mSourceUri) && Objects.equal(mCacheChoice, request.mCacheChoice) && Objects.equal(mMediaVariations, request.mMediaVariations) && Objects.equal(mSourceFile, request.mSourceFile); } @Override public int hashCode() { return Objects.hashCode(mCacheChoice, mSourceUri, mMediaVariations, mSourceFile); } @Override public String toString() { return Objects.toStringHelper(this) .add("uri", mSourceUri) .add("cacheChoice", mCacheChoice) .add("decodeOptions", mImageDecodeOptions) .add("postprocessor", mPostprocessor) .add("priority", mRequestPriority) .add("resizeOptions", mResizeOptions) .add("rotationOptions", mRotationOptions) .add("mediaVariations", mMediaVariations) .toString(); } /** * An enum describing the cache choice. */ public enum CacheChoice { /* Indicates that this image should go in the small disk cache, if one is being used */ SMALL, /* Default */ DEFAULT } /** * Level down to we are willing to go in order to find an image. E.g., we might only want to go * down to bitmap memory cache, and not check the disk cache or do a full fetch. */ public enum RequestLevel { /* Fetch (from the network or local storage) */ FULL_FETCH(1), /* Disk caching */ DISK_CACHE(2), /* Encoded memory caching */ ENCODED_MEMORY_CACHE(3), /* Bitmap caching */ BITMAP_MEMORY_CACHE(4); private int mValue; private RequestLevel(int value) { mValue = value; } public int getValue() { return mValue; } public static RequestLevel getMax(RequestLevel requestLevel1, RequestLevel requestLevel2) { return requestLevel1.getValue() > requestLevel2.getValue() ? requestLevel1 : requestLevel2; } } /** * This is a utility method which returns the type of Uri * @param uri The Uri to test * @return The type of the given Uri if available or SOURCE_TYPE_UNKNOWN if not */ private static @SourceUriType int getSourceUriType(final Uri uri) { if (uri == null) { return SOURCE_TYPE_UNKNOWN; } if (UriUtil.isNetworkUri(uri)) { return SOURCE_TYPE_NETWORK; } else if (UriUtil.isLocalFileUri(uri)) { if (MediaUtils.isVideo(MediaUtils.extractMime(uri.getPath()))) { return SOURCE_TYPE_LOCAL_VIDEO_FILE; } else { return SOURCE_TYPE_LOCAL_IMAGE_FILE; } } else if (UriUtil.isLocalContentUri(uri)) { return SOURCE_TYPE_LOCAL_CONTENT; } else if (UriUtil.isLocalAssetUri(uri)) { return SOURCE_TYPE_LOCAL_ASSET; } else if (UriUtil.isLocalResourceUri(uri)) { return SOURCE_TYPE_LOCAL_RESOURCE; } else if (UriUtil.isDataUri(uri)) { return SOURCE_TYPE_DATA; } else if (UriUtil.isQualifiedResourceUri(uri)) { return SOURCE_TYPE_QUALIFIED_RESOURCE; } else { return SOURCE_TYPE_UNKNOWN; } } }