/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.camera; import android.content.ContentResolver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.provider.MediaStore.Images; import android.provider.MediaStore.Video; import android.util.Log; import java.io.FileDescriptor; import java.util.WeakHashMap; /** * Provides utilities to decode bitmap, get thumbnail, and cancel the * operations. * *
The function {@link #decodeFileDescriptor(FileDescriptor, * BitmapFactory.Options)} is used to decode a bitmap. During decoding another * thread can cancel it using the function {@link #cancelThreadDecoding(Thread, * ContentResolver)} specifying the {@code Thread} which is in decoding. * *
{@code cancelThreadDecoding(Thread,ContentResolver)} is sticky until
* {@code allowThreadDecoding(Thread) } is called.
*/
public class BitmapManager {
private static final String TAG = "BitmapManager";
private static enum State {CANCEL, ALLOW}
private static class ThreadStatus {
public State mState = State.ALLOW;
public BitmapFactory.Options mOptions;
@Override
public String toString() {
String s;
if (mState == State.CANCEL) {
s = "Cancel";
} else if (mState == State.ALLOW) {
s = "Allow";
} else {
s = "?";
}
s = "thread state = " + s + ", options = " + mOptions;
return s;
}
}
private final WeakHashMap This method wraps around @{code getThumbnail} in {@code
* android.provider.MediaStore}. It provides the ability to cancel it.
*/
public Bitmap getThumbnail(ContentResolver cr, long origId, int kind,
BitmapFactory.Options options, boolean isVideo) {
Thread t = Thread.currentThread();
ThreadStatus status = getOrCreateThreadStatus(t);
if (!canThreadDecoding(t)) {
Log.d(TAG, "Thread " + t + " is not allowed to decode.");
return null;
}
try {
if (isVideo) {
return Video.Thumbnails.getThumbnail(cr, origId, t.getId(),
kind, null);
} else {
return Images.Thumbnails.getThumbnail(cr, origId, t.getId(),
kind, null);
}
} finally {
synchronized (status) {
status.notifyAll();
}
}
}
public static synchronized BitmapManager instance() {
if (sManager == null) {
sManager = new BitmapManager();
}
return sManager;
}
}