diff options
-rwxr-xr-x | media/java/android/mtp/MtpDatabase.java | 47 | ||||
-rw-r--r-- | media/jni/android_mtp_MtpDatabase.cpp | 10 |
2 files changed, 55 insertions, 2 deletions
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index a828e2d04347..e6962a14a2d0 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -27,7 +27,9 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.graphics.Bitmap; import android.media.ExifInterface; +import android.media.ThumbnailUtils; import android.net.Uri; import android.os.BatteryManager; import android.os.RemoteException; @@ -49,6 +51,7 @@ import dalvik.system.CloseGuard; import com.google.android.collect.Sets; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -71,6 +74,7 @@ import java.util.stream.IntStream; */ public class MtpDatabase implements AutoCloseable { private static final String TAG = MtpDatabase.class.getSimpleName(); + private static final int MAX_THUMB_SIZE = (200 * 1024); private final Context mContext; private final ContentProviderClient mMediaProvider; @@ -803,6 +807,28 @@ public class MtpDatabase implements AutoCloseable { return obj.getFormat(); } + private byte[] getThumbnailProcess(String path, Bitmap bitmap) { + try { + if (bitmap == null) { + Log.d(TAG, "getThumbnailProcess: Fail to generate thumbnail. Probably unsupported or corrupted image"); + return null; + } + + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream); + + if (byteStream.size() > MAX_THUMB_SIZE) + return null; + + byte[] byteArray = byteStream.toByteArray(); + + return byteArray; + } catch (OutOfMemoryError oomEx) { + Log.w(TAG, "OutOfMemoryError:" + oomEx); + } + return null; + } + @VisibleForNative private boolean getThumbnailInfo(int handle, long[] outLongs) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); @@ -825,6 +851,16 @@ public class MtpDatabase implements AutoCloseable { } catch (IOException e) { // ignore and fall through } + +// Note: above formats will fall through and go on below thumbnail generation if Exif processing fails + case MtpConstants.FORMAT_PNG: + case MtpConstants.FORMAT_GIF: + case MtpConstants.FORMAT_BMP: + outLongs[0] = MAX_THUMB_SIZE; + // only non-zero Width & Height needed. Actual size will be retrieved upon getThumbnailData by Host + outLongs[1] = 320; + outLongs[2] = 240; + return true; } return false; } @@ -847,6 +883,17 @@ public class MtpDatabase implements AutoCloseable { } catch (IOException e) { // ignore and fall through } + +// Note: above formats will fall through and go on below thumbnail generation if Exif processing fails + case MtpConstants.FORMAT_PNG: + case MtpConstants.FORMAT_GIF: + case MtpConstants.FORMAT_BMP: + { + Bitmap bitmap = ThumbnailUtils.createImageThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND); + byte[] byteArray = getThumbnailProcess(path, bitmap); + + return byteArray; + } } return null; } diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index 0a3b47b6f901..17189fd08688 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -820,7 +820,10 @@ MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle, switch (info.mFormat) { case MTP_FORMAT_EXIF_JPEG: case MTP_FORMAT_HEIF: - case MTP_FORMAT_JFIF: { + case MTP_FORMAT_JFIF: + case MTP_FORMAT_PNG: + case MTP_FORMAT_BMP: + case MTP_FORMAT_GIF: { env = AndroidRuntime::getJNIEnv(); if (env->CallBooleanMethod( mDatabase, method_getThumbnailInfo, (jint)handle, mLongBuffer)) { @@ -881,7 +884,10 @@ void* MtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) { switch (format) { case MTP_FORMAT_EXIF_JPEG: case MTP_FORMAT_HEIF: - case MTP_FORMAT_JFIF: { + case MTP_FORMAT_JFIF: + case MTP_FORMAT_PNG: + case MTP_FORMAT_BMP: + case MTP_FORMAT_GIF: { JNIEnv* env = AndroidRuntime::getJNIEnv(); jbyteArray thumbData = (jbyteArray) env->CallObjectMethod( mDatabase, method_getThumbnailData, (jint)handle); |