Commit b2ba3d9d authored by Moxie Marlinspike's avatar Moxie Marlinspike Committed by Bastien Le Querrec

Support for generating video thumbnails

// FREEBIE

Upstream commit: https://github.com/signalapp/Signal-Android/commit/a4c17e5325827f4c44e29148adcaf10862dff33d
parent 2f59ce51
......@@ -10,6 +10,18 @@
android:scaleType="fitCenter"
android:contentDescription="@string/conversation_item__mms_image_description" />
<ImageView android:id="@+id/play_overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:clickable="false"
android:longClickable="false"
android:src="@drawable/ic_play_circle_outline_white_48dp"
android:tint="#77ffffff"
android:tintMode="src_in"
android:visibility="gone"/>
<ViewStub android:id="@+id/transfer_controls_stub"
android:layout_width="70dp"
android:layout_height="70dp"
......
......@@ -1131,9 +1131,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
for (Slide slide : attachmentManager.buildSlideDeck().getSlides()) {
if (slide.hasAudio()) drafts.add(new Draft(Draft.AUDIO, slide.getUri().toString()));
else if (slide.hasVideo()) drafts.add(new Draft(Draft.VIDEO, slide.getUri().toString()));
else if (slide.hasImage()) drafts.add(new Draft(Draft.IMAGE, slide.getUri().toString()));
if (slide.hasAudio() && slide.getUri() != null) drafts.add(new Draft(Draft.AUDIO, slide.getUri().toString()));
else if (slide.hasVideo() && slide.getUri() != null) drafts.add(new Draft(Draft.VIDEO, slide.getUri().toString()));
else if (slide.hasImage() && slide.getUri() != null) drafts.add(new Draft(Draft.IMAGE, slide.getUri().toString()));
}
return drafts;
......
......@@ -381,7 +381,7 @@ public class ConversationFragment extends Fragment
SaveAttachmentTask.showWarningDialog(getActivity(), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
for (Slide slide : message.getSlideDeck().getSlides()) {
if (slide.hasImage() || slide.hasVideo() || slide.hasAudio()) {
if ((slide.hasImage() || slide.hasVideo() || slide.hasAudio()) && slide.getUri() != null) {
SaveAttachmentTask saveTask = new SaveAttachmentTask(getActivity(), masterSecret);
saveTask.execute(new Attachment(slide.getUri(), slide.getContentType(), message.getDateReceived()));
return;
......
......@@ -394,7 +394,7 @@ public class ConversationListFragment extends Fragment
private void sendMediaDraft(DraftDatabase.Draft draft, long threadId, @Nullable String forcedValue) {
List<Attachment> attachment = new LinkedList<Attachment>();
attachment.add(new UriAttachment(Uri.parse(draft.getValue()), draft.getType() + "/*", AttachmentDatabase.TRANSFER_PROGRESS_DONE));
attachment.add(new UriAttachment(Uri.parse(draft.getValue()), draft.getType() + "/*", AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0));
OutgoingMediaMessage message = new OutgoingMediaMessage(recipients,
forcedValue != null ? forcedValue : "",
......
......@@ -87,21 +87,22 @@ public class ImageMediaAdapter extends CursorRecyclerViewAdapter<ViewHolder> {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), MediaPreviewActivity.class);
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, imageRecord.getDate());
intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, threadId);
if (!TextUtils.isEmpty(imageRecord.getAddress())) {
Recipients recipients = RecipientFactory.getRecipientsFromString(getContext(),
imageRecord.getAddress(),
true);
if (recipients != null && recipients.getPrimaryRecipient() != null) {
intent.putExtra(MediaPreviewActivity.RECIPIENT_EXTRA, recipients.getPrimaryRecipient().getRecipientId());
if (imageRecord.getAttachment().getDataUri() != null) {
Intent intent = new Intent(getContext(), MediaPreviewActivity.class);
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, imageRecord.getDate());
intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, threadId);
if (!TextUtils.isEmpty(imageRecord.getAddress())) {
Recipients recipients = RecipientFactory.getRecipientsFromString(getContext(),
imageRecord.getAddress(),
true);
if (recipients != null && recipients.getPrimaryRecipient() != null) {
intent.putExtra(MediaPreviewActivity.RECIPIENT_EXTRA, recipients.getPrimaryRecipient().getRecipientId());
}
}
intent.setDataAndType(imageRecord.getAttachment().getDataUri(), imageRecord.getContentType());
getContext().startActivity(intent);
}
intent.setDataAndType(imageRecord.getAttachment().getDataUri(), imageRecord.getContentType());
getContext().startActivity(intent);
}
}
}
package org.smssecure.smssecure.attachments;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
......@@ -23,10 +22,6 @@ public abstract class Attachment {
@Nullable
private final String relay;
// XXX - This shouldn't be here.
@Nullable
private Bitmap thumbnail;
public Attachment(@NonNull String contentType, int transferState, long size,
@Nullable String location, @Nullable String key, @Nullable String relay)
{
......@@ -76,13 +71,4 @@ public abstract class Attachment {
public String getRelay() {
return relay;
}
public void setThumbnail(@Nullable Bitmap thumbnail) {
this.thumbnail = thumbnail;
}
@Nullable
public Bitmap getThumbnail() {
return thumbnail;
}
}
package org.smssecure.smssecure.attachments;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.smssecure.smssecure.mms.PartAuthority;
......@@ -10,27 +10,38 @@ public class DatabaseAttachment extends Attachment {
private final AttachmentId attachmentId;
private final long mmsId;
private final boolean hasData;
private final boolean hasThumbnail;
public DatabaseAttachment(AttachmentId attachmentId, long mmsId, boolean hasData,
public DatabaseAttachment(AttachmentId attachmentId, long mmsId,
boolean hasData, boolean hasThumbnail,
String contentType, int transferProgress, long size,
String location, String key, String relay)
{
super(contentType, transferProgress, size, location, key, relay);
this.attachmentId = attachmentId;
this.hasData = hasData;
this.hasThumbnail = hasThumbnail;
this.mmsId = mmsId;
}
@Override
@NonNull
@Nullable
public Uri getDataUri() {
return PartAuthority.getAttachmentDataUri(attachmentId);
if (hasData) {
return PartAuthority.getAttachmentDataUri(attachmentId);
} else {
return null;
}
}
@Override
@NonNull
@Nullable
public Uri getThumbnailUri() {
return PartAuthority.getAttachmentThumbnailUri(attachmentId);
if (hasThumbnail) {
return PartAuthority.getAttachmentThumbnailUri(attachmentId);
} else {
return null;
}
}
public AttachmentId getAttachmentId() {
......@@ -56,4 +67,8 @@ public class DatabaseAttachment extends Attachment {
public boolean hasData() {
return hasData;
}
public boolean hasThumbnail() {
return hasThumbnail;
}
}
package org.smssecure.smssecure.attachments;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.smssecure.smssecure.crypto.MasterSecret;
import org.smssecure.smssecure.util.MediaUtil;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.io.InputStream;
import android.support.annotation.Nullable;
public class UriAttachment extends Attachment {
private final @NonNull Uri dataUri;
private final @NonNull Uri thumbnailUri;
public UriAttachment(@NonNull Uri uri, @NonNull String contentType, int transferState) {
this(uri, contentType, transferState, 0);
}
private final @NonNull Uri dataUri;
private final @Nullable Uri thumbnailUri;
public UriAttachment(@NonNull Uri uri, @NonNull String contentType, int transferState, long size) {
this(uri, uri, contentType, transferState, size);
}
public UriAttachment(@NonNull Uri dataUri, @NonNull Uri thumbnailUri,
public UriAttachment(@NonNull Uri dataUri, @Nullable Uri thumbnailUri,
@NonNull String contentType, int transferState, long size)
{
super(contentType, transferState, size, null, null, null);
......@@ -39,7 +28,7 @@ public class UriAttachment extends Attachment {
}
@Override
@NonNull
@Nullable
public Uri getThumbnailUri() {
return thumbnailUri;
}
......
......@@ -35,6 +35,7 @@ public class ThumbnailView extends FrameLayout {
private static final String TAG = ThumbnailView.class.getSimpleName();
private ImageView image;
private ImageView playOverlay;
private int backgroundColorHint;
private int radius;
private OnClickListener parentClickListener;
......@@ -57,8 +58,9 @@ public class ThumbnailView extends FrameLayout {
inflate(context, R.layout.thumbnail_view, this);
this.radius = getResources().getDimensionPixelSize(R.dimen.message_bubble_corner_radius);
this.image = (ImageView) findViewById(R.id.thumbnail_image);
this.radius = getResources().getDimensionPixelSize(R.dimen.message_bubble_corner_radius);
this.image = (ImageView) findViewById(R.id.thumbnail_image);
this.playOverlay = (ImageView) findViewById(R.id.play_overlay);
super.setOnClickListener(new ThumbnailClickDispatcher());
if (attrs != null) {
......@@ -103,6 +105,12 @@ public class ThumbnailView extends FrameLayout {
getTransferControls().setVisibility(View.GONE);
}
if (slide.getThumbnailUri() != null && slide.hasPlayOverlay() && slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE) {
this.playOverlay.setVisibility(View.VISIBLE);
} else {
this.playOverlay.setVisibility(View.GONE);
}
if (Util.equals(slide, this.slide)) {
Log.w(TAG, "Not re-loading slide " + slide.asAttachment().getDataUri());
return;
......
......@@ -21,9 +21,13 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
......@@ -41,7 +45,7 @@ import org.smssecure.smssecure.mms.PartAuthority;
import org.smssecure.smssecure.util.MediaUtil;
import org.smssecure.smssecure.util.MediaUtil.ThumbnailData;
import org.smssecure.smssecure.util.Util;
import org.smssecure.smssecure.util.VisibleForTesting;
import org.smssecure.smssecure.video.EncryptedMediaDataSource;
import java.io.File;
import java.io.FileNotFoundException;
......@@ -69,7 +73,7 @@ public class AttachmentDatabase extends Database {
static final String DATA = "_data";
static final String TRANSFER_STATE = "pending_push";
static final String SIZE = "data_size";
private static final String THUMBNAIL = "thumbnail";
static final String THUMBNAIL = "thumbnail";
static final String THUMBNAIL_ASPECT_RATIO = "aspect_ratio";
static final String UNIQUE_ID = "unique_id";
......@@ -82,7 +86,7 @@ public class AttachmentDatabase extends Database {
private static final String[] PROJECTION = new String[] {ROW_ID + " AS " + ATTACHMENT_ID_ALIAS,
MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION,
CONTENT_LOCATION, DATA, TRANSFER_STATE,
CONTENT_LOCATION, DATA, THUMBNAIL, TRANSFER_STATE,
SIZE, THUMBNAIL, THUMBNAIL_ASPECT_RATIO,
UNIQUE_ID};
......@@ -149,6 +153,7 @@ public class AttachmentDatabase extends Database {
notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId));
}
@VisibleForTesting
public @Nullable DatabaseAttachment getAttachment(AttachmentId attachmentId) {
SQLiteDatabase database = databaseHelper.getReadableDatabase();
Cursor cursor = null;
......@@ -310,6 +315,7 @@ public class AttachmentDatabase extends Database {
return new DatabaseAttachment(databaseAttachment.getAttachmentId(),
databaseAttachment.getMmsId(),
databaseAttachment.hasData(),
databaseAttachment.hasThumbnail(),
mediaStream.getMimeType(),
databaseAttachment.getTransferState(),
dataSize,
......@@ -431,6 +437,7 @@ public class AttachmentDatabase extends Database {
cursor.getLong(cursor.getColumnIndexOrThrow(UNIQUE_ID))),
cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)),
!cursor.isNull(cursor.getColumnIndexOrThrow(DATA)),
!cursor.isNull(cursor.getColumnIndexOrThrow(THUMBNAIL)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_TYPE)),
cursor.getInt(cursor.getColumnIndexOrThrow(TRANSFER_STATE)),
cursor.getLong(cursor.getColumnIndexOrThrow(SIZE)),
......@@ -471,11 +478,8 @@ public class AttachmentDatabase extends Database {
long rowId = database.insert(TABLE_NAME, null, contentValues);
AttachmentId attachmentId = new AttachmentId(rowId, uniqueId);
if (attachment.getThumbnail() != null && masterSecret != null) {
Log.w(TAG, "inserting pre-generated thumbnail");
ThumbnailData data = new ThumbnailData(attachment.getThumbnail());
updateAttachmentThumbnail(masterSecret, attachmentId, data.toDataStream(), data.getAspectRatio());
} else if (!attachment.isInProgress()) {
if (partData != null) {
Log.w(TAG, "Submitting thumbnail generation job...");
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret, attachmentId));
}
......@@ -498,21 +502,33 @@ public class AttachmentDatabase extends Database {
values.put(THUMBNAIL_ASPECT_RATIO, aspectRatio);
database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings());
Cursor cursor = database.query(TABLE_NAME, new String[] {MMS_ID}, PART_ID_WHERE, attachmentId.toStrings(), null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID))));
}
} finally {
if (cursor != null) cursor.close();
}
}
@VisibleForTesting
class ThumbnailFetchCallable implements Callable<InputStream> {
private final MasterSecret masterSecret;
private final AttachmentId attachmentId;
public ThumbnailFetchCallable(MasterSecret masterSecret, AttachmentId attachmentId) {
ThumbnailFetchCallable(MasterSecret masterSecret, AttachmentId attachmentId) {
this.masterSecret = masterSecret;
this.attachmentId = attachmentId;
}
@Override
public @Nullable InputStream call() throws Exception {
Log.w(TAG, "Executing thumbnail job...");
final InputStream stream = getDataStream(masterSecret, attachmentId, THUMBNAIL);
if (stream != null) {
......@@ -525,7 +541,13 @@ public class AttachmentDatabase extends Database {
return null;
}
ThumbnailData data = MediaUtil.generateThumbnail(context, masterSecret, attachment.getContentType(), attachment.getDataUri());
ThumbnailData data;
if (MediaUtil.isVideoType(attachment.getContentType())) {
data = generateVideoThumbnail(masterSecret, attachmentId);
} else{
data = MediaUtil.generateThumbnail(context, masterSecret, attachment.getContentType(), attachment.getDataUri());
}
if (data == null) {
return null;
......@@ -535,5 +557,28 @@ public class AttachmentDatabase extends Database {
return getDataStream(masterSecret, attachmentId, THUMBNAIL);
}
private ThumbnailData generateVideoThumbnail(MasterSecret masterSecret, AttachmentId attachmentId) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Video thumbnails not supported...");
return null;
}
File mediaFile = getAttachmentDataFile(attachmentId, DATA);
if (mediaFile == null) {
Log.w(TAG, "No data file found for video thumbnail...");
return null;
}
EncryptedMediaDataSource dataSource = new EncryptedMediaDataSource(masterSecret, mediaFile);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(dataSource);
Bitmap bitmap = retriever.getFrameAtTime(1000);
Log.w(TAG, "Generated video thumbnail...");
return new ThumbnailData(bitmap);
}
}
}
......@@ -19,6 +19,7 @@ public class ImageDatabase extends Database {
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFER_STATE + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.SIZE + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DATA + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.NORMALIZED_DATE_RECEIVED + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.ADDRESS + " "
+ "FROM " + AttachmentDatabase.TABLE_NAME + " LEFT JOIN " + MmsDatabase.TABLE_NAME
......@@ -45,19 +46,22 @@ public class ImageDatabase extends Database {
private final AttachmentId attachmentId;
private final long mmsId;
private final boolean hasData;
private final boolean hasThumbnail;
private final String contentType;
private final String address;
private final long date;
private final int transferState;
private final long size;
private ImageRecord(AttachmentId attachmentId, long mmsId, boolean hasData,
private ImageRecord(AttachmentId attachmentId, long mmsId,
boolean hasData, boolean hasThumbnail,
String contentType, String address, long date,
int transferState, long size)
{
this.attachmentId = attachmentId;
this.mmsId = mmsId;
this.hasData = hasData;
this.hasThumbnail = hasThumbnail;
this.contentType = contentType;
this.address = address;
this.date = date;
......@@ -72,6 +76,7 @@ public class ImageDatabase extends Database {
return new ImageRecord(attachmentId,
cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.MMS_ID)),
!cursor.isNull(cursor.getColumnIndexOrThrow(AttachmentDatabase.DATA)),
!cursor.isNull(cursor.getColumnIndexOrThrow(AttachmentDatabase.THUMBNAIL)),
cursor.getString(cursor.getColumnIndexOrThrow(AttachmentDatabase.CONTENT_TYPE)),
cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)),
cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.NORMALIZED_DATE_RECEIVED)),
......@@ -80,7 +85,7 @@ public class ImageDatabase extends Database {
}
public Attachment getAttachment() {
return new DatabaseAttachment(attachmentId, mmsId, hasData, contentType, transferState, size, null, null, null);
return new DatabaseAttachment(attachmentId, mmsId, hasData, hasThumbnail, contentType, transferState, size, null, null, null);
}
public String getContentType() {
......
......@@ -134,6 +134,7 @@ public class MmsDatabase extends MessagingDatabase {
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.CONTENT_DISPOSITION,
......@@ -480,6 +481,7 @@ public class MmsDatabase extends MessagingDatabase {
attachments.add(new DatabaseAttachment(databaseAttachment.getAttachmentId(),
databaseAttachment.getMmsId(),
databaseAttachment.hasData(),
databaseAttachment.hasThumbnail(),
databaseAttachment.getContentType(),
AttachmentDatabase.TRANSFER_PROGRESS_DONE,
databaseAttachment.getSize(),
......
......@@ -56,6 +56,7 @@ public class MmsSmsDatabase extends Database {
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.CONTENT_DISPOSITION,
......@@ -132,6 +133,7 @@ public class MmsSmsDatabase extends Database {
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.CONTENT_DISPOSITION,
......@@ -158,6 +160,7 @@ public class MmsSmsDatabase extends Database {
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.CONTENT_DISPOSITION,
......@@ -205,7 +208,10 @@ public class MmsSmsDatabase extends Database {
mmsColumnsPresent.add(AttachmentDatabase.ROW_ID);
mmsColumnsPresent.add(AttachmentDatabase.UNIQUE_ID);
mmsColumnsPresent.add(AttachmentDatabase.MMS_ID);
mmsColumnsPresent.add(AttachmentDatabase.SIZE);
mmsColumnsPresent.add(AttachmentDatabase.DATA);
mmsColumnsPresent.add(AttachmentDatabase.THUMBNAIL);
mmsColumnsPresent.add(AttachmentDatabase.CONTENT_TYPE);
mmsColumnsPresent.add(AttachmentDatabase.CONTENT_LOCATION);
mmsColumnsPresent.add(AttachmentDatabase.CONTENT_DISPOSITION);
......
......@@ -317,7 +317,7 @@ public class AttachmentManager {
}
private void previewImageDraft(final @NonNull Slide slide) {
if (MediaPreviewActivity.isContentTypeSupported(slide.getContentType()) && slide.getThumbnailUri() != null) {
if (MediaPreviewActivity.isContentTypeSupported(slide.getContentType()) && slide.getUri() != null) {
Intent intent = new Intent(context, MediaPreviewActivity.class);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, slide.asAttachment().getSize());
......
......@@ -33,7 +33,7 @@ import org.smssecure.smssecure.util.ResUtil;
public class AudioSlide extends Slide {
public AudioSlide(Context context, Uri uri, long dataSize) throws IOException {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.AUDIO_UNSPECIFIED, dataSize));
super(context, constructAttachmentFromUri(context, uri, MediaUtil.AUDIO_UNSPECIFIED, dataSize, false));
}
public AudioSlide(Context context, Attachment attachment) {
......
......@@ -20,7 +20,7 @@ public class GifSlide extends ImageSlide {
}
public GifSlide(Context context, Uri uri, long size) throws IOException {
super(context, constructAttachmentFromUri(context, uri, ContentType.IMAGE_GIF, size));
super(context, constructAttachmentFromUri(context, uri, ContentType.IMAGE_GIF, size, true));
}
@Override
......
......@@ -38,7 +38,7 @@ public class ImageSlide extends Slide {
}
public ImageSlide(Context context, Uri uri, long size) throws IOException {
super(context, constructAttachmentFromUri(context, uri, ContentType.IMAGE_JPEG, size));
super(context, constructAttachmentFromUri(context, uri, ContentType.IMAGE_JPEG, size, true));
}
@Override
......@@ -51,7 +51,9 @@ public class ImageSlide extends Slide {
return true;
}
@NonNull @Override public String getContentDescription() {
@NonNull
@Override
public String getContentDescription() {
return context.getString(R.string.Slide_image);
}
}
......@@ -99,13 +99,18 @@ public abstract class Slide {
return false;
}
public boolean hasPlayOverlay() {
return false;
}
protected static Attachment constructAttachmentFromUri(@NonNull Context context,
@NonNull Uri uri,
@NonNull String defaultMime,
long size)
long size,
boolean hasThumbnail)
{
Optional<String> resolvedType = Optional.fromNullable(MediaUtil.getMimeType(context, uri));
return new UriAttachment(uri, resolvedType.or(defaultMime), AttachmentDatabase.TRANSFER_PROGRESS_STARTED, size);
return new UriAttachment(uri, hasThumbnail ? uri : null, resolvedType.or(defaultMime), AttachmentDatabase.TRANSFER_PROGRESS_STARTED, size);
}
@Override
......
......@@ -21,7 +21,6 @@ import android.content.res.Resources.Theme;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.smssecure.smssecure.R;
import org.smssecure.smssecure.attachments.Attachment;
......@@ -30,12 +29,10 @@ import org.smssecure.smssecure.util.ResUtil;
import java.io.IOException;
import com.google.android.mms.pdu_alt.PduPart;
public class VideoSlide extends Slide {
public VideoSlide(Context context, Uri uri, long dataSize) throws IOException {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.VIDEO_UNSPECIFIED, dataSize));
super(context, constructAttachmentFromUri(context, uri, MediaUtil.VIDEO_UNSPECIFIED, dataSize, false));
}
public VideoSlide(Context context, Attachment attachment) {
......@@ -43,13 +40,12 @@ public class VideoSlide extends Slide {
}
@Override
@Nullable
public Uri getThumbnailUri() {
return null;
public boolean hasPlaceholder() {
return true;
}
@Override
public boolean hasPlaceholder() {
public boolean hasPlayOverlay() {
return true;
}
......@@ -68,7 +64,8 @@ public class VideoSlide extends Slide {
return true;
}
@NonNull @Override public String getContentDescription() {
@NonNull @Override
public String getContentDescription() {
return context.getString(R.string.Slide_video);
}
}
......@@ -29,6 +29,7 @@ import java.io.InputStream;
import java.util.concurrent.ExecutionException;