Add a util to safely set a MediaMetadataRetriever data source.

This commit is contained in:
Greyson Parrelli 2019-10-19 12:23:11 -04:00
parent 9ba1391a1e
commit c7f76c5d1c
4 changed files with 36 additions and 4 deletions

View file

@ -57,6 +57,7 @@ import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaMetadataRetrieverUtil;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.MediaUtil.ThumbnailData;
import org.thoughtcrime.securesms.util.StorageUtil;
@ -1082,7 +1083,7 @@ public class AttachmentDatabase extends Database {
if (dataSource == null) return null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(dataSource);
MediaMetadataRetrieverUtil.setDataSource(retriever, dataSource);
Bitmap bitmap = retriever.getFrameAtTime(1000);

View file

@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.service.GenericForegroundService;
import org.thoughtcrime.securesms.service.NotificationController;
import org.thoughtcrime.securesms.util.MediaMetadataRetrieverUtil;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@ -174,7 +175,7 @@ public final class AttachmentUploadJob extends BaseJob {
if (dataSource == null) return null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(dataSource);
MediaMetadataRetrieverUtil.setDataSource(retriever, dataSource);
Bitmap bitmap = retriever.getFrameAtTime(1000);

View file

@ -0,0 +1,30 @@
package org.thoughtcrime.securesms.util;
import android.media.MediaDataSource;
import android.media.MediaMetadataRetriever;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import java.io.IOException;
public final class MediaMetadataRetrieverUtil {
private MediaMetadataRetrieverUtil() {}
/**
* {@link MediaMetadataRetriever#setDataSource(MediaDataSource)} tends to crash in native code on
* specific devices, so this just a wrapper to convert that into an {@link IOException}.
*/
@RequiresApi(23)
public static void setDataSource(@NonNull MediaMetadataRetriever retriever,
@NonNull MediaDataSource dataSource)
throws IOException
{
try {
retriever.setDataSource(dataSource);
} catch (Exception e) {
throw new IOException(e);
}
}
}

View file

@ -300,9 +300,9 @@ public class MediaUtil {
MediaDataSource mediaDataSource = BlobProvider.getInstance().getMediaDataSource(context, uri);
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(mediaDataSource);
MediaMetadataRetrieverUtil.setDataSource(mediaMetadataRetriever, mediaDataSource);
return mediaMetadataRetriever.getFrameAtTime(1000);
} catch (Exception e) { // XXX Some devices are hitting a native crash in setDataSource. Not much we can do.
} catch (IOException e) {
Log.w(TAG, "failed to get thumbnail for video blob uri: " + uri, e);
return null;
}