Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.ui;
     18 
     19 import android.graphics.Bitmap;
     20 
     21 import com.android.gallery3d.util.Future;
     22 import com.android.gallery3d.util.FutureListener;
     23 
     24 // We use this class to
     25 //     1.) load bitmaps in background.
     26 //     2.) as a place holder for the loaded bitmap
     27 public abstract class BitmapLoader implements FutureListener<Bitmap> {
     28     @SuppressWarnings("unused")
     29     private static final String TAG = "BitmapLoader";
     30 
     31     /* Transition Map:
     32      *   INIT -> REQUESTED, RECYCLED
     33      *   REQUESTED -> INIT (cancel), LOADED, ERROR, RECYCLED
     34      *   LOADED, ERROR -> RECYCLED
     35      */
     36     private static final int STATE_INIT = 0;
     37     private static final int STATE_REQUESTED = 1;
     38     private static final int STATE_LOADED = 2;
     39     private static final int STATE_ERROR = 3;
     40     private static final int STATE_RECYCLED = 4;
     41 
     42     private int mState = STATE_INIT;
     43     // mTask is not null only when a task is on the way
     44     private Future<Bitmap> mTask;
     45     private Bitmap mBitmap;
     46 
     47     @Override
     48     public void onFutureDone(Future<Bitmap> future) {
     49         synchronized (this) {
     50             mTask = null;
     51             mBitmap = future.get();
     52             if (mState == STATE_RECYCLED) {
     53                 if (mBitmap != null) {
     54                     recycleBitmap(mBitmap);
     55                     mBitmap = null;
     56                 }
     57                 return; // don't call callback
     58             }
     59             if (future.isCancelled() && mBitmap == null) {
     60                 if (mState == STATE_REQUESTED) mTask = submitBitmapTask(this);
     61                 return; // don't call callback
     62             } else {
     63                 mState = mBitmap == null ? STATE_ERROR : STATE_LOADED;
     64             }
     65         }
     66         onLoadComplete(mBitmap);
     67     }
     68 
     69     public synchronized void startLoad() {
     70         if (mState == STATE_INIT) {
     71             mState = STATE_REQUESTED;
     72             if (mTask == null) mTask = submitBitmapTask(this);
     73         }
     74     }
     75 
     76     public synchronized void cancelLoad() {
     77         if (mState == STATE_REQUESTED) {
     78             mState = STATE_INIT;
     79             if (mTask != null) mTask.cancel();
     80         }
     81     }
     82 
     83     // Recycle the loader and the bitmap
     84     public synchronized void recycle() {
     85         mState = STATE_RECYCLED;
     86         if (mBitmap != null) {
     87             recycleBitmap(mBitmap);
     88             mBitmap = null;
     89         }
     90         if (mTask != null) mTask.cancel();
     91     }
     92 
     93     public synchronized boolean isRequestInProgress() {
     94         return mState == STATE_REQUESTED;
     95     }
     96 
     97     public synchronized boolean isRecycled() {
     98         return mState == STATE_RECYCLED;
     99     }
    100 
    101     public synchronized Bitmap getBitmap() {
    102         return mBitmap;
    103     }
    104 
    105     abstract protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l);
    106     abstract protected void recycleBitmap(Bitmap bitmap);
    107     abstract protected void onLoadComplete(Bitmap bitmap);
    108 }
    109