blob: 61eed85261cd7dd2aa76ba9002c82480f97f2a6c [file] [log] [blame]
package com.android.gallery3d.ui;
import android.graphics.Bitmap;
import android.util.Log;
import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.util.Future;
import com.android.gallery3d.util.FutureListener;
public abstract class AbstractDisplayItem
extends DisplayItem implements FutureListener<Bitmap> {
private static final String TAG = "AbstractDisplayItem";
private static final int STATE_INVALID = 0x01;
private static final int STATE_VALID = 0x02;
private static final int STATE_UPDATING = 0x04;
private static final int STATE_CANCELING = 0x08;
private static final int STATE_ERROR = 0x10;
private int mState = STATE_INVALID;
private Future<Bitmap> mFuture;
private boolean mImageRequested = false;
private boolean mRecycling = false;
private Bitmap mBitmap;
protected final MediaItem mMediaItem;
public AbstractDisplayItem(MediaItem item) {
mMediaItem = item;
if (item == null) mState = STATE_ERROR;
}
public void updateImage() {
Future<Bitmap> future = mFuture;
mFuture = null;
if (future.isCancelled()) {
mState = STATE_INVALID;
if (mRecycling) {
onRecycled();
} else if (mImageRequested) {
Log.v(TAG, String.format("request image again %s", toString()));
requestImage();
}
return;
}
Bitmap bitmap = null;
try {
bitmap = future.get();
} catch (Throwable t) {
Log.e(TAG, "cannot get bitmap", t);
}
if (mRecycling) {
if (bitmap != null) bitmap.recycle();
onRecycled();
return;
}
mBitmap = bitmap;
mState = bitmap == null ? STATE_ERROR : STATE_VALID ;
onBitmapAvailable(mBitmap);
}
@Override
public long getIdentity() {
return mMediaItem != null
? mMediaItem.getUniqueId()
: System.identityHashCode(this);
}
public void requestImage() {
if (mState == STATE_INVALID) {
mState = STATE_UPDATING;
mFuture = mMediaItem.requestImage(MediaItem.TYPE_MICROTHUMBNAIL, this);
}
mImageRequested = true;
}
public void cancelImageRequest() {
if (mState == STATE_UPDATING) {
mState = STATE_CANCELING;
mFuture.requestCancel();
}
mImageRequested = false;
}
private boolean inState(int states) {
return (mState & states) != 0;
}
public void recycle() {
if (!inState(STATE_UPDATING | STATE_CANCELING)) {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
onRecycled();
} else {
mRecycling = true;
cancelImageRequest();
}
}
public boolean isRequestInProgress() {
return mImageRequested && inState(STATE_UPDATING | STATE_CANCELING);
}
protected void onRecycled() {
}
abstract protected void onBitmapAvailable(Bitmap bitmap);
abstract public void onFutureDone(Future<? extends Bitmap> future);
}