Revise ThumbnailUtils API.
diff --git a/api/current.xml b/api/current.xml
index 24b9c96..425dad4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -83971,29 +83971,6 @@
visibility="public"
>
</constructor>
-<method name="createImageThumbnail"
- return="android.graphics.Bitmap"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="cr" type="android.content.ContentResolver">
-</parameter>
-<parameter name="filePath" type="java.lang.String">
-</parameter>
-<parameter name="uri" type="android.net.Uri">
-</parameter>
-<parameter name="origId" type="long">
-</parameter>
-<parameter name="kind" type="int">
-</parameter>
-<parameter name="saveMini" type="boolean">
-</parameter>
-</method>
<method name="createVideoThumbnail"
return="android.graphics.Bitmap"
abstract="false"
@@ -84007,7 +83984,7 @@
<parameter name="filePath" type="java.lang.String">
</parameter>
</method>
-<method name="extractMiniThumb"
+<method name="extractThumbnail"
return="android.graphics.Bitmap"
abstract="false"
native="false"
@@ -84023,10 +84000,38 @@
</parameter>
<parameter name="height" type="int">
</parameter>
-<parameter name="recycle" type="boolean">
+</method>
+<method name="extractThumbnail"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="source" type="android.graphics.Bitmap">
+</parameter>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="options" type="int">
</parameter>
</method>
-<field name="MINI_THUMB_TARGET_SIZE"
+<field name="OPTIONS_RECYCLE_INPUT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_SIZE_MICRO_THUMBNAIL"
type="int"
transient="false"
volatile="false"
@@ -84037,29 +84042,7 @@
visibility="public"
>
</field>
-<field name="NO_RECYCLE_INPUT"
- type="boolean"
- transient="false"
- volatile="false"
- value="false"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="RECYCLE_INPUT"
- type="boolean"
- transient="false"
- volatile="false"
- value="true"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="THUMBNAIL_TARGET_SIZE"
+<field name="TARGET_SIZE_NORMAL_THUMBNAIL"
type="int"
transient="false"
volatile="false"
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 211bc0a..74a03da 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -383,10 +383,10 @@
if (isVideo) {
bitmap = ThumbnailUtils.createVideoThumbnail(filePath);
if (kind == MICRO_KIND && bitmap != null) {
- bitmap = ThumbnailUtils.extractMiniThumb(bitmap,
- ThumbnailUtils.MINI_THUMB_TARGET_SIZE,
- ThumbnailUtils.MINI_THUMB_TARGET_SIZE,
- ThumbnailUtils.RECYCLE_INPUT);
+ bitmap = ThumbnailUtils.extractThumbnail(bitmap,
+ ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
+ ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
+ ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
}
} else {
bitmap = ThumbnailUtils.createImageThumbnail(cr, filePath, uri, origId,
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 225d4b6..30d95e3 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -46,41 +46,32 @@
private static final String TAG = "ThumbnailUtils";
/* Maximum pixels size for created bitmap. */
- private static final int THUMBNAIL_MAX_NUM_PIXELS = 512 * 384;
- private static final int MINI_THUMB_MAX_NUM_PIXELS = 128 * 128;
+ private static final int MAX_NUM_PIXELS_THUMBNAIL = 512 * 384;
+ private static final int MAX_NUM_PIXELS_MICRO_THUMBNAIL = 128 * 128;
private static final int UNCONSTRAINED = -1;
- /* Whether we should rotate the resulting bitmap. */
- private static final boolean ROTATE_AS_NEEDED = true;
- private static final boolean NO_ROTATE = false;
-
- /* Whether we should create bitmap in native memory. */
- private static final boolean USE_NATIVE = true;
- private static final boolean NO_NATIVE = false;
+ /* Options used internally. */
+ private static final int OPTIONS_NONE = 0x0;
+ private static final int OPTIONS_DO_NOT_USE_NATIVE = 0x1;
+ private static final int OPTIONS_SCALE_UP = 0x2;
/**
* Constant used to indicate we should recycle the input in
- * {@link #extractMiniThumb(Bitmap, int, int, boolean)} unless the output is the input.
+ * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input.
*/
- public static final boolean RECYCLE_INPUT = true;
-
- /**
- * Constant used to indicate we should not recycle the input in
- * {@link #extractMiniThumb(Bitmap, int, int, boolean)}.
- */
- public static final boolean NO_RECYCLE_INPUT = false;
+ public static final int OPTIONS_RECYCLE_INPUT = 0x4;
/**
* Constant used to indicate the dimension of normal thumbnail in
- * {@link #extractMiniThumb(Bitmap, int, int, boolean)}.
+ * {@link #extractThumbnail(Bitmap, int, int, int)}.
*/
- public static final int THUMBNAIL_TARGET_SIZE = 320;
+ public static final int TARGET_SIZE_NORMAL_THUMBNAIL = 320;
/**
- * Constant used to indicate the dimension of mini thumbnail in
- * {@link #extractMiniThumb(Bitmap, int, int, boolean)}.
+ * Constant used to indicate the dimension of micro thumbnail in
+ * {@link #extractThumbnail(Bitmap, int, int, int)}.
*/
- public static final int MINI_THUMB_TARGET_SIZE = 96;
+ public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;
/**
* This method first examines if the thumbnail embedded in EXIF is bigger than our target
@@ -97,14 +88,16 @@
* @param kind either MINI_KIND or MICRO_KIND
* @param saveMini Whether to save MINI_KIND thumbnail obtained in this method.
* @return Bitmap
+ *
+ * @hide This method is only used by media framework and media provider internally.
*/
public static Bitmap createImageThumbnail(ContentResolver cr, String filePath, Uri uri,
long origId, int kind, boolean saveMini) {
boolean wantMini = (kind == Images.Thumbnails.MINI_KIND || saveMini);
int targetSize = wantMini ?
- THUMBNAIL_TARGET_SIZE : MINI_THUMB_TARGET_SIZE;
+ TARGET_SIZE_NORMAL_THUMBNAIL : TARGET_SIZE_MICRO_THUMBNAIL;
int maxPixels = wantMini ?
- THUMBNAIL_MAX_NUM_PIXELS : MINI_THUMB_MAX_NUM_PIXELS;
+ MAX_NUM_PIXELS_THUMBNAIL : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
Bitmap bitmap = null;
MediaFileType fileType = MediaFile.getFileType(filePath);
@@ -134,16 +127,16 @@
if (kind == Images.Thumbnails.MICRO_KIND) {
// now we make it a "square thumbnail" for MICRO_KIND thumbnail
- bitmap = extractMiniThumb(bitmap,
- MINI_THUMB_TARGET_SIZE,
- MINI_THUMB_TARGET_SIZE, RECYCLE_INPUT);
+ bitmap = extractThumbnail(bitmap,
+ TARGET_SIZE_MICRO_THUMBNAIL,
+ TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT);
}
return bitmap;
}
/**
* Create a video thumbnail for a video. May return null if the video is
- * corrupt.
+ * corrupt or the format is not supported.
*
* @param filePath
*/
@@ -174,10 +167,22 @@
* @param source original bitmap source
* @param width targeted width
* @param height targeted height
- * @param recycle whether we want to recycle the input
*/
- public static Bitmap extractMiniThumb(
- Bitmap source, int width, int height, boolean recycle) {
+ public static Bitmap extractThumbnail(
+ Bitmap source, int width, int height) {
+ return extractThumbnail(source, width, height, OPTIONS_NONE);
+ }
+
+ /**
+ * Creates a centered bitmap of the desired size.
+ *
+ * @param source original bitmap source
+ * @param width targeted width
+ * @param height targeted height
+ * @param options options used during thumbnail extraction
+ */
+ public static Bitmap extractThumbnail(
+ Bitmap source, int width, int height, int options) {
if (source == null) {
return null;
}
@@ -190,8 +195,9 @@
}
Matrix matrix = new Matrix();
matrix.setScale(scale, scale);
- Bitmap miniThumbnail = transform(matrix, source, width, height, true, recycle);
- return miniThumbnail;
+ Bitmap thumbnail = transform(matrix, source, width, height,
+ OPTIONS_SCALE_UP | options);
+ return thumbnail;
}
/*
@@ -272,7 +278,7 @@
private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
Uri uri, ContentResolver cr) {
return makeBitmap(minSideLength, maxNumOfPixels, uri, cr,
- NO_NATIVE);
+ OPTIONS_DO_NOT_USE_NATIVE);
}
/**
@@ -281,7 +287,8 @@
* whether they want the Bitmap be created in native memory.
*/
private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
- Uri uri, ContentResolver cr, boolean useNative) {
+ Uri uri, ContentResolver cr, int opt) {
+ boolean useNative = (opt & OPTIONS_DO_NOT_USE_NATIVE) != 0;
ParcelFileDescriptor input = null;
try {
input = cr.openFileDescriptor(uri, "r");
@@ -340,29 +347,6 @@
return b;
}
- /**
- * Rotates the bitmap by the specified degree.
- * If a new bitmap is created, the original bitmap is recycled.
- */
- private static Bitmap rotate(Bitmap b, int degrees) {
- if (degrees != 0 && b != null) {
- Matrix m = new Matrix();
- m.setRotate(degrees,
- (float) b.getWidth() / 2, (float) b.getHeight() / 2);
- try {
- Bitmap b2 = Bitmap.createBitmap(
- b, 0, 0, b.getWidth(), b.getHeight(), m, true);
- if (b != b2) {
- b.recycle();
- b = b2;
- }
- } catch (OutOfMemoryError ex) {
- // We have no memory to rotate. Return the original bitmap.
- }
- }
- return b;
- }
-
private static void closeSilently(ParcelFileDescriptor c) {
if (c == null) return;
try {
@@ -388,8 +372,9 @@
Bitmap source,
int targetWidth,
int targetHeight,
- boolean scaleUp,
- boolean recycle) {
+ int options) {
+ boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
+ boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;
int deltaX = source.getWidth() - targetWidth;
int deltaY = source.getHeight() - targetHeight;