package com.koushikdutta.ion;
import com.koushikdutta.async.AsyncServer;
import com.koushikdutta.async.ByteBufferList;
import com.koushikdutta.async.future.Future;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.async.http.AsyncHttpRequest;
import com.koushikdutta.async.http.libcore.DiskLruCache;
import com.koushikdutta.async.parser.ByteBufferListParser;
import com.koushikdutta.ion.bitmap.BitmapInfo;
import com.koushikdutta.ion.bitmap.Transform;
import com.koushikdutta.ion.loader.MediaFile;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
class BitmapFetcher implements IonRequestBuilder.LoadRequestCallback {
String downloadKey;
String bitmapKey;
BitmapInfo info;
boolean hasTransforms;
ArrayList<Transform> transforms;
IonRequestBuilder builder;
int resizeWidth;
int resizeHeight;
boolean animateGif;
boolean deepZoom;
private boolean fastLoad(String uri) {
Ion ion = builder.ion;
if (deepZoom) {
if (uri == null || !uri.startsWith("file:/"))
return false;
File file = new File(URI.create(uri));
if (!file.exists())
return false;
MediaFile.MediaFileType type = MediaFile.getFileType(file.getAbsolutePath());
if (type == null || !MediaFile.isVideoFileType(type.fileType)) {
LoadDeepZoom loadDeepZoom = new LoadDeepZoom(ion, downloadKey, animateGif, null, null);
loadDeepZoom.onCompleted(null, file);
// System.out.println("fastloading deepZoom");
return true;
}
// fall through to allow some other loader to open this, cause this is a video file
}
boolean put = !hasTransforms;
for (Loader loader: ion.configure().getLoaders()) {
Future<BitmapInfo> future = loader.loadBitmap(ion, downloadKey, uri, resizeWidth, resizeHeight, animateGif);
if (future != null) {
final BitmapCallback callback = new LoadBitmapBase(ion, downloadKey, put);
future.setCallback(new FutureCallback<BitmapInfo>() {
@Override
public void onCompleted(Exception e, BitmapInfo result) {
callback.report(e, result);
}
});
return true;
}
}
return false;
}
public static final int MAX_IMAGEVIEW_LOAD = 5;
public static boolean shouldDeferImageView(Ion ion) {
if (ion.bitmapsPending.keySet().size() <= MAX_IMAGEVIEW_LOAD)
return false;
int loadCount = 0;
for (String key: ion.bitmapsPending.keySet()) {
Object owner = ion.bitmapsPending.tag(key);
if (owner instanceof LoadBitmapBase) {
loadCount++;
if (loadCount > MAX_IMAGEVIEW_LOAD)
return true;
}
}
return false;
}
public DeferredLoadBitmap defer() {
DeferredLoadBitmap ret = new DeferredLoadBitmap(builder.ion, downloadKey, this);
executeTransforms(builder.ion);
return ret;
}
private void executeTransforms(Ion ion) {
// if there's a transform, do it
if (!hasTransforms)
return;
// verify this transform isn't already pending
// make sure that the parent download isn't cancelled (empty list)
// and also make sure there are waiters for this transformed bitmap
if (ion.bitmapsPending.tag(bitmapKey) == null) {
ion.bitmapsPending.add(downloadKey, new TransformBitmap(ion, bitmapKey, downloadKey, transforms));
}
}
@Override
public boolean loadRequest(AsyncHttpRequest request) {
return !fastLoad(request.getUri().toString());
}
public void execute() {
final Ion ion = builder.ion;
// bitmaps that were transformed are put into the DiskLruCache to prevent
// subsequent retransformation. See if we can retrieve the bitmap from the disk cache.
// See TransformBitmap for where the cache is populated.
DiskLruCache diskLruCache = ion.responseCache.getDiskLruCache();
if (!builder.noCache && hasTransforms && diskLruCache.containsKey(bitmapKey) && !deepZoom) {
TransformBitmap.getBitmapSnapshot(ion, bitmapKey);
return;
}
// Perform a download as necessary.
if (ion.bitmapsPending.tag(downloadKey) == null && !fastLoad(builder.uri)) {
builder.setHandler(null);
builder.loadRequestCallback = this;
if (!deepZoom) {
IonRequestBuilder.EmitterTransform<ByteBufferList> emitterTransform = builder.execute(new ByteBufferListParser(), new Runnable() {
@Override
public void run() {
AsyncServer.post(Ion.mainHandler, new Runnable() {
@Override
public void run() {
ion.bitmapsPending.remove(downloadKey);
}
});
}
});
emitterTransform.setCallback(new LoadBitmap(ion, downloadKey, !hasTransforms, resizeWidth, resizeHeight, animateGif, emitterTransform));
}
else {
// System.out.println("downloading file for deepZoom");
File file = diskLruCache.getFile(downloadKey, 0);
IonRequestBuilder.EmitterTransform<File> emitterTransform = builder.write(file);
LoadDeepZoom loadDeepZoom = new LoadDeepZoom(ion, downloadKey, animateGif, emitterTransform, diskLruCache) {
@Override
public void onCompleted(Exception e, File file) {
super.onCompleted(e, file);
}
};
emitterTransform.setCallback(loadDeepZoom);
}
}
executeTransforms(ion);
}
}