From 8932eef991d4a1c6181a1d44e2afdcb80aaf9f2b Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 2 Aug 2024 16:45:06 -0400 Subject: [PATCH] Convert some SignalServiceAttachment* classes to kotlin. --- .../securesms/attachments/Attachment.kt | 2 +- .../attachments/PointerAttachment.kt | 12 +- .../AttachmentKeyboardMediaAdapter.java | 2 +- .../forward/MultiselectForwardFragmentArgs.kt | 4 +- .../conversation/v2/ConversationFragment.kt | 10 +- .../securesms/database/MediaTable.kt | 2 +- .../mediapreview/MediaIntentFactory.kt | 16 +- .../MediaPreviewPlayerControlView.kt | 2 +- .../mediapreview/MediaPreviewV2Fragment.kt | 8 +- .../securesms/mediasend/Media.java | 27 +-- .../securesms/mediasend/MediaRepository.java | 12 +- .../mediasend/MediaUploadRepository.java | 12 +- .../mediasend/SentMediaQualityTransform.java | 2 +- .../securesms/mediasend/VideoTrimTransform.kt | 2 +- .../mediasend/v2/MediaSelectionRepository.kt | 12 +- .../mediasend/v2/MediaSelectionState.kt | 2 +- .../mediasend/v2/MediaSelectionViewModel.kt | 2 +- .../securesms/mediasend/v2/MediaValidator.kt | 12 +- .../v2/gallery/MediaGallerySelectableItem.kt | 2 +- .../v2/gallery/MediaGallerySelectedItem.kt | 2 +- .../v2/review/AddMessageDialogFragment.kt | 2 +- .../v2/review/MediaReviewFragment.kt | 22 +- .../review/MediaReviewFragmentPagerAdapter.kt | 10 +- .../InternalMessageDetailsFragment.kt | 2 +- .../InternalMessageDetailsViewModel.kt | 2 +- .../profiles/manage/EditProfileViewModel.java | 2 +- .../releasechannel/ReleaseChannel.kt | 38 ++-- .../securesms/sharing/MultiShareArgs.java | 2 +- .../securesms/sharing/MultiShareSender.java | 2 +- .../thoughtcrime/securesms/stories/Stories.kt | 8 +- .../securesms/util/ImageCompressionUtil.java | 14 +- .../securesms/util/MediaUtil.java | 4 +- .../securesms/util/SaveAttachmentTask.java | 9 +- .../mediasend/MediaRepositoryTest.kt | 6 +- .../api/messages/SignalServiceAttachment.java | 194 ------------------ .../api/messages/SignalServiceAttachment.kt | 178 ++++++++++++++++ .../SignalServiceAttachmentPointer.java | 166 --------------- .../SignalServiceAttachmentPointer.kt | 41 ++++ .../SignalServiceAttachmentStream.java | 179 ---------------- .../messages/SignalServiceAttachmentStream.kt | 78 +++++++ 40 files changed, 431 insertions(+), 673 deletions(-) delete mode 100644 libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachment.java create mode 100644 libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachment.kt delete mode 100644 libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentPointer.java create mode 100644 libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentPointer.kt delete mode 100644 libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java create mode 100644 libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt index 15d941f560..32f20a866b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt @@ -23,7 +23,7 @@ import java.util.UUID */ abstract class Attachment( @JvmField - val contentType: String, + val contentType: String?, @JvmField val transferState: Int, @JvmField diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt index 73e6997cf8..c98468740f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt @@ -17,7 +17,7 @@ import java.util.UUID class PointerAttachment : Attachment { @VisibleForTesting constructor( - contentType: String, + contentType: String?, transferState: Int, size: Long, fileName: String?, @@ -87,15 +87,11 @@ class PointerAttachment : Attachment { @JvmStatic @JvmOverloads fun forPointer(pointer: Optional, stickerLocator: StickerLocator? = null, fastPreflightId: String? = null, transferState: Int = AttachmentTable.TRANSFER_PROGRESS_PENDING): Optional { - if (!pointer.isPresent || !pointer.get().isPointer) { + if (!pointer.isPresent || !pointer.get().isPointer()) { return Optional.empty() } - val encodedKey: String? = if (pointer.get().asPointer().key != null) { - encodeWithPadding(pointer.get().asPointer().key) - } else { - null - } + val encodedKey: String? = pointer.get().asPointer().key?.let { encodeWithPadding(it) } return Optional.of( PointerAttachment( @@ -143,7 +139,7 @@ class PointerAttachment : Attachment { fileName = quotedAttachment.fileName, cdn = Cdn.fromCdnNumber(thumbnail?.asPointer()?.cdnNumber ?: 0), location = thumbnail?.asPointer()?.remoteId?.toString() ?: "0", - key = if (thumbnail != null && thumbnail.asPointer().key != null) encodeWithPadding(thumbnail.asPointer().key) else null, + key = thumbnail?.asPointer()?.key?.let { encodeWithPadding(it) }, digest = thumbnail?.asPointer()?.digest?.orElse(null), incrementalDigest = thumbnail?.asPointer()?.incrementalDigest?.orElse(null), incrementalMacChunkSize = thumbnail?.asPointer()?.incrementalMacChunkSize ?: 0, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/AttachmentKeyboardMediaAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/AttachmentKeyboardMediaAdapter.java index ef3a425af5..4d3f6c7a36 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/AttachmentKeyboardMediaAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/AttachmentKeyboardMediaAdapter.java @@ -140,7 +140,7 @@ class AttachmentKeyboardMediaAdapter extends RecyclerView.Adapter 0) { duration.setVisibility(View.VISIBLE); duration.setText(formatTime(media.getDuration())); - } else if (MediaUtil.isVideoType(media.getMimeType())) { + } else if (MediaUtil.isVideoType(media.getContentType())) { videoIcon.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragmentArgs.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragmentArgs.kt index 0aca847a74..e4c4ce3715 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragmentArgs.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragmentArgs.kt @@ -55,11 +55,11 @@ data class MultiselectForwardFragmentArgs @JvmOverloads constructor( companion object { @JvmStatic - fun create(context: Context, threadId: Long, mediaUri: Uri, mediaType: String, consumer: Consumer) { + fun create(context: Context, threadId: Long, mediaUri: Uri, contentType: String?, consumer: Consumer) { SignalExecutors.BOUNDED.execute { val multiShareArgs = MultiShareArgs.Builder(setOf()) .withDataUri(mediaUri) - .withDataType(mediaType) + .withDataType(contentType) .build() val sendButtonColors: ViewColorSet? = threadId.takeIf { it > 0 } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 133a91c746..d0f698907f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -3649,12 +3649,12 @@ class ConversationFragment : val slides: List = result.nonUploadedMedia.mapNotNull { when { - MediaUtil.isVideoType(it.mimeType) -> VideoSlide(requireContext(), it.uri, it.size, it.isVideoGif, it.width, it.height, it.caption.orNull(), it.transformProperties.orNull()) - MediaUtil.isGif(it.mimeType) -> GifSlide(requireContext(), it.uri, it.size, it.width, it.height, it.isBorderless, it.caption.orNull()) - MediaUtil.isImageType(it.mimeType) -> ImageSlide(requireContext(), it.uri, it.mimeType, it.size, it.width, it.height, it.isBorderless, it.caption.orNull(), null, it.transformProperties.orNull()) - MediaUtil.isDocumentType(it.mimeType) -> { DocumentSlide(requireContext(), it.uri, it.mimeType, it.size, it.fileName.orNull()) } + MediaUtil.isVideoType(it.contentType) -> VideoSlide(requireContext(), it.uri, it.size, it.isVideoGif, it.width, it.height, it.caption.orNull(), it.transformProperties.orNull()) + MediaUtil.isGif(it.contentType) -> GifSlide(requireContext(), it.uri, it.size, it.width, it.height, it.isBorderless, it.caption.orNull()) + MediaUtil.isImageType(it.contentType) -> ImageSlide(requireContext(), it.uri, it.contentType, it.size, it.width, it.height, it.isBorderless, it.caption.orNull(), null, it.transformProperties.orNull()) + MediaUtil.isDocumentType(it.contentType) -> { DocumentSlide(requireContext(), it.uri, it.contentType, it.size, it.fileName.orNull()) } else -> { - Log.w(TAG, "Asked to send an unexpected mimeType: '${it.mimeType}'. Skipping.") + Log.w(TAG, "Asked to send an unexpected mimeType: '${it.contentType}'. Skipping.") null } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt index 9ea66d9086..c50b0d343a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt @@ -246,7 +246,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD val isOutgoing: Boolean ) { - val contentType: String + val contentType: String? get() = attachment!!.contentType companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaIntentFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaIntentFactory.kt index d33c4552c6..8be7a3b859 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaIntentFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaIntentFactory.kt @@ -33,7 +33,7 @@ object MediaIntentFactory { val threadId: Long, val date: Long, val initialMediaUri: Uri, - val initialMediaType: String, + val initialMediaType: String?, val initialMediaSize: Long, val initialCaption: String? = null, val leftIsRecent: Boolean = false, @@ -68,13 +68,13 @@ object MediaIntentFactory { return create( context, MediaPreviewArgs( - mediaRecord.threadId, - mediaRecord.date, - attachment.uri!!, - attachment.contentType, - attachment.size, - attachment.caption, - leftIsRecent, + threadId = mediaRecord.threadId, + date = mediaRecord.date, + initialMediaUri = attachment.uri!!, + initialMediaType = attachment.contentType, + initialMediaSize = attachment.size, + initialCaption = attachment.caption, + leftIsRecent = leftIsRecent, allMediaInRail = allMediaInRail, sorting = MediaTable.Sorting.Newest, isVideoGif = attachment.videoGif, diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewPlayerControlView.kt b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewPlayerControlView.kt index 5fbb999b87..e0bc2334fb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewPlayerControlView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewPlayerControlView.kt @@ -50,7 +50,7 @@ class MediaPreviewPlayerControlView @JvmOverloads constructor( companion object { @JvmStatic - fun fromString(contentType: String): MediaMode { + fun fromString(contentType: String?): MediaMode { if (MediaUtil.isVideo(contentType)) return VIDEO if (MediaUtil.isImageType(contentType)) return IMAGE throw IllegalArgumentException("Unknown content type: $contentType") diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt index 534a9bf2d9..118da9f76c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt @@ -526,10 +526,10 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v val uri = attachment?.uri if (attachment != null && uri != null) { MultiselectForwardFragmentArgs.create( - requireContext(), - mediaItem.threadId, - uri, - attachment.contentType + context = requireContext(), + threadId = mediaItem.threadId, + mediaUri = uri, + contentType = attachment.contentType ) { args: MultiselectForwardFragmentArgs -> MultiselectForwardFragment.showBottomSheet(childFragmentManager, args) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/Media.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/Media.java index e08a6a07e1..eda183837f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/Media.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/Media.java @@ -5,6 +5,7 @@ import android.os.Parcel; import android.os.Parcelable; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import org.thoughtcrime.securesms.database.AttachmentTable; import org.thoughtcrime.securesms.util.MediaUtil; @@ -21,9 +22,9 @@ public class Media implements Parcelable { public static final String ALL_MEDIA_BUCKET_ID = "org.thoughtcrime.securesms.ALL_MEDIA"; - private final Uri uri; - private final String mimeType; - private final long date; + private final Uri uri; + private final String contentType; + private final long date; private final int width; private final int height; private final long size; @@ -37,7 +38,7 @@ public class Media implements Parcelable { private Optional fileName; public Media(@NonNull Uri uri, - @NonNull String mimeType, + @Nullable String contentType, long date, int width, int height, @@ -51,7 +52,7 @@ public class Media implements Parcelable { Optional fileName) { this.uri = uri; - this.mimeType = mimeType; + this.contentType = contentType; this.date = date; this.width = width; this.height = height; @@ -66,9 +67,9 @@ public class Media implements Parcelable { } protected Media(Parcel in) { - uri = in.readParcelable(Uri.class.getClassLoader()); - mimeType = in.readString(); - date = in.readLong(); + uri = in.readParcelable(Uri.class.getClassLoader()); + contentType = in.readString(); + date = in.readLong(); width = in.readInt(); height = in.readInt(); size = in.readLong(); @@ -90,8 +91,8 @@ public class Media implements Parcelable { return uri; } - public String getMimeType() { - return mimeType; + public String getContentType() { + return contentType; } public long getDate() { @@ -154,7 +155,7 @@ public class Media implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(uri, flags); - dest.writeString(mimeType); + dest.writeString(contentType); dest.writeLong(date); dest.writeInt(width); dest.writeInt(height); @@ -212,10 +213,10 @@ public class Media implements Parcelable { } public static @NonNull Media stripTransform(@NonNull Media media) { - Preconditions.checkArgument(MediaUtil.isImageType(media.mimeType)); + Preconditions.checkArgument(MediaUtil.isImageType(media.contentType)); return new Media(media.getUri(), - media.getMimeType(), + media.getContentType(), media.getDate(), media.getWidth(), media.getHeight(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaRepository.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaRepository.java index a764fa6146..ac85b7c530 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaRepository.java @@ -361,12 +361,12 @@ public class MediaRepository { } if (width == 0 || height == 0) { - Pair dimens = MediaUtil.getDimensions(context, media.getMimeType(), media.getUri()); + Pair dimens = MediaUtil.getDimensions(context, media.getContentType(), media.getUri()); width = dimens.first; height = dimens.second; } - return new Media(media.getUri(), media.getMimeType(), media.getDate(), width, height, size, 0, media.isBorderless(), media.isVideoGif(), media.getBucketId(), media.getCaption(), Optional.empty(), Optional.empty()); + return new Media(media.getUri(), media.getContentType(), media.getDate(), width, height, size, 0, media.isBorderless(), media.isVideoGif(), media.getBucketId(), media.getCaption(), Optional.empty(), Optional.empty()); } private Media getContentResolverPopulatedMedia(@NonNull Context context, @NonNull Media media) throws IOException { @@ -387,20 +387,20 @@ public class MediaRepository { } if (width == 0 || height == 0) { - Pair dimens = MediaUtil.getDimensions(context, media.getMimeType(), media.getUri()); + Pair dimens = MediaUtil.getDimensions(context, media.getContentType(), media.getUri()); width = dimens.first; height = dimens.second; } - return new Media(media.getUri(), media.getMimeType(), media.getDate(), width, height, size, 0, media.isBorderless(), media.isVideoGif(), media.getBucketId(), media.getCaption(), Optional.empty(), Optional.empty()); + return new Media(media.getUri(), media.getContentType(), media.getDate(), width, height, size, 0, media.isBorderless(), media.isVideoGif(), media.getBucketId(), media.getCaption(), Optional.empty(), Optional.empty()); } @VisibleForTesting public static @NonNull Media fixMimeType(@NonNull Context context, @NonNull Media media) { - if (MediaUtil.isOctetStream(media.getMimeType())) { + if (MediaUtil.isOctetStream(media.getContentType())) { Log.w(TAG, "Media has mimetype octet stream"); String newMimeType = MediaUtil.getMimeType(context, media.getUri()); - if (newMimeType != null && !newMimeType.equals(media.getMimeType())) { + if (newMimeType != null && !newMimeType.equals(media.getContentType())) { Log.d(TAG, "Changing mime type to '" + newMimeType + "'"); return Media.withMimeType(media, newMimeType); } else if (media.getSize() > 0 && media.getWidth() > 0 && media.getHeight() > 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java index 56af8c3229..1789d163ad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaUploadRepository.java @@ -214,16 +214,16 @@ public class MediaUploadRepository { } public static @NonNull Attachment asAttachment(@NonNull Context context, @NonNull Media media) { - if (MediaUtil.isVideoType(media.getMimeType())) { + if (MediaUtil.isVideoType(media.getContentType())) { return new VideoSlide(context, media.getUri(), media.getSize(), media.isVideoGif(), media.getWidth(), media.getHeight(), media.getCaption().orElse(null), media.getTransformProperties().orElse(null)).asAttachment(); - } else if (MediaUtil.isGif(media.getMimeType())) { + } else if (MediaUtil.isGif(media.getContentType())) { return new GifSlide(context, media.getUri(), media.getSize(), media.getWidth(), media.getHeight(), media.isBorderless(), media.getCaption().orElse(null)).asAttachment(); - } else if (MediaUtil.isImageType(media.getMimeType())) { - return new ImageSlide(context, media.getUri(), media.getMimeType(), media.getSize(), media.getWidth(), media.getHeight(), media.isBorderless(), media.getCaption().orElse(null), null, media.getTransformProperties().orElse(null)).asAttachment(); - } else if (MediaUtil.isTextType(media.getMimeType())) { + } else if (MediaUtil.isImageType(media.getContentType())) { + return new ImageSlide(context, media.getUri(), media.getContentType(), media.getSize(), media.getWidth(), media.getHeight(), media.isBorderless(), media.getCaption().orElse(null), null, media.getTransformProperties().orElse(null)).asAttachment(); + } else if (MediaUtil.isTextType(media.getContentType())) { return new TextSlide(context, media.getUri(), null, media.getSize()).asAttachment(); } else { - throw new AssertionError("Unexpected mimeType: " + media.getMimeType()); + throw new AssertionError("Unexpected mimeType: " + media.getContentType()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/SentMediaQualityTransform.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/SentMediaQualityTransform.java index 1b49c2e90a..551d6e1cc1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/SentMediaQualityTransform.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/SentMediaQualityTransform.java @@ -27,7 +27,7 @@ public final class SentMediaQualityTransform implements MediaTransform { @Override public @NonNull Media transform(@NonNull Context context, @NonNull Media media) { return new Media(media.getUri(), - media.getMimeType(), + media.getContentType(), media.getDate(), media.getWidth(), media.getHeight(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.kt index 6365c5e450..857c20e418 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.kt @@ -12,7 +12,7 @@ class VideoTrimTransform(private val data: VideoTrimData) : MediaTransform { override fun transform(context: Context, media: Media): Media { return Media( media.uri, - media.mimeType, + media.contentType, media.date, media.width, media.height, diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt index 958e40841e..0a91a35701 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionRepository.kt @@ -153,7 +153,7 @@ class MediaSelectionRepository(context: Context) { scheduleMessages(sendType, contacts.map { it.recipientId }, trimmedBody, updatedMedia, trimmedMentions, trimmedBodyRanges, isViewOnce, scheduledTime) emitter.onComplete() } - } else if (MediaUtil.isDocumentType(selectedMedia.first().mimeType)) { + } else if (MediaUtil.isDocumentType(selectedMedia.first().contentType)) { Log.i(TAG, "Document. Skipping pre-upload.") emitter.onSuccess( MediaSendActivityResult( @@ -315,14 +315,14 @@ class MediaSelectionRepository(context: Context) { val context: Context = AppDependencies.application for (mediaItem in nonUploadedMedia) { - if (MediaUtil.isVideoType(mediaItem.mimeType)) { + if (MediaUtil.isVideoType(mediaItem.contentType)) { slideDeck.addSlide(VideoSlide(context, mediaItem.uri, mediaItem.size, mediaItem.isVideoGif, mediaItem.width, mediaItem.height, mediaItem.caption.orElse(null), mediaItem.transformProperties.orElse(null))) - } else if (MediaUtil.isGif(mediaItem.mimeType)) { + } else if (MediaUtil.isGif(mediaItem.contentType)) { slideDeck.addSlide(GifSlide(context, mediaItem.uri, mediaItem.size, mediaItem.width, mediaItem.height, mediaItem.isBorderless, mediaItem.caption.orElse(null))) - } else if (MediaUtil.isImageType(mediaItem.mimeType)) { - slideDeck.addSlide(ImageSlide(context, mediaItem.uri, mediaItem.mimeType, mediaItem.size, mediaItem.width, mediaItem.height, mediaItem.isBorderless, mediaItem.caption.orElse(null), null, mediaItem.transformProperties.orElse(null))) + } else if (MediaUtil.isImageType(mediaItem.contentType)) { + slideDeck.addSlide(ImageSlide(context, mediaItem.uri, mediaItem.contentType, mediaItem.size, mediaItem.width, mediaItem.height, mediaItem.isBorderless, mediaItem.caption.orElse(null), null, mediaItem.transformProperties.orElse(null))) } else { - Log.w(TAG, "Asked to send an unexpected mimeType: '" + mediaItem.mimeType + "'. Skipping.") + Log.w(TAG, "Asked to send an unexpected mimeType: '" + mediaItem.contentType + "'. Skipping.") } } val splitMessage = MessageUtil.getSplitMessage(context, body, sendType.calculateCharacters(body).maxPrimaryMessageSize) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionState.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionState.kt index ed5ebc941c..3f107a07f9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionState.kt @@ -32,7 +32,7 @@ data class MediaSelectionState( val suppressEmptyError: Boolean = true ) { - val isVideoTrimmingVisible: Boolean = focusedMedia != null && MediaUtil.isVideoType(focusedMedia.mimeType) && MediaConstraints.isVideoTranscodeAvailable() && !focusedMedia.isVideoGif + val isVideoTrimmingVisible: Boolean = focusedMedia != null && MediaUtil.isVideoType(focusedMedia.contentType) && MediaConstraints.isVideoTranscodeAvailable() && !focusedMedia.isVideoGif val transcodingPreset: TranscodingPreset = MediaConstraints.getPushMediaConstraints(SentMediaQuality.fromCode(quality.code)).videoTranscodingSettings diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionViewModel.kt index f5c519e220..ce1d101efa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaSelectionViewModel.kt @@ -421,7 +421,7 @@ class MediaSelectionViewModel( } val filteredPreUploadMedia = if (destination is MediaSelectionDestination.SingleRecipient || !Stories.isFeatureEnabled()) { - media.filter { !MediaUtil.isDocumentType(it.mimeType) } + media.filter { !MediaUtil.isDocumentType(it.contentType) } } else { media.filter { Stories.MediaTransform.canPreUploadMedia(it) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaValidator.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaValidator.kt index 98c42e971f..a50f12c456 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaValidator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/MediaValidator.kt @@ -17,7 +17,7 @@ object MediaValidator { var error: FilterError? = null if (!isAllMediaValid) { - error = if (media.all { MediaUtil.isImageOrVideoType(it.mimeType) || MediaUtil.isDocumentType(it.mimeType) }) { + error = if (media.all { MediaUtil.isImageOrVideoType(it.contentType) || MediaUtil.isDocumentType(it.contentType) }) { FilterError.ItemTooLarge } else { FilterError.ItemInvalidType @@ -51,9 +51,9 @@ object MediaValidator { @WorkerThread private fun filterForValidMedia(context: Context, media: List, mediaConstraints: MediaConstraints, isStory: Boolean): List { return media - .filter { m -> isSupportedMediaType(m.mimeType) } + .filter { m -> isSupportedMediaType(m.contentType) } .filter { m -> - MediaUtil.isImageAndNotGif(m.mimeType) || isValidGif(context, m, mediaConstraints) || isValidVideo(context, m, mediaConstraints) || isValidDocument(context, m, mediaConstraints) + MediaUtil.isImageAndNotGif(m.contentType) || isValidGif(context, m, mediaConstraints) || isValidVideo(context, m, mediaConstraints) || isValidDocument(context, m, mediaConstraints) } .filter { m -> !isStory || Stories.MediaTransform.getSendRequirements(m) != Stories.MediaTransform.SendRequirements.CAN_NOT_SEND @@ -61,15 +61,15 @@ object MediaValidator { } private fun isValidGif(context: Context, media: Media, mediaConstraints: MediaConstraints): Boolean { - return MediaUtil.isGif(media.mimeType) && media.size < mediaConstraints.getGifMaxSize(context) + return MediaUtil.isGif(media.contentType) && media.size < mediaConstraints.getGifMaxSize(context) } private fun isValidVideo(context: Context, media: Media, mediaConstraints: MediaConstraints): Boolean { - return MediaUtil.isVideoType(media.mimeType) && media.size < mediaConstraints.getUncompressedVideoMaxSize(context) + return MediaUtil.isVideoType(media.contentType) && media.size < mediaConstraints.getUncompressedVideoMaxSize(context) } private fun isValidDocument(context: Context, media: Media, mediaConstraints: MediaConstraints): Boolean { - return MediaUtil.isDocumentType(media.mimeType) && media.size < mediaConstraints.getDocumentMaxSize(context) + return MediaUtil.isDocumentType(media.contentType) && media.size < mediaConstraints.getDocumentMaxSize(context) } private fun isSupportedMediaType(mimeType: String): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectableItem.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectableItem.kt index 00ab0d08ea..46b717207d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectableItem.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectableItem.kt @@ -115,7 +115,7 @@ object MediaGallerySelectableItem { checkView?.visible = model.isSelected checkView?.text = "${model.selectionOneBasedIndex}" itemView.setOnClickListener { onMediaClicked(model.media, model.isSelected) } - playOverlay?.visible = MediaUtil.isVideo(model.media.mimeType) && !model.media.isVideoGif + playOverlay?.visible = MediaUtil.isVideo(model.media.contentType) && !model.media.isVideoGif title?.visible = false if (PAYLOAD_INDEX_CHANGED in payload) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectedItem.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectedItem.kt index de6e0f9924..4976863741 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectedItem.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGallerySelectedItem.kt @@ -42,7 +42,7 @@ object MediaGallerySelectedItem { .centerCrop() .into(imageView) - videoOverlay.visible = MediaUtil.isVideo(model.media.mimeType) && !model.media.isVideoGif + videoOverlay.visible = MediaUtil.isVideo(model.media.contentType) && !model.media.isVideoGif itemView.setOnClickListener { onSelectedMediaClicked(model.media) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/AddMessageDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/AddMessageDialogFragment.kt index a5df1fac7e..d748799282 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/AddMessageDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/AddMessageDialogFragment.kt @@ -129,7 +129,7 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a binding.content.addAMessageInput.text = null dismiss() } - binding.content.viewOnceToggle.visible = state.selectedMedia.size == 1 && !state.isStory && !MediaUtil.isDocumentType(state.focusedMedia?.mimeType) + binding.content.viewOnceToggle.visible = state.selectedMedia.size == 1 && !state.isStory && !MediaUtil.isDocumentType(state.focusedMedia?.contentType) } initializeMentions() diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragment.kt index df18b34c45..8455318176 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragment.kt @@ -220,7 +220,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul SimpleTask.run(viewLifecycleOwner.lifecycle, { snapshot.selectedMedia.take(2).map { media -> val editorData = snapshot.editorStateMap[media.uri] - if (MediaUtil.isImageType(media.mimeType) && editorData != null && editorData is ImageEditorFragment.Data) { + if (MediaUtil.isImageType(media.contentType) && editorData != null && editorData is ImageEditorFragment.Data) { val model = editorData.readModel() if (model != null) { ImageEditorFragment.renderToSingleUseBlob(requireContext(), model) @@ -388,14 +388,14 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul } else { getString(R.string.MediaReviewFragment__video_set_to_standard_quality) } - } else if (MediaUtil.isImageType(media.mimeType)) { + } else if (MediaUtil.isImageType(media.contentType)) { if (state.quality == SentMediaQuality.HIGH) { getString(R.string.MediaReviewFragment__photo_set_to_high_quality) } else { getString(R.string.MediaReviewFragment__photo_set_to_standard_quality) } } else { - Log.i(TAG, "Could not display quality toggle toast for attachment of type: ${media.mimeType}") + Log.i(TAG, "Could not display quality toggle toast for attachment of type: ${media.contentType}") return } } else { @@ -484,7 +484,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul private fun presentImageQualityToggle(state: MediaSelectionState) { qualityButton.updateLayoutParams { - if (MediaUtil.isImageAndNotGif(state.focusedMedia?.mimeType ?: "")) { + if (MediaUtil.isImageAndNotGif(state.focusedMedia?.contentType ?: "")) { startToStart = ConstraintLayout.LayoutParams.UNSET startToEnd = cropAndRotateButton.id } else { @@ -540,7 +540,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul private fun presentVideoTimeline(state: MediaSelectionState) { val mediaItem = state.focusedMedia ?: return - if (!MediaUtil.isVideoType(mediaItem.mimeType) || !MediaConstraints.isVideoTranscodeAvailable()) { + if (!MediaUtil.isVideoType(mediaItem.contentType) || !MediaConstraints.isVideoTranscodeAvailable()) { return } val uri = mediaItem.uri @@ -659,7 +659,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul } private fun computeViewOnceButtonAnimators(state: MediaSelectionState): List { - return if (state.isTouchEnabled && state.selectedMedia.size == 1 && !state.isStory && !MediaUtil.isDocumentType(state.focusedMedia?.mimeType)) { + return if (state.isTouchEnabled && state.selectedMedia.size == 1 && !state.isStory && !MediaUtil.isDocumentType(state.focusedMedia?.contentType)) { listOf(MediaReviewAnimatorController.getFadeInAnimator(viewOnceButton)) } else { listOf(MediaReviewAnimatorController.getFadeOutAnimator(viewOnceButton)) @@ -676,7 +676,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul private fun computeAddMediaButtonsAnimators(state: MediaSelectionState): List { return when { - !state.isTouchEnabled || state.viewOnceToggleState == MediaSelectionState.ViewOnceToggleState.ONCE || MediaUtil.isDocumentType(state.focusedMedia?.mimeType) -> { + !state.isTouchEnabled || state.viewOnceToggleState == MediaSelectionState.ViewOnceToggleState.ONCE || MediaUtil.isDocumentType(state.focusedMedia?.contentType) -> { listOf( MediaReviewAnimatorController.getFadeOutAnimator(addMediaButton), MediaReviewAnimatorController.getFadeOutAnimator(selectionRecycler) @@ -710,7 +710,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul } private fun computeSaveButtonAnimators(state: MediaSelectionState): List { - return if (state.isTouchEnabled && !MediaUtil.isVideo(state.focusedMedia?.mimeType) && !MediaUtil.isDocumentType(state.focusedMedia?.mimeType)) { + return if (state.isTouchEnabled && !MediaUtil.isVideo(state.focusedMedia?.contentType) && !MediaUtil.isDocumentType(state.focusedMedia?.contentType)) { listOf( MediaReviewAnimatorController.getFadeInAnimator(saveButton) ) @@ -722,7 +722,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul } private fun computeQualityButtonAnimators(state: MediaSelectionState): List { - return if (state.isTouchEnabled && !state.isStory && !MediaUtil.isDocumentType(state.focusedMedia?.mimeType)) { + return if (state.isTouchEnabled && !state.isStory && !MediaUtil.isDocumentType(state.focusedMedia?.contentType)) { listOf(MediaReviewAnimatorController.getFadeInAnimator(qualityButton)) } else { listOf(MediaReviewAnimatorController.getFadeOutAnimator(qualityButton)) @@ -730,7 +730,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul } private fun computeCropAndRotateButtonAnimators(state: MediaSelectionState): List { - return if (state.isTouchEnabled && MediaUtil.isImageAndNotGif(state.focusedMedia?.mimeType ?: "")) { + return if (state.isTouchEnabled && MediaUtil.isImageAndNotGif(state.focusedMedia?.contentType ?: "")) { listOf(MediaReviewAnimatorController.getFadeInAnimator(cropAndRotateButton)) } else { listOf(MediaReviewAnimatorController.getFadeOutAnimator(cropAndRotateButton)) @@ -738,7 +738,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul } private fun computeDrawToolButtonAnimators(state: MediaSelectionState): List { - return if (state.isTouchEnabled && MediaUtil.isImageAndNotGif(state.focusedMedia?.mimeType ?: "")) { + return if (state.isTouchEnabled && MediaUtil.isImageAndNotGif(state.focusedMedia?.contentType ?: "")) { listOf(MediaReviewAnimatorController.getFadeInAnimator(drawToolButton)) } else { listOf(MediaReviewAnimatorController.getFadeOutAnimator(drawToolButton)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragmentPagerAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragmentPagerAdapter.kt index 55b72a8fdf..f755e4fece 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragmentPagerAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/review/MediaReviewFragmentPagerAdapter.kt @@ -44,12 +44,12 @@ class MediaReviewFragmentPagerAdapter(fragment: Fragment) : FragmentStateAdapter val mediaItem: Media = mediaList[position] return when { - MediaUtil.isGif(mediaItem.mimeType) -> MediaReviewGifPageFragment.newInstance(mediaItem.uri) - MediaUtil.isImageType(mediaItem.mimeType) -> MediaReviewImagePageFragment.newInstance(mediaItem.uri) - MediaUtil.isVideoType(mediaItem.mimeType) -> MediaReviewVideoPageFragment.newInstance(mediaItem.uri, mediaItem.isVideoGif) - MediaUtil.isDocumentType(mediaItem.mimeType) -> MediaReviewDocumentPageFragment.newInstance(mediaItem) + MediaUtil.isGif(mediaItem.contentType) -> MediaReviewGifPageFragment.newInstance(mediaItem.uri) + MediaUtil.isImageType(mediaItem.contentType) -> MediaReviewImagePageFragment.newInstance(mediaItem.uri) + MediaUtil.isVideoType(mediaItem.contentType) -> MediaReviewVideoPageFragment.newInstance(mediaItem.uri, mediaItem.isVideoGif) + MediaUtil.isDocumentType(mediaItem.contentType) -> MediaReviewDocumentPageFragment.newInstance(mediaItem) else -> { - throw UnsupportedOperationException("Can only render images and videos. Found mimetype: '" + mediaItem.mimeType + "'") + throw UnsupportedOperationException("Can only render images and videos. Found mimetype: '" + mediaItem.contentType + "'") } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsFragment.kt index e60e1fd0f2..a9d3ae6a8d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsFragment.kt @@ -197,7 +197,7 @@ private fun AttachmentBlock(attachment: AttachmentInfo) { ) ClickToCopyRow( name = "Content Type", - value = attachment.contentType + value = attachment.contentType ?: "null" ) ClickToCopyRow( name = "Start Hash", diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsViewModel.kt index b8d4d7004f..73aa14aa24 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/InternalMessageDetailsViewModel.kt @@ -62,7 +62,7 @@ class InternalMessageDetailsViewModel(val messageId: Long) : ViewModel() { data class AttachmentInfo( val id: Long, - val contentType: String, + val contentType: String?, val size: Long, val fileName: String?, val hashStart: String?, diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java index d4559265ea..2b5f0ff969 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/manage/EditProfileViewModel.java @@ -140,7 +140,7 @@ class EditProfileViewModel extends ViewModel { internalAvatarState.postValue(InternalAvatarState.loading(data)); - repository.setAvatar(context, data, media.getMimeType(), result -> { + repository.setAvatar(context, data, media.getContentType(), result -> { switch (result) { case SUCCESS: internalAvatarState.postValue(InternalAvatarState.loaded(data)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/releasechannel/ReleaseChannel.kt b/app/src/main/java/org/thoughtcrime/securesms/releasechannel/ReleaseChannel.kt index 5c4de0662d..99b284bd43 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/releasechannel/ReleaseChannel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/releasechannel/ReleaseChannel.kt @@ -35,25 +35,25 @@ object ReleaseChannel { ): MessageTable.InsertResult? { val attachments: Optional> = if (media != null) { val attachment = SignalServiceAttachmentPointer( - Cdn.S3.cdnNumber, - SignalServiceAttachmentRemoteId.S3, - mediaType, - null, - Optional.empty(), - Optional.empty(), - mediaWidth, - mediaHeight, - Optional.empty(), - Optional.empty(), - 0, - Optional.of(media), - false, - false, - MediaUtil.isVideo(mediaType), - Optional.empty(), - Optional.empty(), - System.currentTimeMillis(), - mediaAttachmentUuid + cdnNumber = Cdn.S3.cdnNumber, + remoteId = SignalServiceAttachmentRemoteId.S3, + contentType = mediaType, + key = null, + size = Optional.empty(), + preview = Optional.empty(), + width = mediaWidth, + height = mediaHeight, + digest = Optional.empty(), + incrementalDigest = Optional.empty(), + incrementalMacChunkSize = 0, + fileName = Optional.of(media), + voiceNote = false, + isBorderless = false, + isGif = MediaUtil.isVideo(mediaType), + caption = Optional.empty(), + blurHash = Optional.empty(), + uploadTimestamp = System.currentTimeMillis(), + uuid = mediaAttachmentUuid ) Optional.of(listOf(attachment)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareArgs.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareArgs.java index 39c6bc938b..f73b55c4eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareArgs.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareArgs.java @@ -182,7 +182,7 @@ public final class MultiShareArgs implements Parcelable { } return isTextStory || - (!media.isEmpty() && media.stream().allMatch(m -> MediaUtil.isStorySupportedType(m.getMimeType()))) || + (!media.isEmpty() && media.stream().allMatch(m -> MediaUtil.isStorySupportedType(m.getContentType()))) || MediaUtil.isStorySupportedType(dataType) || isValidForTextStoryGeneration(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java index 36ccd1b412..fe62d72757 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/MultiShareSender.java @@ -437,7 +437,7 @@ public final class MultiShareSender { slideDeck.addSlide(new StickerSlide(context, multiShareArgs.getDataUri(), 0, multiShareArgs.getStickerLocator(), multiShareArgs.getDataType())); } else if (!multiShareArgs.getMedia().isEmpty()) { for (Media media : multiShareArgs.getMedia()) { - Slide slide = SlideFactory.getSlide(context, media.getMimeType(), media.getUri(), media.getWidth(), media.getHeight(), media.getTransformProperties().orElse(null)); + Slide slide = SlideFactory.getSlide(context, media.getContentType(), media.getUri(), media.getWidth(), media.getHeight(), media.getTransformProperties().orElse(null)); if (slide != null) { slideDeck.addSlide(slide); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt index 33c40ffaa5..9547adf2c1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt @@ -200,7 +200,7 @@ object Stories { @WorkerThread fun canPreUploadMedia(media: Media): Boolean { return when { - MediaUtil.isVideo(media.mimeType) -> getSendRequirements(media) != SendRequirements.REQUIRES_CLIP + MediaUtil.isVideo(media.contentType) -> getSendRequirements(media) != SendRequirements.REQUIRES_CLIP else -> true } } @@ -239,11 +239,11 @@ object Stories { } private fun canClipMedia(media: Media): Boolean { - return MediaUtil.isVideo(media.mimeType) && MediaConstraints.isVideoTranscodeAvailable() + return MediaUtil.isVideo(media.contentType) && MediaConstraints.isVideoTranscodeAvailable() } private fun getContentDuration(media: Media): DurationResult { - return if (MediaUtil.isVideo(media.mimeType)) { + return if (MediaUtil.isVideo(media.contentType)) { val mediaDuration = if (media.duration == 0L && media.transformProperties.map(TransformProperties::shouldSkipTransform).orElse(true)) { getVideoDuration(media.uri) } else if (media.transformProperties.map { it.videoTrim }.orElse(false)) { @@ -349,7 +349,7 @@ object Stories { Log.d(TAG, "Transforming media clip: ${transformProperties.videoTrimStartTimeUs.microseconds.inWholeSeconds}s to ${transformProperties.videoTrimEndTimeUs.microseconds.inWholeSeconds}s") return Media( media.uri, - media.mimeType, + media.contentType, media.date, media.width, media.height, diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ImageCompressionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ImageCompressionUtil.java index e8cd01a4c3..dac71dbdd9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ImageCompressionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ImageCompressionUtil.java @@ -73,10 +73,10 @@ public final class ImageCompressionUtil { */ @WorkerThread public static @NonNull Result compress(@NonNull Context context, - @NonNull String mimeType, - @NonNull Object glideModel, - int maxDimension, - @IntRange(from = 0, to = 100) int quality) + @Nullable String contentType, + @NonNull Object glideModel, + int maxDimension, + @IntRange(from = 0, to = 100) int quality) throws BitmapDecodingException { Bitmap scaledBitmap; @@ -121,16 +121,16 @@ public final class ImageCompressionUtil { } ByteArrayOutputStream output = new ByteArrayOutputStream(); - Bitmap.CompressFormat format = mimeTypeToCompressFormat(mimeType); + Bitmap.CompressFormat format = mimeTypeToCompressFormat(contentType); scaledBitmap.compress(format, quality, output); byte[] data = output.toByteArray(); - Log.d(TAG, "[Input] mimeType: " + mimeType + " [Output] format: " + format + ", maxDimension: " + maxDimension + ", quality: " + quality + ", size(KiB): " + new ByteSize(data.length).getInWholeKibiBytes()); + Log.d(TAG, "[Input] mimeType: " + contentType + " [Output] format: " + format + ", maxDimension: " + maxDimension + ", quality: " + quality + ", size(KiB): " + new ByteSize(data.length).getInWholeKibiBytes()); return new Result(data, compressFormatToMimeType(format), scaledBitmap.getWidth(), scaledBitmap.getHeight()); } - private static @NonNull Bitmap.CompressFormat mimeTypeToCompressFormat(@NonNull String mimeType) { + private static @NonNull Bitmap.CompressFormat mimeTypeToCompressFormat(@Nullable String mimeType) { if (MediaUtil.isJpegType(mimeType) || MediaUtil.isHeicType(mimeType) || MediaUtil.isHeifType(mimeType) || diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java index 858ee2fc40..5fc605f44e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java @@ -76,7 +76,7 @@ public class MediaUtil { public static final String UNKNOWN = "*/*"; public static final String OCTET = "application/octet-stream"; - public static SlideType getSlideTypeFromContentType(@NonNull String contentType) { + public static SlideType getSlideTypeFromContentType(@Nullable String contentType) { if (isGif(contentType)) { return SlideType.GIF; } else if (isImageType(contentType)) { @@ -356,7 +356,7 @@ public class MediaUtil { } public static boolean isNonGifVideo(Media media) { - return isVideo(media.getMimeType()) && !media.isVideoGif(); + return isVideo(media.getContentType()) && !media.isVideoGif(); } public static boolean isImageType(String contentType) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SaveAttachmentTask.java b/app/src/main/java/org/thoughtcrime/securesms/util/SaveAttachmentTask.java index bcd2ed14af..d02e6574bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SaveAttachmentTask.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SaveAttachmentTask.java @@ -408,9 +408,12 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask size; - private final Optional preview; - private final Optional digest; - private final Optional incrementalDigest; - private final int incrementalMacChunkSize; - private final Optional fileName; - private final boolean voiceNote; - private final boolean borderless; - private final boolean gif; - private final int width; - private final int height; - private final Optional caption; - private final Optional blurHash; - private final long uploadTimestamp; - private final UUID uuid; - - public SignalServiceAttachmentPointer(int cdnNumber, - SignalServiceAttachmentRemoteId remoteId, - String contentType, - byte[] key, - Optional size, - Optional preview, - int width, - int height, - Optional digest, - Optional incrementalDigest, - int incrementalMacChunkSize, - Optional fileName, - boolean voiceNote, - boolean borderless, - boolean gif, - Optional caption, - Optional blurHash, - long uploadTimestamp, - @Nullable UUID uuid) - { - super(contentType); - this.cdnNumber = cdnNumber; - this.remoteId = remoteId; - this.key = key; - this.size = size; - this.preview = preview; - this.width = width; - this.height = height; - this.incrementalMacChunkSize = incrementalMacChunkSize; - this.digest = digest; - this.incrementalDigest = incrementalDigest; - this.fileName = fileName; - this.voiceNote = voiceNote; - this.borderless = borderless; - this.caption = caption; - this.blurHash = blurHash; - this.uploadTimestamp = uploadTimestamp; - this.gif = gif; - this.uuid = uuid; - } - - public int getCdnNumber() { - return cdnNumber; - } - - public SignalServiceAttachmentRemoteId getRemoteId() { - return remoteId; - } - - public byte[] getKey() { - return key; - } - - @Override - public boolean isStream() { - return false; - } - - @Override - public boolean isPointer() { - return true; - } - - public Optional getSize() { - return size; - } - - public Optional getFileName() { - return fileName; - } - - public Optional getPreview() { - return preview; - } - - public Optional getDigest() { - return digest; - } - - public Optional getIncrementalDigest() { - return incrementalDigest; - } - - public boolean getVoiceNote() { - return voiceNote; - } - - public boolean isBorderless() { - return borderless; - } - - public boolean isGif() { - return gif; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getIncrementalMacChunkSize() { - return incrementalMacChunkSize; - } - - public Optional getCaption() { - return caption; - } - - public Optional getBlurHash() { - return blurHash; - } - - public long getUploadTimestamp() { - return uploadTimestamp; - } - - public @Nullable UUID getUuid() { - return uuid; - } -} diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentPointer.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentPointer.kt new file mode 100644 index 0000000000..cd4b45628b --- /dev/null +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentPointer.kt @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014-2017 Open Whisper Systems + * + * Licensed according to the LICENSE file in this repository. + */ +package org.whispersystems.signalservice.api.messages + +import java.util.Optional +import java.util.UUID + +/** + * Represents a received SignalServiceAttachment "handle." This + * is a pointer to the actual attachment content, which needs to be + * retrieved using [SignalServiceMessageReceiver.retrieveAttachment] + * + * @author Moxie Marlinspike + */ +class SignalServiceAttachmentPointer( + val cdnNumber: Int, + val remoteId: SignalServiceAttachmentRemoteId, + contentType: String?, + val key: ByteArray?, + val size: Optional, + val preview: Optional, + val width: Int, + val height: Int, + val digest: Optional, + val incrementalDigest: Optional, + val incrementalMacChunkSize: Int, + val fileName: Optional, + val voiceNote: Boolean, + val isBorderless: Boolean, + val isGif: Boolean, + val caption: Optional, + val blurHash: Optional, + val uploadTimestamp: Long, + val uuid: UUID? +) : SignalServiceAttachment(contentType) { + override fun isStream() = false + override fun isPointer() = true +} diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java deleted file mode 100644 index afd859708d..0000000000 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Copyright (C) 2014-2016 Open Whisper Systems - * - * Licensed according to the LICENSE file in this repository. - */ - -package org.whispersystems.signalservice.api.messages; - - -import org.whispersystems.signalservice.internal.push.http.CancelationSignal; -import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; -import java.util.UUID; - -import javax.annotation.Nullable; - -/** - * Represents a local SignalServiceAttachment to be sent. - */ -public class SignalServiceAttachmentStream extends SignalServiceAttachment implements Closeable { - - private final InputStream inputStream; - private final long length; - private final Optional fileName; - private final ProgressListener listener; - private final CancelationSignal cancelationSignal; - private final Optional preview; - private final boolean voiceNote; - private final boolean borderless; - private final boolean gif; - private final boolean faststart; - private final int width; - private final int height; - private final long uploadTimestamp; - private final Optional caption; - private final Optional blurHash; - private final Optional resumableUploadSpec; - private final UUID uuid; - - public SignalServiceAttachmentStream(InputStream inputStream, - String contentType, - long length, - Optional fileName, - boolean voiceNote, - boolean borderless, - boolean gif, - boolean faststart, - ProgressListener listener, - CancelationSignal cancelationSignal) - { - this(inputStream, contentType, length, fileName, voiceNote, borderless, gif, faststart, Optional.empty(), 0, 0, System.currentTimeMillis(), Optional.empty(), Optional.empty(), listener, cancelationSignal, Optional.empty(), UUID.randomUUID()); - } - - public SignalServiceAttachmentStream(InputStream inputStream, - String contentType, - long length, - Optional fileName, - boolean voiceNote, - boolean borderless, - boolean gif, - boolean faststart, - Optional preview, - int width, - int height, - long uploadTimestamp, - Optional caption, - Optional blurHash, - ProgressListener listener, - CancelationSignal cancelationSignal, - Optional resumableUploadSpec, - @Nullable UUID uuid) - { - super(contentType); - this.inputStream = inputStream; - this.length = length; - this.fileName = fileName; - this.listener = listener; - this.voiceNote = voiceNote; - this.borderless = borderless; - this.gif = gif; - this.preview = preview; - this.faststart = faststart; - this.width = width; - this.height = height; - this.uploadTimestamp = uploadTimestamp; - this.caption = caption; - this.blurHash = blurHash; - this.cancelationSignal = cancelationSignal; - this.resumableUploadSpec = resumableUploadSpec; - this.uuid = uuid; - } - - @Override - public boolean isStream() { - return true; - } - - @Override - public boolean isPointer() { - return false; - } - - public InputStream getInputStream() { - return inputStream; - } - - public long getLength() { - return length; - } - - public Optional getFileName() { - return fileName; - } - - public ProgressListener getListener() { - return listener; - } - - public CancelationSignal getCancelationSignal() { - return cancelationSignal; - } - - public Optional getPreview() { - return preview; - } - - public boolean getVoiceNote() { - return voiceNote; - } - - public boolean isBorderless() { - return borderless; - } - - public boolean isGif() { - return gif; - } - - public boolean isFaststart() { - return faststart; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public Optional getCaption() { - return caption; - } - - public Optional getBlurHash() { - return blurHash; - } - - public long getUploadTimestamp() { - return uploadTimestamp; - } - - public Optional getResumableUploadSpec() { - return resumableUploadSpec; - } - - public @Nullable UUID getUuid() { - return uuid; - } - - @Override - public void close() throws IOException { - inputStream.close(); - } -} diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.kt new file mode 100644 index 0000000000..f5d0bd8615 --- /dev/null +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.kt @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2014-2016 Open Whisper Systems + * + * Licensed according to the LICENSE file in this repository. + */ +package org.whispersystems.signalservice.api.messages + +import org.whispersystems.signalservice.internal.push.http.CancelationSignal +import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec +import java.io.Closeable +import java.io.IOException +import java.io.InputStream +import java.util.Optional +import java.util.UUID + +/** + * Represents a local SignalServiceAttachment to be sent. + */ +class SignalServiceAttachmentStream( + val inputStream: InputStream, + contentType: String?, + val length: Long, + val fileName: Optional, + val voiceNote: Boolean, + val isBorderless: Boolean, + val isGif: Boolean, + val isFaststart: Boolean, + val preview: Optional, + val width: Int, + val height: Int, + val uploadTimestamp: Long, + val caption: Optional, + val blurHash: Optional, + val listener: ProgressListener?, + val cancelationSignal: CancelationSignal?, + val resumableUploadSpec: Optional, + val uuid: UUID? +) : SignalServiceAttachment(contentType!!), Closeable { + constructor( + inputStream: InputStream, + contentType: String?, + length: Long, + fileName: Optional, + voiceNote: Boolean, + borderless: Boolean, + gif: Boolean, + faststart: Boolean, + listener: ProgressListener?, + cancelationSignal: CancelationSignal? + ) : this( + inputStream = inputStream, + contentType = contentType, + length = length, + fileName = fileName, + voiceNote = voiceNote, + isBorderless = borderless, + isGif = gif, + isFaststart = faststart, + preview = Optional.empty(), + width = 0, + height = 0, + uploadTimestamp = System.currentTimeMillis(), + caption = Optional.empty(), + blurHash = Optional.empty(), + listener = listener, + cancelationSignal = cancelationSignal, + resumableUploadSpec = Optional.empty(), + uuid = UUID.randomUUID() + ) + + override fun isStream() = true + override fun isPointer() = false + + @Throws(IOException::class) + override fun close() { + inputStream.close() + } +}