Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44dcf658 authored by Ray Chen's avatar Ray Chen
Browse files

Make createVideoThumbnail and createImageThumbnail look consistent.

Change-Id: I9a4798fefe3968ac847d46100036a6dde39791c9
parent 3eefc126
Loading
Loading
Loading
Loading
+2 −22
Original line number Diff line number Diff line
@@ -86123,6 +86123,8 @@
>
<parameter name="filePath" type="java.lang.String">
</parameter>
<parameter name="kind" type="int">
</parameter>
</method>
<method name="extractThumbnail"
 return="android.graphics.Bitmap"
@@ -86171,28 +86173,6 @@
 visibility="public"
>
</field>
<field name="TARGET_SIZE_MICRO_THUMBNAIL"
 type="int"
 transient="false"
 volatile="false"
 value="96"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="TARGET_SIZE_MINI_THUMBNAIL"
 type="int"
 transient="false"
 volatile="false"
 value="320"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
</class>
<class name="ToneGenerator"
 extends="java.lang.Object"
+10 −13
Original line number Diff line number Diff line
@@ -374,8 +374,8 @@ public final class MediaStore {

                // We probably run out of space, so create the thumbnail in memory.
                if (bitmap == null) {
                    Log.v(TAG, "We probably run out of space, so create the thumbnail in memory.");

                    Log.v(TAG, "Create the thumbnail in memory: origId=" + origId
                            + ", kind=" + kind + ", isVideo="+isVideo);
                    Uri uri = Uri.parse(
                            baseUri.buildUpon().appendPath(String.valueOf(origId))
                                    .toString().replaceFirst("thumbnails", "media"));
@@ -388,16 +388,9 @@ public final class MediaStore {
                        filePath = c.getString(1);
                    }
                    if (isVideo) {
                        bitmap = ThumbnailUtils.createVideoThumbnail(filePath);
                        if (kind == MICRO_KIND && bitmap != null) {
                            bitmap = ThumbnailUtils.extractThumbnail(bitmap,
                                    ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
                                    ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
                                    ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
                        }
                        bitmap = ThumbnailUtils.createVideoThumbnail(filePath, kind);
                    } else {
                        bitmap = ThumbnailUtils.createImageThumbnail(cr, filePath, uri, origId,
                                kind, false);
                        bitmap = ThumbnailUtils.createImageThumbnail(filePath, kind);
                    }
                }
            } catch (SQLiteException ex) {
@@ -613,8 +606,12 @@ public final class MediaStore {
                        }

                        long id = ContentUris.parseId(url);
                        Bitmap miniThumb  = StoreThumbnail(cr, source, id, 320F, 240F, Images.Thumbnails.MINI_KIND);
                        Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F, Images.Thumbnails.MICRO_KIND);
                        // Wait until MINI_KIND thumbnail is generated.
                        Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id,
                                Images.Thumbnails.MINI_KIND, null);
                        // This is for backward compatibility.
                        Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F,
                                Images.Thumbnails.MICRO_KIND);
                    } else {
                        Log.e(TAG, "Failed to create thumbnail, removing original");
                        cr.delete(url, null, null);
+43 −128
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.Thumbnails;
import android.util.Log;

import java.io.FileInputStream;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.OutputStream;
@@ -61,14 +62,14 @@ public class ThumbnailUtils {
    public static final int OPTIONS_RECYCLE_INPUT = 0x2;

    /**
     * Constant used to indicate the dimension of mini thumbnail in
     * {@link #extractThumbnail(Bitmap, int, int, int)}.
     * Constant used to indicate the dimension of mini thumbnail.
     * @hide Only used by media framework and media provider internally.
     */
    public static final int TARGET_SIZE_MINI_THUMBNAIL = 320;

    /**
     * Constant used to indicate the dimension of micro thumbnail in
     * {@link #extractThumbnail(Bitmap, int, int, int)}.
     * Constant used to indicate the dimension of micro thumbnail.
     * @hide Only used by media framework and media provider internally.
     */
    public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;

@@ -80,23 +81,20 @@ public class ThumbnailUtils {
     *
     * This method always returns a "square thumbnail" for MICRO_KIND thumbnail.
     *
     * @param cr ContentResolver
     * @param filePath file path needed by EXIF interface
     * @param uri URI of original image
     * @param origId image id
     * @param kind either MINI_KIND or MICRO_KIND
     * @param saveMini Whether to save MINI_KIND thumbnail obtained in this method.
     * @param filePath the path of image file
     * @param kind could be MINI_KIND or MICRO_KIND
     * @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 ?
                TARGET_SIZE_MINI_THUMBNAIL : TARGET_SIZE_MICRO_THUMBNAIL;
        int maxPixels = wantMini ?
                MAX_NUM_PIXELS_THUMBNAIL : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
    public static Bitmap createImageThumbnail(String filePath, int kind) {
        boolean wantMini = (kind == Images.Thumbnails.MINI_KIND);
        int targetSize = wantMini
                ? TARGET_SIZE_MINI_THUMBNAIL
                : TARGET_SIZE_MICRO_THUMBNAIL;
        int maxPixels = wantMini
                ? MAX_NUM_PIXELS_THUMBNAIL
                : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
        SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
        Bitmap bitmap = null;
        MediaFileType fileType = MediaFile.getFileType(filePath);
@@ -106,21 +104,25 @@ public class ThumbnailUtils {
        }

        if (bitmap == null) {
            bitmap = makeBitmap(targetSize, maxPixels, uri, cr);
        }

        if (bitmap == null) {
            try {
                FileDescriptor fd = new FileInputStream(filePath).getFD();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 1;
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFileDescriptor(fd, null, options);
                if (options.mCancel || options.outWidth == -1
                        || options.outHeight == -1) {
                    return null;
                }
                options.inSampleSize = computeSampleSize(
                        options, targetSize, maxPixels);
                options.inJustDecodeBounds = false;

        if (saveMini) {
            if (sizedThumbnailBitmap.mThumbnailData != null) {
                storeThumbnail(cr, origId,
                        sizedThumbnailBitmap.mThumbnailData,
                        sizedThumbnailBitmap.mThumbnailWidth,
                        sizedThumbnailBitmap.mThumbnailHeight);
            } else {
                storeThumbnail(cr, origId, bitmap);
                options.inDither = false;
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);
            } catch (IOException ex) {
                Log.e(TAG, "", ex);
            }
        }

@@ -137,9 +139,10 @@ public class ThumbnailUtils {
     * Create a video thumbnail for a video. May return null if the video is
     * corrupt or the format is not supported.
     *
     * @param filePath
     * @param filePath the path of video file
     * @param kind could be MINI_KIND or MICRO_KIND
     */
    public static Bitmap createVideoThumbnail(String filePath) {
    public static Bitmap createVideoThumbnail(String filePath, int kind) {
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
@@ -157,6 +160,12 @@ public class ThumbnailUtils {
                // Ignore failures while cleaning up.
            }
        }
        if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {
            bitmap = extractThumbnail(bitmap,
                    TARGET_SIZE_MICRO_THUMBNAIL,
                    TARGET_SIZE_MICRO_THUMBNAIL,
                    OPTIONS_RECYCLE_INPUT);
        }
        return bitmap;
    }

@@ -262,25 +271,6 @@ public class ThumbnailUtils {
        }
    }

    /**
     * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels.
     * The image data will be read from specified ContentResolver.
     */
    private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
            Uri uri, ContentResolver cr) {
        ParcelFileDescriptor input = null;
        try {
            input = cr.openFileDescriptor(uri, "r");
            return makeBitmap(minSideLength, maxNumOfPixels, uri, cr, input,
                    null);
        } catch (IOException ex) {
            Log.e(TAG, "", ex);
            return null;
        } finally {
            closeSilently(input);
        }
    }

    /**
     * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels.
     * The image data will be read from specified pfd if it's not null, otherwise
@@ -438,81 +428,6 @@ public class ThumbnailUtils {
        return b2;
    }

    private static final String[] THUMB_PROJECTION = new String[] {
        BaseColumns._ID // 0
    };

    /**
     * Look up thumbnail uri by given imageId, it will be automatically created if it's not created
     * yet. Most of the time imageId is identical to thumbId, but it's not always true.
     */
    private static Uri getImageThumbnailUri(ContentResolver cr, long origId, int width, int height) {
        Uri thumbUri = Images.Thumbnails.EXTERNAL_CONTENT_URI;
        Cursor c = cr.query(thumbUri, THUMB_PROJECTION,
              Thumbnails.IMAGE_ID + "=?",
              new String[]{String.valueOf(origId)}, null);
        if (c == null) return null;
        try {
            if (c.moveToNext()) {
                return ContentUris.withAppendedId(thumbUri, c.getLong(0));
            }
        } finally {
            if (c != null) c.close();
        }

        ContentValues values = new ContentValues(4);
        values.put(Thumbnails.KIND, Thumbnails.MINI_KIND);
        values.put(Thumbnails.IMAGE_ID, origId);
        values.put(Thumbnails.HEIGHT, height);
        values.put(Thumbnails.WIDTH, width);
        try {
            return cr.insert(thumbUri, values);
        } catch (Exception ex) {
            Log.w(TAG, ex);
            return null;
        }
    }

    /**
     * Store a given thumbnail in the database. (Bitmap)
     */
    private static boolean storeThumbnail(ContentResolver cr, long origId, Bitmap thumb) {
        if (thumb == null) return false;
        try {
            Uri uri = getImageThumbnailUri(cr, origId, thumb.getWidth(), thumb.getHeight());
            if (uri == null) return false;
            OutputStream thumbOut = cr.openOutputStream(uri);
            thumb.compress(Bitmap.CompressFormat.JPEG, 85, thumbOut);
            thumbOut.close();
            return true;
        } catch (Throwable t) {
            Log.e(TAG, "Unable to store thumbnail", t);
            return false;
        }
    }

    /**
     * Store a given thumbnail in the database. (byte array)
     */
    private static boolean storeThumbnail(ContentResolver cr, long origId, byte[] jpegThumbnail,
            int width, int height) {
        if (jpegThumbnail == null) return false;

        Uri uri = getImageThumbnailUri(cr, origId, width, height);
        if (uri == null) {
            return false;
        }
        try {
            OutputStream thumbOut = cr.openOutputStream(uri);
            thumbOut.write(jpegThumbnail);
            thumbOut.close();
            return true;
        } catch (Throwable t) {
            Log.e(TAG, "Unable to store thumbnail", t);
            return false;
        }
    }

    /**
     * SizedThumbnailBitmap contains the bitmap, which is downsampled either from
     * the thumbnail in exif or the full image.