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.photos.data.GalleryBitmapPool;
     22 import com.android.gallery3d.util.Future;
     23 import com.android.gallery3d.util.FutureListener;
     24 
     25 // We use this class to
     26 //     1.) load bitmaps in background.
     27 //     2.) as a place holder for the loaded bitmap
     28 public abstract class BitmapLoader implements FutureListener<Bitmap> {
     29     @SuppressWarnings("unused")
     30     private static final String TAG = "BitmapLoader";
     31 
     32     /* Transition Map:
     33      *   INIT -> REQUESTED, RECYCLED
     34      *   REQUESTED -> INIT (cancel), LOADED, ERROR, RECYCLED
     35      *   LOADED, ERROR -> RECYCLED
     36      */
     37     private static final int STATE_INIT = 0;
     38     private static final int STATE_REQUESTED = 1;
     39     private static final int STATE_LOADED = 2;
     40     private static final int STATE_ERROR = 3;
     41     private static final int STATE_RECYCLED = 4;
     42 
     43     private int mState = STATE_INIT;
     44     // mTask is not null only when a task is on the way
     45     private Future<Bitmap> mTask;
     46     private Bitmap mBitmap;
     47 
     48     @Override
     49     public void onFutureDone(Future<Bitmap> future) {
     50         synchronized (this) {
     51             mTask = null;
     52             mBitmap = future.get();
     53             if (mState == STATE_RECYCLED) {
     54                 if (mBitmap != null) {
     55                     GalleryBitmapPool.getInstance().put(mBitmap);
     56                     mBitmap = null;
     57                 }
     58                 return; // don't call callback
     59             }
     60             if (future.isCancelled() && mBitmap == null) {
     61                 if (mState == STATE_REQUESTED) mTask = submitBitmapTask(this);
     62                 return; // don't call callback
     63             } else {
     64                 mState = mBitmap == null ? STATE_ERROR : STATE_LOADED;
     65             }
     66         }
     67         onLoadComplete(mBitmap);
     68     }
     69 
     70     public synchronized void startLoad() {
     71         if (mState == STATE_INIT) {
     72             mState = STATE_REQUESTED;
     73             if (mTask == null) mTask = submitBitmapTask(this);
     74         }
     75     }
     76 
     77     public synchronized void cancelLoad() {
     78         if (mState == STATE_REQUESTED) {
     79             mState = STATE_INIT;
     80             if (mTask != null) mTask.cancel();
     81         }
     82     }
     83 
     84     // Recycle the loader and the bitmap
     85     public synchronized void recycle() {
     86         mState = STATE_RECYCLED;
     87         if (mBitmap != null) {
     88             GalleryBitmapPool.getInstance().put(mBitmap);
     89             mBitmap = null;
     90         }
     91         if (mTask != null) mTask.cancel();
     92     }
     93 
     94     public synchronized boolean isRequestInProgress() {
     95         return mState == STATE_REQUESTED;
     96     }
     97 
     98     public synchronized boolean isRecycled() {
     99         return mState == STATE_RECYCLED;
    100     }
    101 
    102     public synchronized Bitmap getBitmap() {
    103         return mBitmap;
    104     }
    105 
    106     abstract protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l);
    107     abstract protected void onLoadComplete(Bitmap bitmap);
    108 }
    109