/* * 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.core; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.Set; import android.app.ActivityManager; import android.content.Context; import android.graphics.Rect; import com.facebook.cache.disk.DiskCacheConfig; import com.facebook.common.internal.Preconditions; import com.facebook.common.internal.Supplier; import com.facebook.common.memory.MemoryTrimmableRegistry; import com.facebook.common.memory.NoOpMemoryTrimmableRegistry; import com.facebook.common.util.ByteConstants; import com.facebook.imagepipeline.animated.base.AnimatedImageResult; import com.facebook.imagepipeline.animated.factory.AnimatedImageFactory; import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendImpl; import com.facebook.imagepipeline.animated.util.AnimatedDrawableUtil; import com.facebook.imagepipeline.bitmaps.GingerbreadBitmapFactory; import com.facebook.imagepipeline.bitmaps.DalvikBitmapFactory; import com.facebook.imagepipeline.bitmaps.ArtBitmapFactory; import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory; import com.facebook.imagepipeline.bitmaps.EmptyJpegGenerator; import com.facebook.imagepipeline.cache.DefaultBitmapMemoryCacheParamsSupplier; import com.facebook.imagepipeline.cache.CacheKeyFactory; import com.facebook.imagepipeline.cache.DefaultCacheKeyFactory; import com.facebook.imagepipeline.cache.DefaultEncodedMemoryCacheParamsSupplier; import com.facebook.imagepipeline.cache.ImageCacheStatsTracker; import com.facebook.imagepipeline.cache.MemoryCacheParams; import com.facebook.imagepipeline.cache.NoOpImageCacheStatsTracker; import com.facebook.imagepipeline.decoder.ProgressiveJpegConfig; import com.facebook.imagepipeline.decoder.ImageDecoder; import com.facebook.imagepipeline.decoder.SimpleProgressiveJpegConfig; import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend; import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendProvider; import com.facebook.imagepipeline.memory.PoolConfig; import com.facebook.imagepipeline.memory.PoolFactory; import com.facebook.imagepipeline.listener.RequestListener; import com.facebook.imagepipeline.producers.HttpUrlConnectionNetworkFetcher; import com.facebook.imagepipeline.producers.NetworkFetcher; /** * Master configuration class for the image pipeline library. * * To use: * <code> * ImagePipelineConfig config = ImagePipelineConfig.newBuilder() * .setXXX(xxx) * .setYYY(yyy) * .build(); * ImagePipelineFactory factory = new ImagePipelineFactory(config); * ImagePipeline pipeline = factory.newPipeline(); * </code> * * <p>This should only be done once per process. */ public class ImagePipelineConfig { // There are a lot of parameters in this class. Please follow strict alphabetical order. private final Supplier<MemoryCacheParams> mBitmapMemoryCacheParamsSupplier; private final CacheKeyFactory mCacheKeyFactory; private final Context mContext; private final Supplier<MemoryCacheParams> mEncodedMemoryCacheParamsSupplier; private final ExecutorSupplier mExecutorSupplier; private final ImageCacheStatsTracker mImageCacheStatsTracker; private final AnimatedDrawableUtil mAnimatedDrawableUtil; private final AnimatedImageFactory mAnimatedImageFactory; private final ImageDecoder mImageDecoder; private final Supplier<Boolean> mIsPrefetchEnabledSupplier; private final DiskCacheConfig mMainDiskCacheConfig; private final MemoryTrimmableRegistry mMemoryTrimmableRegistry; private final NetworkFetcher mNetworkFetcher; private final PoolFactory mPoolFactory; private final ProgressiveJpegConfig mProgressiveJpegConfig; private final Set<RequestListener> mRequestListeners; private final boolean mResizeAndRotateEnabledForNetwork; private final DiskCacheConfig mSmallImageDiskCacheConfig; private final PlatformBitmapFactory mPlatformBitmapFactory; private ImagePipelineConfig(Builder builder) { mBitmapMemoryCacheParamsSupplier = builder.mBitmapMemoryCacheParamsSupplier == null ? new DefaultBitmapMemoryCacheParamsSupplier( (ActivityManager) builder.mContext.getSystemService(Context.ACTIVITY_SERVICE)) : builder.mBitmapMemoryCacheParamsSupplier; mCacheKeyFactory = builder.mCacheKeyFactory == null ? DefaultCacheKeyFactory.getInstance() : builder.mCacheKeyFactory; mContext = Preconditions.checkNotNull(builder.mContext); mEncodedMemoryCacheParamsSupplier = builder.mEncodedMemoryCacheParamsSupplier == null ? new DefaultEncodedMemoryCacheParamsSupplier() : builder.mEncodedMemoryCacheParamsSupplier; mExecutorSupplier = builder.mExecutorSupplier == null ? new DefaultExecutorSupplier() : builder.mExecutorSupplier; mImageCacheStatsTracker = builder.mImageCacheStatsTracker == null ? NoOpImageCacheStatsTracker.getInstance() : builder.mImageCacheStatsTracker; mIsPrefetchEnabledSupplier = builder.mIsPrefetchEnabledSupplier == null ? new Supplier<Boolean>() { @Override public Boolean get() { return true; } } : builder.mIsPrefetchEnabledSupplier; mMainDiskCacheConfig = builder.mMainDiskCacheConfig == null ? getDefaultMainDiskCacheConfig(builder.mContext) : builder.mMainDiskCacheConfig; mMemoryTrimmableRegistry = builder.mMemoryTrimmableRegistry == null ? NoOpMemoryTrimmableRegistry.getInstance() : builder.mMemoryTrimmableRegistry; mPoolFactory = builder.mPoolFactory == null ? new PoolFactory(PoolConfig.newBuilder().build()) : builder.mPoolFactory; mProgressiveJpegConfig = builder.mProgressiveJpegConfig == null ? new SimpleProgressiveJpegConfig() : builder.mProgressiveJpegConfig; mRequestListeners = builder.mRequestListeners == null ? new HashSet<RequestListener>() : builder.mRequestListeners; mResizeAndRotateEnabledForNetwork = builder.mResizeAndRotateEnabledForNetwork; mSmallImageDiskCacheConfig = builder.mSmallImageDiskCacheConfig == null ? mMainDiskCacheConfig : builder.mSmallImageDiskCacheConfig; mAnimatedDrawableUtil = new AnimatedDrawableUtil(); AnimatedDrawableBackendProvider animatedDrawableBackendProvider = new AnimatedDrawableBackendProvider() { @Override public AnimatedDrawableBackend get(AnimatedImageResult imageResult, Rect bounds) { return new AnimatedDrawableBackendImpl(mAnimatedDrawableUtil, imageResult, bounds); } }; GingerbreadBitmapFactory factoryGingerbread = new GingerbreadBitmapFactory(); DalvikBitmapFactory factoryICS = new DalvikBitmapFactory( new EmptyJpegGenerator(mPoolFactory.getPooledByteBufferFactory()), mPoolFactory.getSharedByteArray()); ArtBitmapFactory factoryLollipop = new ArtBitmapFactory(mPoolFactory.getBitmapPool()); mPlatformBitmapFactory = new PlatformBitmapFactory( factoryGingerbread, factoryICS, factoryLollipop); mAnimatedImageFactory = builder.mAnimatedImageFactory == null ? new AnimatedImageFactory(animatedDrawableBackendProvider, mPlatformBitmapFactory) : builder.mAnimatedImageFactory; mImageDecoder = builder.mImageDecoder == null ? new ImageDecoder(mAnimatedImageFactory, mPlatformBitmapFactory) : builder.mImageDecoder; mNetworkFetcher = builder.mNetworkFetcher == null ? new HttpUrlConnectionNetworkFetcher() : builder.mNetworkFetcher; } private static DiskCacheConfig getDefaultMainDiskCacheConfig(final Context context) { return DiskCacheConfig.newBuilder() .setBaseDirectoryPathSupplier( new Supplier<File>() { @Override public File get() { return context.getApplicationContext().getCacheDir(); } }) .setBaseDirectoryName("image_cache") .setMaxCacheSize(40 * ByteConstants.MB) .setMaxCacheSizeOnLowDiskSpace(10 * ByteConstants.MB) .setMaxCacheSizeOnVeryLowDiskSpace(2 * ByteConstants.MB) .build(); } public Supplier<MemoryCacheParams> getBitmapMemoryCacheParamsSupplier() { return mBitmapMemoryCacheParamsSupplier; } public CacheKeyFactory getCacheKeyFactory() { return mCacheKeyFactory; } public Context getContext() { return mContext; } public Supplier<MemoryCacheParams> getEncodedMemoryCacheParamsSupplier() { return mEncodedMemoryCacheParamsSupplier; } public ExecutorSupplier getExecutorSupplier() { return mExecutorSupplier; } public ImageCacheStatsTracker getImageCacheStatsTracker() { return mImageCacheStatsTracker; } public ImageDecoder getImageDecoder() { return mImageDecoder; } public Supplier<Boolean> getIsPrefetchEnabledSupplier() { return mIsPrefetchEnabledSupplier; } public DiskCacheConfig getMainDiskCacheConfig() { return mMainDiskCacheConfig; } public MemoryTrimmableRegistry getMemoryTrimmableRegistry() { return mMemoryTrimmableRegistry; } public NetworkFetcher getNetworkFetcher() { return mNetworkFetcher; } public PoolFactory getPoolFactory() { return mPoolFactory; } public ProgressiveJpegConfig getProgressiveJpegConfig() { return mProgressiveJpegConfig; } public Set<RequestListener> getRequestListeners() { return Collections.unmodifiableSet(mRequestListeners); } public boolean isResizeAndRotateEnabledForNetwork() { return mResizeAndRotateEnabledForNetwork; } public DiskCacheConfig getSmallImageDiskCacheConfig() { return mSmallImageDiskCacheConfig; } public PlatformBitmapFactory getPlatformBitmapFactory() { return mPlatformBitmapFactory; } public static Builder newBuilder(Context context) { return new Builder(context); } public static class Builder { private Supplier<MemoryCacheParams> mBitmapMemoryCacheParamsSupplier; private CacheKeyFactory mCacheKeyFactory; private final Context mContext; private Supplier<MemoryCacheParams> mEncodedMemoryCacheParamsSupplier; private ExecutorSupplier mExecutorSupplier; private ImageCacheStatsTracker mImageCacheStatsTracker; private ImageDecoder mImageDecoder; private Supplier<Boolean> mIsPrefetchEnabledSupplier; private DiskCacheConfig mMainDiskCacheConfig; private MemoryTrimmableRegistry mMemoryTrimmableRegistry; private NetworkFetcher mNetworkFetcher; private PoolFactory mPoolFactory; private ProgressiveJpegConfig mProgressiveJpegConfig; private Set<RequestListener> mRequestListeners; private boolean mResizeAndRotateEnabledForNetwork = true; private DiskCacheConfig mSmallImageDiskCacheConfig; private AnimatedImageFactory mAnimatedImageFactory; private Builder(Context context) { // Doesn't use a setter as always required. mContext = Preconditions.checkNotNull(context); } public Builder setBitmapMemoryCacheParamsSupplier( Supplier<MemoryCacheParams> bitmapMemoryCacheParamsSupplier) { mBitmapMemoryCacheParamsSupplier = Preconditions.checkNotNull(bitmapMemoryCacheParamsSupplier); return this; } public Builder setCacheKeyFactory(CacheKeyFactory cacheKeyFactory) { mCacheKeyFactory = cacheKeyFactory; return this; } public Builder setEncodedMemoryCacheParamsSupplier( Supplier<MemoryCacheParams> encodedMemoryCacheParamsSupplier) { mEncodedMemoryCacheParamsSupplier = Preconditions.checkNotNull(encodedMemoryCacheParamsSupplier); return this; } public Builder setExecutorSupplier(ExecutorSupplier executorSupplier) { mExecutorSupplier = executorSupplier; return this; } public Builder setImageCacheStatsTracker(ImageCacheStatsTracker imageCacheStatsTracker) { mImageCacheStatsTracker = imageCacheStatsTracker; return this; } public Builder setAnimatedImageFactory(AnimatedImageFactory animatedImageFactory) { mAnimatedImageFactory = animatedImageFactory; return this; } public Builder setImageDecoder(ImageDecoder imageDecoder) { mImageDecoder = imageDecoder; return this; } public Builder setIsPrefetchEnabledSupplier(Supplier<Boolean> isPrefetchEnabledSupplier) { mIsPrefetchEnabledSupplier = isPrefetchEnabledSupplier; return this; } public Builder setMainDiskCacheConfig(DiskCacheConfig mainDiskCacheConfig) { mMainDiskCacheConfig = mainDiskCacheConfig; return this; } public Builder setMemoryTrimmableRegistry(MemoryTrimmableRegistry memoryTrimmableRegistry) { mMemoryTrimmableRegistry = memoryTrimmableRegistry; return this; } public Builder setNetworkFetcher(NetworkFetcher networkFetcher) { mNetworkFetcher = networkFetcher; return this; } public Builder setPoolFactory(PoolFactory poolFactory) { mPoolFactory = poolFactory; return this; } public Builder setProgressiveJpegConfig(ProgressiveJpegConfig progressiveJpegConfig) { mProgressiveJpegConfig = progressiveJpegConfig; return this; } public Builder setRequestListeners(Set<RequestListener> requestListeners) { mRequestListeners = requestListeners; return this; } public Builder setResizeAndRotateEnabledForNetwork(boolean resizeAndRotateEnabledForNetwork) { mResizeAndRotateEnabledForNetwork = resizeAndRotateEnabledForNetwork; return this; } public Builder setSmallImageDiskCacheConfig(DiskCacheConfig smallImageDiskCacheConfig) { mSmallImageDiskCacheConfig = smallImageDiskCacheConfig; return this; } public ImagePipelineConfig build() { return new ImagePipelineConfig(this); } } }