Convert AttachmentTable and models to kotlin.
This commit is contained in:
parent
888a40a5c4
commit
3554f82ea3
62 changed files with 2626 additions and 2986 deletions
|
@ -1,319 +0,0 @@
|
|||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.os.ParcelCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.audio.AudioHash;
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.util.ParcelUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class Attachment implements Parcelable {
|
||||
|
||||
@NonNull
|
||||
private final String contentType;
|
||||
private final int transferState;
|
||||
private final long size;
|
||||
|
||||
@Nullable
|
||||
private final String fileName;
|
||||
|
||||
private final int cdnNumber;
|
||||
|
||||
@Nullable
|
||||
private final String location;
|
||||
|
||||
@Nullable
|
||||
private final String key;
|
||||
|
||||
@Nullable
|
||||
private final String relay;
|
||||
|
||||
@Nullable
|
||||
private final byte[] digest;
|
||||
|
||||
@Nullable
|
||||
private final byte[] incrementalDigest;
|
||||
|
||||
@Nullable
|
||||
private final String fastPreflightId;
|
||||
|
||||
private final boolean voiceNote;
|
||||
private final boolean borderless;
|
||||
private final boolean videoGif;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final boolean quote;
|
||||
private final long uploadTimestamp;
|
||||
private final int incrementalMacChunkSize;
|
||||
|
||||
@Nullable
|
||||
private final String caption;
|
||||
|
||||
@Nullable
|
||||
private final StickerLocator stickerLocator;
|
||||
|
||||
@Nullable
|
||||
private final BlurHash blurHash;
|
||||
|
||||
@Nullable
|
||||
private final AudioHash audioHash;
|
||||
|
||||
@NonNull
|
||||
private final TransformProperties transformProperties;
|
||||
|
||||
public Attachment(@NonNull String contentType,
|
||||
int transferState,
|
||||
long size,
|
||||
@Nullable String fileName,
|
||||
int cdnNumber,
|
||||
@Nullable String location,
|
||||
@Nullable String key,
|
||||
@Nullable String relay,
|
||||
@Nullable byte[] digest,
|
||||
@Nullable byte[] incrementalDigest,
|
||||
@Nullable String fastPreflightId,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
boolean videoGif,
|
||||
int width,
|
||||
int height,
|
||||
int incrementalMacChunkSize,
|
||||
boolean quote,
|
||||
long uploadTimestamp,
|
||||
@Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash,
|
||||
@Nullable AudioHash audioHash,
|
||||
@Nullable TransformProperties transformProperties)
|
||||
{
|
||||
this.contentType = contentType;
|
||||
this.transferState = transferState;
|
||||
this.size = size;
|
||||
this.fileName = fileName;
|
||||
this.cdnNumber = cdnNumber;
|
||||
this.location = location;
|
||||
this.key = key;
|
||||
this.relay = relay;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.fastPreflightId = fastPreflightId;
|
||||
this.voiceNote = voiceNote;
|
||||
this.borderless = borderless;
|
||||
this.videoGif = videoGif;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.incrementalMacChunkSize = incrementalMacChunkSize;
|
||||
this.quote = quote;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.stickerLocator = stickerLocator;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.audioHash = audioHash;
|
||||
this.transformProperties = transformProperties != null ? transformProperties : TransformProperties.empty();
|
||||
}
|
||||
|
||||
protected Attachment(Parcel in) {
|
||||
this.contentType = Objects.requireNonNull(in.readString());
|
||||
this.transferState = in.readInt();
|
||||
this.size = in.readLong();
|
||||
this.fileName = in.readString();
|
||||
this.cdnNumber = in.readInt();
|
||||
this.location = in.readString();
|
||||
this.key = in.readString();
|
||||
this.relay = in.readString();
|
||||
this.digest = ParcelUtil.readByteArray(in);
|
||||
this.incrementalDigest = ParcelUtil.readByteArray(in);
|
||||
this.fastPreflightId = in.readString();
|
||||
this.voiceNote = ParcelUtil.readBoolean(in);
|
||||
this.borderless = ParcelUtil.readBoolean(in);
|
||||
this.videoGif = ParcelUtil.readBoolean(in);
|
||||
this.width = in.readInt();
|
||||
this.height = in.readInt();
|
||||
this.incrementalMacChunkSize = in.readInt();
|
||||
this.quote = ParcelUtil.readBoolean(in);
|
||||
this.uploadTimestamp = in.readLong();
|
||||
this.stickerLocator = ParcelCompat.readParcelable(in, StickerLocator.class.getClassLoader(), StickerLocator.class);
|
||||
this.caption = in.readString();
|
||||
this.blurHash = ParcelCompat.readParcelable(in, BlurHash.class.getClassLoader(), BlurHash.class);
|
||||
this.audioHash = ParcelCompat.readParcelable(in, AudioHash.class.getClassLoader(), AudioHash.class);
|
||||
this.transformProperties = Objects.requireNonNull(ParcelCompat.readParcelable(in, TransformProperties.class.getClassLoader(), TransformProperties.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
AttachmentCreator.writeSubclass(dest, this);
|
||||
dest.writeString(contentType);
|
||||
dest.writeInt(transferState);
|
||||
dest.writeLong(size);
|
||||
dest.writeString(fileName);
|
||||
dest.writeInt(cdnNumber);
|
||||
dest.writeString(location);
|
||||
dest.writeString(key);
|
||||
dest.writeString(relay);
|
||||
ParcelUtil.writeByteArray(dest, digest);
|
||||
ParcelUtil.writeByteArray(dest, incrementalDigest);
|
||||
dest.writeString(fastPreflightId);
|
||||
ParcelUtil.writeBoolean(dest, voiceNote);
|
||||
ParcelUtil.writeBoolean(dest, borderless);
|
||||
ParcelUtil.writeBoolean(dest, videoGif);
|
||||
dest.writeInt(width);
|
||||
dest.writeInt(height);
|
||||
dest.writeInt(incrementalMacChunkSize);
|
||||
ParcelUtil.writeBoolean(dest, quote);
|
||||
dest.writeLong(uploadTimestamp);
|
||||
dest.writeParcelable(stickerLocator, 0);
|
||||
dest.writeString(caption);
|
||||
dest.writeParcelable(blurHash, 0);
|
||||
dest.writeParcelable(audioHash, 0);
|
||||
dest.writeParcelable(transformProperties, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<Attachment> CREATOR = AttachmentCreator.INSTANCE;
|
||||
|
||||
@Nullable
|
||||
public abstract Uri getUri();
|
||||
|
||||
public abstract @Nullable Uri getPublicUri();
|
||||
|
||||
public int getTransferState() {
|
||||
return transferState;
|
||||
}
|
||||
|
||||
public boolean isInProgress() {
|
||||
return transferState != AttachmentTable.TRANSFER_PROGRESS_DONE &&
|
||||
transferState != AttachmentTable.TRANSFER_PROGRESS_FAILED &&
|
||||
transferState != AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE;
|
||||
}
|
||||
|
||||
public boolean isPermanentlyFailed() {
|
||||
return transferState == AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public int getCdnNumber() {
|
||||
return cdnNumber;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getRelay() {
|
||||
return relay;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getIncrementalDigest() {
|
||||
if (incrementalDigest != null && incrementalDigest.length > 0) {
|
||||
return incrementalDigest;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFastPreflightId() {
|
||||
return fastPreflightId;
|
||||
}
|
||||
|
||||
public boolean isVoiceNote() {
|
||||
return voiceNote;
|
||||
}
|
||||
|
||||
public boolean isBorderless() {
|
||||
return borderless;
|
||||
}
|
||||
|
||||
public boolean isVideoGif() {
|
||||
return videoGif;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getIncrementalMacChunkSize() {
|
||||
return incrementalMacChunkSize;
|
||||
}
|
||||
|
||||
public boolean isQuote() {
|
||||
return quote;
|
||||
}
|
||||
|
||||
public long getUploadTimestamp() {
|
||||
return uploadTimestamp;
|
||||
}
|
||||
|
||||
public boolean isSticker() {
|
||||
return stickerLocator != null;
|
||||
}
|
||||
|
||||
public @Nullable StickerLocator getSticker() {
|
||||
return stickerLocator;
|
||||
}
|
||||
|
||||
public @Nullable BlurHash getBlurHash() {
|
||||
return blurHash;
|
||||
}
|
||||
|
||||
public @Nullable AudioHash getAudioHash() {
|
||||
return audioHash;
|
||||
}
|
||||
|
||||
public @Nullable String getCaption() {
|
||||
return caption;
|
||||
}
|
||||
|
||||
public @NonNull TransformProperties getTransformProperties() {
|
||||
return transformProperties;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package org.thoughtcrime.securesms.attachments
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import androidx.core.os.ParcelCompat
|
||||
import org.thoughtcrime.securesms.audio.AudioHash
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.util.ParcelUtil
|
||||
|
||||
/**
|
||||
* Note: We have to use our own Parcelable implementation because we need to do custom stuff to preserve
|
||||
* subclass information.
|
||||
*/
|
||||
abstract class Attachment(
|
||||
@JvmField
|
||||
val contentType: String,
|
||||
@JvmField
|
||||
val transferState: Int,
|
||||
@JvmField
|
||||
val size: Long,
|
||||
@JvmField
|
||||
val fileName: String?,
|
||||
@JvmField
|
||||
val cdnNumber: Int,
|
||||
@JvmField
|
||||
val location: String?,
|
||||
@JvmField
|
||||
val key: String?,
|
||||
@JvmField
|
||||
val relay: String?,
|
||||
@JvmField
|
||||
val digest: ByteArray?,
|
||||
@JvmField
|
||||
val incrementalDigest: ByteArray?,
|
||||
@JvmField
|
||||
val fastPreflightId: String?,
|
||||
@JvmField
|
||||
val voiceNote: Boolean,
|
||||
@JvmField
|
||||
val borderless: Boolean,
|
||||
@JvmField
|
||||
val videoGif: Boolean,
|
||||
@JvmField
|
||||
val width: Int,
|
||||
@JvmField
|
||||
val height: Int,
|
||||
@JvmField
|
||||
val incrementalMacChunkSize: Int,
|
||||
@JvmField
|
||||
val quote: Boolean,
|
||||
@JvmField
|
||||
val uploadTimestamp: Long,
|
||||
@JvmField
|
||||
val caption: String?,
|
||||
@JvmField
|
||||
val stickerLocator: StickerLocator?,
|
||||
@JvmField
|
||||
val blurHash: BlurHash?,
|
||||
@JvmField
|
||||
val audioHash: AudioHash?,
|
||||
@JvmField
|
||||
val transformProperties: TransformProperties?
|
||||
) : Parcelable {
|
||||
|
||||
abstract val uri: Uri?
|
||||
abstract val publicUri: Uri?
|
||||
|
||||
protected constructor(parcel: Parcel) : this(
|
||||
contentType = parcel.readString()!!,
|
||||
transferState = parcel.readInt(),
|
||||
size = parcel.readLong(),
|
||||
fileName = parcel.readString(),
|
||||
cdnNumber = parcel.readInt(),
|
||||
location = parcel.readString(),
|
||||
key = parcel.readString(),
|
||||
relay = parcel.readString(),
|
||||
digest = ParcelUtil.readByteArray(parcel),
|
||||
incrementalDigest = ParcelUtil.readByteArray(parcel),
|
||||
fastPreflightId = parcel.readString(),
|
||||
voiceNote = ParcelUtil.readBoolean(parcel),
|
||||
borderless = ParcelUtil.readBoolean(parcel),
|
||||
videoGif = ParcelUtil.readBoolean(parcel),
|
||||
width = parcel.readInt(),
|
||||
height = parcel.readInt(),
|
||||
incrementalMacChunkSize = parcel.readInt(),
|
||||
quote = ParcelUtil.readBoolean(parcel),
|
||||
uploadTimestamp = parcel.readLong(),
|
||||
caption = parcel.readString(),
|
||||
stickerLocator = ParcelCompat.readParcelable(parcel, StickerLocator::class.java.classLoader, StickerLocator::class.java),
|
||||
blurHash = ParcelCompat.readParcelable(parcel, BlurHash::class.java.classLoader, BlurHash::class.java),
|
||||
audioHash = ParcelCompat.readParcelable(parcel, AudioHash::class.java.classLoader, AudioHash::class.java),
|
||||
transformProperties = ParcelCompat.readParcelable(parcel, TransformProperties::class.java.classLoader, TransformProperties::class.java)
|
||||
)
|
||||
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
AttachmentCreator.writeSubclass(dest, this)
|
||||
dest.writeString(contentType)
|
||||
dest.writeInt(transferState)
|
||||
dest.writeLong(size)
|
||||
dest.writeString(fileName)
|
||||
dest.writeInt(cdnNumber)
|
||||
dest.writeString(location)
|
||||
dest.writeString(key)
|
||||
dest.writeString(relay)
|
||||
ParcelUtil.writeByteArray(dest, digest)
|
||||
ParcelUtil.writeByteArray(dest, incrementalDigest)
|
||||
dest.writeString(fastPreflightId)
|
||||
ParcelUtil.writeBoolean(dest, voiceNote)
|
||||
ParcelUtil.writeBoolean(dest, borderless)
|
||||
ParcelUtil.writeBoolean(dest, videoGif)
|
||||
dest.writeInt(width)
|
||||
dest.writeInt(height)
|
||||
dest.writeInt(incrementalMacChunkSize)
|
||||
ParcelUtil.writeBoolean(dest, quote)
|
||||
dest.writeLong(uploadTimestamp)
|
||||
dest.writeString(caption)
|
||||
dest.writeParcelable(stickerLocator, 0)
|
||||
dest.writeParcelable(blurHash, 0)
|
||||
dest.writeParcelable(audioHash, 0)
|
||||
dest.writeParcelable(transformProperties, 0)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
val isInProgress: Boolean
|
||||
get() = transferState != AttachmentTable.TRANSFER_PROGRESS_DONE && transferState != AttachmentTable.TRANSFER_PROGRESS_FAILED && transferState != AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE
|
||||
|
||||
val isPermanentlyFailed: Boolean
|
||||
get() = transferState == AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE
|
||||
|
||||
val isSticker: Boolean
|
||||
get() = stickerLocator != null
|
||||
|
||||
fun getIncrementalDigest(): ByteArray? {
|
||||
return if (incrementalDigest != null && incrementalDigest.size > 0) {
|
||||
incrementalDigest
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<Attachment> = AttachmentCreator
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@ import android.os.Parcelable
|
|||
object AttachmentCreator : Parcelable.Creator<Attachment> {
|
||||
enum class Subclass(val clazz: Class<out Attachment>, val code: String) {
|
||||
DATABASE(DatabaseAttachment::class.java, "database"),
|
||||
MMS_NOTIFICATION(MmsNotificationAttachment::class.java, "mms_notification"),
|
||||
POINTER(PointerAttachment::class.java, "pointer"),
|
||||
TOMBSTONE(TombstoneAttachment::class.java, "tombstone"),
|
||||
URI(UriAttachment::class.java, "uri")
|
||||
|
@ -32,7 +31,6 @@ object AttachmentCreator : Parcelable.Creator<Attachment> {
|
|||
|
||||
return when (Subclass.values().first { rawCode == it.code }) {
|
||||
Subclass.DATABASE -> DatabaseAttachment(source)
|
||||
Subclass.MMS_NOTIFICATION -> MmsNotificationAttachment(source)
|
||||
Subclass.POINTER -> PointerAttachment(source)
|
||||
Subclass.TOMBSTONE -> TombstoneAttachment(source)
|
||||
Subclass.URI -> UriAttachment(source)
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.os.ParcelCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.audio.AudioHash;
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.ParcelUtil;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class DatabaseAttachment extends Attachment {
|
||||
|
||||
private final AttachmentId attachmentId;
|
||||
private final long mmsId;
|
||||
private final boolean hasData;
|
||||
private final boolean hasThumbnail;
|
||||
private final int displayOrder;
|
||||
|
||||
public DatabaseAttachment(AttachmentId attachmentId,
|
||||
long mmsId,
|
||||
boolean hasData,
|
||||
boolean hasThumbnail,
|
||||
String contentType,
|
||||
int transferProgress,
|
||||
long size,
|
||||
String fileName,
|
||||
int cdnNumber,
|
||||
String location,
|
||||
String key,
|
||||
String relay,
|
||||
byte[] digest,
|
||||
byte[] incrementalDigest,
|
||||
int incrementalMacChunkSize,
|
||||
String fastPreflightId,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
boolean videoGif,
|
||||
int width,
|
||||
int height,
|
||||
boolean quote,
|
||||
@Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash,
|
||||
@Nullable AudioHash audioHash,
|
||||
@Nullable TransformProperties transformProperties,
|
||||
int displayOrder,
|
||||
long uploadTimestamp)
|
||||
{
|
||||
super(contentType, transferProgress, size, fileName, cdnNumber, location, key, relay, digest, incrementalDigest, fastPreflightId, voiceNote, borderless, videoGif, width, height, incrementalMacChunkSize, quote, uploadTimestamp, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
this.attachmentId = attachmentId;
|
||||
this.hasData = hasData;
|
||||
this.hasThumbnail = hasThumbnail;
|
||||
this.mmsId = mmsId;
|
||||
this.displayOrder = displayOrder;
|
||||
}
|
||||
|
||||
protected DatabaseAttachment(Parcel in) {
|
||||
super(in);
|
||||
this.attachmentId = ParcelCompat.readParcelable(in, AttachmentId.class.getClassLoader(), AttachmentId.class);
|
||||
this.hasData = ParcelUtil.readBoolean(in);
|
||||
this.hasThumbnail = ParcelUtil.readBoolean(in);
|
||||
this.mmsId = in.readLong();
|
||||
this.displayOrder = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(attachmentId, 0);
|
||||
ParcelUtil.writeBoolean(dest, hasData);
|
||||
ParcelUtil.writeBoolean(dest, hasThumbnail);
|
||||
dest.writeLong(mmsId);
|
||||
dest.writeInt(displayOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Uri getUri() {
|
||||
if (hasData || (FeatureFlags.instantVideoPlayback() && getIncrementalDigest() != null)) {
|
||||
return PartAuthority.getAttachmentDataUri(attachmentId);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getPublicUri() {
|
||||
if (hasData) {
|
||||
return PartAuthority.getAttachmentPublicUri(getUri());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public AttachmentId getAttachmentId() {
|
||||
return attachmentId;
|
||||
}
|
||||
|
||||
public int getDisplayOrder() {
|
||||
return displayOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other != null &&
|
||||
other instanceof DatabaseAttachment &&
|
||||
((DatabaseAttachment) other).attachmentId.equals(this.attachmentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return attachmentId.hashCode();
|
||||
}
|
||||
|
||||
public long getMmsId() {
|
||||
return mmsId;
|
||||
}
|
||||
|
||||
public boolean hasData() {
|
||||
return hasData;
|
||||
}
|
||||
|
||||
public boolean hasThumbnail() {
|
||||
return hasThumbnail;
|
||||
}
|
||||
|
||||
public static class DisplayOrderComparator implements Comparator<DatabaseAttachment> {
|
||||
@Override
|
||||
public int compare(DatabaseAttachment lhs, DatabaseAttachment rhs) {
|
||||
return Integer.compare(lhs.getDisplayOrder(), rhs.getDisplayOrder());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package org.thoughtcrime.securesms.attachments
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import androidx.core.os.ParcelCompat
|
||||
import org.thoughtcrime.securesms.audio.AudioHash
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.ParcelUtil
|
||||
|
||||
class DatabaseAttachment : Attachment {
|
||||
|
||||
@JvmField
|
||||
val attachmentId: AttachmentId
|
||||
|
||||
@JvmField
|
||||
val mmsId: Long
|
||||
|
||||
@JvmField
|
||||
val hasData: Boolean
|
||||
|
||||
private val hasThumbnail: Boolean
|
||||
val displayOrder: Int
|
||||
|
||||
constructor(
|
||||
attachmentId: AttachmentId,
|
||||
mmsId: Long,
|
||||
hasData: Boolean,
|
||||
hasThumbnail: Boolean,
|
||||
contentType: String?,
|
||||
transferProgress: Int,
|
||||
size: Long,
|
||||
fileName: String?,
|
||||
cdnNumber: Int,
|
||||
location: String?,
|
||||
key: String?,
|
||||
relay: String?,
|
||||
digest: ByteArray?,
|
||||
incrementalDigest: ByteArray?,
|
||||
incrementalMacChunkSize: Int,
|
||||
fastPreflightId: String?,
|
||||
voiceNote: Boolean,
|
||||
borderless: Boolean,
|
||||
videoGif: Boolean,
|
||||
width: Int,
|
||||
height: Int,
|
||||
quote: Boolean,
|
||||
caption: String?,
|
||||
stickerLocator: StickerLocator?,
|
||||
blurHash: BlurHash?,
|
||||
audioHash: AudioHash?,
|
||||
transformProperties: TransformProperties?,
|
||||
displayOrder: Int,
|
||||
uploadTimestamp: Long
|
||||
) : super(
|
||||
contentType = contentType!!,
|
||||
transferState = transferProgress,
|
||||
size = size,
|
||||
fileName = fileName,
|
||||
cdnNumber = cdnNumber,
|
||||
location = location,
|
||||
key = key,
|
||||
relay = relay,
|
||||
digest = digest,
|
||||
incrementalDigest = incrementalDigest,
|
||||
fastPreflightId = fastPreflightId,
|
||||
voiceNote = voiceNote,
|
||||
borderless = borderless,
|
||||
videoGif = videoGif, width = width,
|
||||
height = height,
|
||||
incrementalMacChunkSize = incrementalMacChunkSize,
|
||||
quote = quote,
|
||||
uploadTimestamp = uploadTimestamp,
|
||||
caption = caption,
|
||||
stickerLocator = stickerLocator,
|
||||
blurHash = blurHash,
|
||||
audioHash = audioHash,
|
||||
transformProperties = transformProperties
|
||||
) {
|
||||
this.attachmentId = attachmentId
|
||||
this.mmsId = mmsId
|
||||
this.hasData = hasData
|
||||
this.hasThumbnail = hasThumbnail
|
||||
this.displayOrder = displayOrder
|
||||
}
|
||||
|
||||
constructor(parcel: Parcel) : super(parcel) {
|
||||
attachmentId = ParcelCompat.readParcelable(parcel, AttachmentId::class.java.classLoader, AttachmentId::class.java)!!
|
||||
hasData = ParcelUtil.readBoolean(parcel)
|
||||
hasThumbnail = ParcelUtil.readBoolean(parcel)
|
||||
mmsId = parcel.readLong()
|
||||
displayOrder = parcel.readInt()
|
||||
}
|
||||
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
super.writeToParcel(dest, flags)
|
||||
dest.writeParcelable(attachmentId, 0)
|
||||
ParcelUtil.writeBoolean(dest, hasData)
|
||||
ParcelUtil.writeBoolean(dest, hasThumbnail)
|
||||
dest.writeLong(mmsId)
|
||||
dest.writeInt(displayOrder)
|
||||
}
|
||||
|
||||
override val uri: Uri?
|
||||
get() = if (hasData || FeatureFlags.instantVideoPlayback() && getIncrementalDigest() != null) {
|
||||
PartAuthority.getAttachmentDataUri(attachmentId)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
override val publicUri: Uri?
|
||||
get() = if (hasData) {
|
||||
PartAuthority.getAttachmentPublicUri(uri)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other != null &&
|
||||
other is DatabaseAttachment && other.attachmentId == attachmentId
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return attachmentId.hashCode()
|
||||
}
|
||||
|
||||
class DisplayOrderComparator : Comparator<DatabaseAttachment> {
|
||||
override fun compare(lhs: DatabaseAttachment, rhs: DatabaseAttachment): Int {
|
||||
return lhs.displayOrder.compareTo(rhs.displayOrder)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
|
||||
public class MmsNotificationAttachment extends Attachment {
|
||||
|
||||
public MmsNotificationAttachment(int status, long size) {
|
||||
super("application/mms", getTransferStateFromStatus(status), size, null, 0, null, null, null, null, null, null, false, false, false, 0, 0, 0, false, 0, null, null, null, null, null);
|
||||
}
|
||||
|
||||
protected MmsNotificationAttachment(Parcel in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getPublicUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getTransferStateFromStatus(int status) {
|
||||
if (status == MessageTable.MmsStatus.DOWNLOAD_INITIALIZED ||
|
||||
status == MessageTable.MmsStatus.DOWNLOAD_NO_CONNECTIVITY)
|
||||
{
|
||||
return AttachmentTable.TRANSFER_PROGRESS_PENDING;
|
||||
} else if (status == MessageTable.MmsStatus.DOWNLOAD_CONNECTING) {
|
||||
return AttachmentTable.TRANSFER_PROGRESS_STARTED;
|
||||
} else {
|
||||
return AttachmentTable.TRANSFER_PROGRESS_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.signal.core.util.Base64;
|
||||
import org.whispersystems.signalservice.api.InvalidMessageStructureException;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.util.AttachmentPointerUtil;
|
||||
import org.whispersystems.signalservice.internal.push.DataMessage;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class PointerAttachment extends Attachment {
|
||||
|
||||
private PointerAttachment(@NonNull String contentType,
|
||||
int transferState,
|
||||
long size,
|
||||
@Nullable String fileName,
|
||||
int cdnNumber,
|
||||
@NonNull String location,
|
||||
@Nullable String key,
|
||||
@Nullable String relay,
|
||||
@Nullable byte[] digest,
|
||||
@Nullable byte[] incrementalDigest,
|
||||
int incrementalMacChunkSize,
|
||||
@Nullable String fastPreflightId,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
boolean videoGif,
|
||||
int width,
|
||||
int height,
|
||||
long uploadTimestamp,
|
||||
@Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash)
|
||||
{
|
||||
super(contentType, transferState, size, fileName, cdnNumber, location, key, relay, digest, incrementalDigest, fastPreflightId, voiceNote, borderless, videoGif, width, height, incrementalMacChunkSize, false, uploadTimestamp, caption, stickerLocator, blurHash, null, null);
|
||||
}
|
||||
|
||||
protected PointerAttachment(Parcel in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getPublicUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Attachment> forPointers(Optional<List<SignalServiceAttachment>> pointers) {
|
||||
List<Attachment> results = new LinkedList<>();
|
||||
|
||||
if (pointers.isPresent()) {
|
||||
for (SignalServiceAttachment pointer : pointers.get()) {
|
||||
Optional<Attachment> result = forPointer(Optional.of(pointer));
|
||||
|
||||
if (result.isPresent()) {
|
||||
results.add(result.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Attachment> forPointers(@Nullable List<SignalServiceDataMessage.Quote.QuotedAttachment> pointers) {
|
||||
List<Attachment> results = new LinkedList<>();
|
||||
|
||||
if (pointers != null) {
|
||||
for (SignalServiceDataMessage.Quote.QuotedAttachment pointer : pointers) {
|
||||
Optional<Attachment> result = forPointer(pointer);
|
||||
|
||||
if (result.isPresent()) {
|
||||
results.add(result.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static Optional<Attachment> forPointer(Optional<SignalServiceAttachment> pointer) {
|
||||
return forPointer(pointer, null, null);
|
||||
}
|
||||
|
||||
public static Optional<Attachment> forPointer(Optional<SignalServiceAttachment> pointer, @Nullable StickerLocator stickerLocator) {
|
||||
return forPointer(pointer, stickerLocator, null);
|
||||
}
|
||||
|
||||
public static Optional<Attachment> forPointer(Optional<SignalServiceAttachment> pointer, @Nullable StickerLocator stickerLocator, @Nullable String fastPreflightId) {
|
||||
if (!pointer.isPresent() || !pointer.get().isPointer()) return Optional.empty();
|
||||
|
||||
String encodedKey = null;
|
||||
|
||||
if (pointer.get().asPointer().getKey() != null) {
|
||||
encodedKey = Base64.encodeWithPadding(pointer.get().asPointer().getKey());
|
||||
}
|
||||
|
||||
return Optional.of(new PointerAttachment(pointer.get().getContentType(),
|
||||
AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
pointer.get().asPointer().getSize().orElse(0),
|
||||
pointer.get().asPointer().getFileName().orElse(null),
|
||||
pointer.get().asPointer().getCdnNumber(),
|
||||
pointer.get().asPointer().getRemoteId().toString(),
|
||||
encodedKey,
|
||||
null,
|
||||
pointer.get().asPointer().getDigest().orElse(null),
|
||||
pointer.get().asPointer().getIncrementalDigest().orElse(null),
|
||||
pointer.get().asPointer().getIncrementalMacChunkSize(),
|
||||
fastPreflightId,
|
||||
pointer.get().asPointer().getVoiceNote(),
|
||||
pointer.get().asPointer().isBorderless(),
|
||||
pointer.get().asPointer().isGif(),
|
||||
pointer.get().asPointer().getWidth(),
|
||||
pointer.get().asPointer().getHeight(),
|
||||
pointer.get().asPointer().getUploadTimestamp(),
|
||||
pointer.get().asPointer().getCaption().orElse(null),
|
||||
stickerLocator,
|
||||
BlurHash.parseOrNull(pointer.get().asPointer().getBlurHash().orElse(null))));
|
||||
|
||||
}
|
||||
|
||||
public static Optional<Attachment> forPointer(SignalServiceDataMessage.Quote.QuotedAttachment pointer) {
|
||||
SignalServiceAttachment thumbnail = pointer.getThumbnail();
|
||||
|
||||
return Optional.of(new PointerAttachment(pointer.getContentType(),
|
||||
AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
thumbnail != null ? thumbnail.asPointer().getSize().orElse(0) : 0,
|
||||
pointer.getFileName(),
|
||||
thumbnail != null ? thumbnail.asPointer().getCdnNumber() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getRemoteId().toString() : "0",
|
||||
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeWithPadding(thumbnail.asPointer().getKey()) : null,
|
||||
null,
|
||||
thumbnail != null ? thumbnail.asPointer().getDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalMacChunkSize() : 0,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
thumbnail != null ? thumbnail.asPointer().getWidth() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getHeight() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getUploadTimestamp() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getCaption().orElse(null) : null,
|
||||
null,
|
||||
null));
|
||||
}
|
||||
|
||||
public static Optional<Attachment> forPointer(DataMessage.Quote.QuotedAttachment quotedAttachment) {
|
||||
SignalServiceAttachment thumbnail;
|
||||
try {
|
||||
thumbnail = quotedAttachment.thumbnail != null ? AttachmentPointerUtil.createSignalAttachmentPointer(quotedAttachment.thumbnail) : null;
|
||||
} catch (InvalidMessageStructureException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new PointerAttachment(quotedAttachment.contentType,
|
||||
AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
thumbnail != null ? thumbnail.asPointer().getSize().orElse(0) : 0,
|
||||
quotedAttachment.fileName,
|
||||
thumbnail != null ? thumbnail.asPointer().getCdnNumber() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getRemoteId().toString() : "0",
|
||||
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeWithPadding(thumbnail.asPointer().getKey()) : null,
|
||||
null,
|
||||
thumbnail != null ? thumbnail.asPointer().getDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalMacChunkSize() : 0,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
thumbnail != null ? thumbnail.asPointer().getWidth() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getHeight() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getUploadTimestamp() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getCaption().orElse(null) : null,
|
||||
null,
|
||||
null));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package org.thoughtcrime.securesms.attachments
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import org.signal.core.util.Base64.encodeWithPadding
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.whispersystems.signalservice.api.InvalidMessageStructureException
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
||||
import org.whispersystems.signalservice.api.util.AttachmentPointerUtil
|
||||
import org.whispersystems.signalservice.internal.push.DataMessage
|
||||
import java.util.Optional
|
||||
|
||||
class PointerAttachment : Attachment {
|
||||
private constructor(
|
||||
contentType: String,
|
||||
transferState: Int,
|
||||
size: Long,
|
||||
fileName: String?,
|
||||
cdnNumber: Int,
|
||||
location: String,
|
||||
key: String?,
|
||||
relay: String?,
|
||||
digest: ByteArray?,
|
||||
incrementalDigest: ByteArray?,
|
||||
incrementalMacChunkSize: Int,
|
||||
fastPreflightId: String?,
|
||||
voiceNote: Boolean,
|
||||
borderless: Boolean,
|
||||
videoGif: Boolean,
|
||||
width: Int,
|
||||
height: Int,
|
||||
uploadTimestamp: Long,
|
||||
caption: String?,
|
||||
stickerLocator: StickerLocator?,
|
||||
blurHash: BlurHash?
|
||||
) : super(
|
||||
contentType = contentType,
|
||||
transferState = transferState,
|
||||
size = size,
|
||||
fileName = fileName,
|
||||
cdnNumber = cdnNumber,
|
||||
location = location,
|
||||
key = key,
|
||||
relay = relay,
|
||||
digest = digest,
|
||||
incrementalDigest = incrementalDigest,
|
||||
fastPreflightId = fastPreflightId,
|
||||
voiceNote = voiceNote,
|
||||
borderless = borderless,
|
||||
videoGif = videoGif,
|
||||
width = width,
|
||||
height = height,
|
||||
incrementalMacChunkSize = incrementalMacChunkSize,
|
||||
quote = false,
|
||||
uploadTimestamp = uploadTimestamp,
|
||||
caption = caption,
|
||||
stickerLocator = stickerLocator,
|
||||
blurHash = blurHash,
|
||||
audioHash = null,
|
||||
transformProperties = null
|
||||
)
|
||||
|
||||
constructor(parcel: Parcel) : super(parcel)
|
||||
|
||||
override val uri: Uri? = null
|
||||
override val publicUri: Uri? = null
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun forPointers(pointers: Optional<List<SignalServiceAttachment>>): List<Attachment> {
|
||||
if (!pointers.isPresent) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return pointers.get()
|
||||
.map { forPointer(Optional.ofNullable(it)) }
|
||||
.filter { it.isPresent }
|
||||
.map { it.get() }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun forPointer(pointer: Optional<SignalServiceAttachment>, stickerLocator: StickerLocator? = null, fastPreflightId: String? = null): Optional<Attachment> {
|
||||
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
|
||||
}
|
||||
|
||||
return Optional.of(
|
||||
PointerAttachment(
|
||||
contentType = pointer.get().contentType,
|
||||
transferState = AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
size = pointer.get().asPointer().size.orElse(0).toLong(),
|
||||
fileName = pointer.get().asPointer().fileName.orElse(null),
|
||||
cdnNumber = pointer.get().asPointer().cdnNumber,
|
||||
location = pointer.get().asPointer().remoteId.toString(),
|
||||
key = encodedKey,
|
||||
relay = null,
|
||||
digest = pointer.get().asPointer().digest.orElse(null),
|
||||
incrementalDigest = pointer.get().asPointer().incrementalDigest.orElse(null),
|
||||
incrementalMacChunkSize = pointer.get().asPointer().incrementalMacChunkSize,
|
||||
fastPreflightId = fastPreflightId,
|
||||
voiceNote = pointer.get().asPointer().voiceNote,
|
||||
borderless = pointer.get().asPointer().isBorderless,
|
||||
videoGif = pointer.get().asPointer().isGif,
|
||||
width = pointer.get().asPointer().width,
|
||||
height = pointer.get().asPointer().height,
|
||||
uploadTimestamp = pointer.get().asPointer().uploadTimestamp,
|
||||
caption = pointer.get().asPointer().caption.orElse(null),
|
||||
stickerLocator = stickerLocator,
|
||||
blurHash = BlurHash.parseOrNull(pointer.get().asPointer().blurHash.orElse(null))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun forPointer(pointer: SignalServiceDataMessage.Quote.QuotedAttachment): Optional<Attachment> {
|
||||
val thumbnail = pointer.thumbnail
|
||||
|
||||
return Optional.of(
|
||||
PointerAttachment(
|
||||
contentType = pointer.contentType,
|
||||
transferState = AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
size = (if (thumbnail != null) thumbnail.asPointer().size.orElse(0) else 0).toLong(),
|
||||
fileName = pointer.fileName,
|
||||
cdnNumber = thumbnail?.asPointer()?.cdnNumber ?: 0,
|
||||
location = thumbnail?.asPointer()?.remoteId?.toString() ?: "0",
|
||||
key = if (thumbnail != null && thumbnail.asPointer().key != null) encodeWithPadding(thumbnail.asPointer().key) else null,
|
||||
relay = null,
|
||||
digest = thumbnail?.asPointer()?.digest?.orElse(null),
|
||||
incrementalDigest = thumbnail?.asPointer()?.incrementalDigest?.orElse(null),
|
||||
incrementalMacChunkSize = thumbnail?.asPointer()?.incrementalMacChunkSize ?: 0,
|
||||
fastPreflightId = null,
|
||||
voiceNote = false,
|
||||
borderless = false,
|
||||
videoGif = false,
|
||||
width = thumbnail?.asPointer()?.width ?: 0,
|
||||
height = thumbnail?.asPointer()?.height ?: 0,
|
||||
uploadTimestamp = thumbnail?.asPointer()?.uploadTimestamp ?: 0,
|
||||
caption = thumbnail?.asPointer()?.caption?.orElse(null),
|
||||
stickerLocator = null,
|
||||
blurHash = null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun forPointer(quotedAttachment: DataMessage.Quote.QuotedAttachment): Optional<Attachment> {
|
||||
val thumbnail: SignalServiceAttachment? = try {
|
||||
if (quotedAttachment.thumbnail != null) {
|
||||
AttachmentPointerUtil.createSignalAttachmentPointer(quotedAttachment.thumbnail)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (e: InvalidMessageStructureException) {
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
return Optional.of(
|
||||
PointerAttachment(
|
||||
contentType = quotedAttachment.contentType!!,
|
||||
transferState = AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
size = (if (thumbnail != null) thumbnail.asPointer().size.orElse(0) else 0).toLong(),
|
||||
fileName = quotedAttachment.fileName,
|
||||
cdnNumber = thumbnail?.asPointer()?.cdnNumber ?: 0,
|
||||
location = thumbnail?.asPointer()?.remoteId?.toString() ?: "0",
|
||||
key = if (thumbnail != null && thumbnail.asPointer().key != null) encodeWithPadding(thumbnail.asPointer().key) else null,
|
||||
relay = null,
|
||||
digest = thumbnail?.asPointer()?.digest?.orElse(null),
|
||||
incrementalDigest = thumbnail?.asPointer()?.incrementalDigest?.orElse(null),
|
||||
incrementalMacChunkSize = thumbnail?.asPointer()?.incrementalMacChunkSize ?: 0,
|
||||
fastPreflightId = null,
|
||||
voiceNote = false,
|
||||
borderless = false,
|
||||
videoGif = false,
|
||||
width = thumbnail?.asPointer()?.width ?: 0,
|
||||
height = thumbnail?.asPointer()?.height ?: 0,
|
||||
uploadTimestamp = thumbnail?.asPointer()?.uploadTimestamp ?: 0,
|
||||
caption = thumbnail?.asPointer()?.caption?.orElse(null),
|
||||
stickerLocator = null,
|
||||
blurHash = null
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
|
||||
/**
|
||||
* An attachment that represents where an attachment used to be. Useful when you need to know that
|
||||
* a message had an attachment and some metadata about it (like the contentType), even though the
|
||||
* underlying media no longer exists. An example usecase would be view-once messages, so that we can
|
||||
* quote them and know their contentType even though the media has been deleted.
|
||||
*/
|
||||
public class TombstoneAttachment extends Attachment {
|
||||
|
||||
public TombstoneAttachment(@NonNull String contentType, boolean quote) {
|
||||
super(contentType, AttachmentTable.TRANSFER_PROGRESS_DONE, 0, null, 0, null, null, null, null, null, null, false, false, false, 0, 0, 0, quote, 0, null, null, null, null, null);
|
||||
}
|
||||
|
||||
protected TombstoneAttachment(Parcel in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getPublicUri() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package org.thoughtcrime.securesms.attachments
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
|
||||
/**
|
||||
* An attachment that represents where an attachment used to be. Useful when you need to know that
|
||||
* a message had an attachment and some metadata about it (like the contentType), even though the
|
||||
* underlying media no longer exists. An example usecase would be view-once messages, so that we can
|
||||
* quote them and know their contentType even though the media has been deleted.
|
||||
*/
|
||||
class TombstoneAttachment : Attachment {
|
||||
constructor(contentType: String, quote: Boolean) : super(
|
||||
contentType = contentType,
|
||||
quote = quote,
|
||||
transferState = AttachmentTable.TRANSFER_PROGRESS_DONE,
|
||||
size = 0,
|
||||
fileName = null,
|
||||
cdnNumber = 0,
|
||||
location = null,
|
||||
key = null,
|
||||
relay = null,
|
||||
digest = null,
|
||||
incrementalDigest = null,
|
||||
fastPreflightId = null,
|
||||
voiceNote = false,
|
||||
borderless = false,
|
||||
videoGif = false,
|
||||
width = 0,
|
||||
height = 0,
|
||||
incrementalMacChunkSize = 0,
|
||||
uploadTimestamp = 0,
|
||||
caption = null,
|
||||
stickerLocator = null,
|
||||
blurHash = null,
|
||||
audioHash = null,
|
||||
transformProperties = null
|
||||
)
|
||||
|
||||
constructor(parcel: Parcel) : super(parcel)
|
||||
|
||||
override val uri: Uri? = null
|
||||
override val publicUri: Uri? = null
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.os.ParcelCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.audio.AudioHash;
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class UriAttachment extends Attachment {
|
||||
|
||||
private final @NonNull Uri dataUri;
|
||||
|
||||
public UriAttachment(@NonNull Uri uri,
|
||||
@NonNull String contentType,
|
||||
int transferState,
|
||||
long size,
|
||||
@Nullable String fileName,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
boolean videoGif,
|
||||
boolean quote,
|
||||
@Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash,
|
||||
@Nullable AudioHash audioHash,
|
||||
@Nullable TransformProperties transformProperties)
|
||||
{
|
||||
this(uri, contentType, transferState, size, 0, 0, fileName, null, voiceNote, borderless, videoGif, quote, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
}
|
||||
|
||||
public UriAttachment(@NonNull Uri dataUri,
|
||||
@NonNull String contentType,
|
||||
int transferState,
|
||||
long size,
|
||||
int width,
|
||||
int height,
|
||||
@Nullable String fileName,
|
||||
@Nullable String fastPreflightId,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
boolean videoGif,
|
||||
boolean quote,
|
||||
@Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash,
|
||||
@Nullable AudioHash audioHash,
|
||||
@Nullable TransformProperties transformProperties)
|
||||
{
|
||||
super(contentType, transferState, size, fileName, 0, null, null, null, null, null, fastPreflightId, voiceNote, borderless, videoGif, width, height, 0, quote, 0, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
this.dataUri = Objects.requireNonNull(dataUri);
|
||||
}
|
||||
|
||||
protected UriAttachment(Parcel in) {
|
||||
super(in);
|
||||
this.dataUri = Objects.requireNonNull(ParcelCompat.readParcelable(in, Uri.class.getClassLoader(), Uri.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(dataUri, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Uri getUri() {
|
||||
return dataUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getPublicUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other != null && other instanceof UriAttachment && ((UriAttachment) other).dataUri.equals(this.dataUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return dataUri.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package org.thoughtcrime.securesms.attachments
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import androidx.core.os.ParcelCompat
|
||||
import org.thoughtcrime.securesms.audio.AudioHash
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import java.util.Objects
|
||||
|
||||
class UriAttachment : Attachment {
|
||||
|
||||
constructor(
|
||||
uri: Uri,
|
||||
contentType: String,
|
||||
transferState: Int,
|
||||
size: Long,
|
||||
fileName: String?,
|
||||
voiceNote: Boolean,
|
||||
borderless: Boolean,
|
||||
videoGif: Boolean,
|
||||
quote: Boolean,
|
||||
caption: String?,
|
||||
stickerLocator: StickerLocator?,
|
||||
blurHash: BlurHash?,
|
||||
audioHash: AudioHash?,
|
||||
transformProperties: TransformProperties?
|
||||
) : this(
|
||||
dataUri = uri,
|
||||
contentType = contentType,
|
||||
transferState = transferState,
|
||||
size = size,
|
||||
width = 0,
|
||||
height = 0,
|
||||
fileName = fileName,
|
||||
fastPreflightId = null,
|
||||
voiceNote = voiceNote,
|
||||
borderless = borderless,
|
||||
videoGif = videoGif,
|
||||
quote = quote,
|
||||
caption = caption,
|
||||
stickerLocator = stickerLocator,
|
||||
blurHash = blurHash,
|
||||
audioHash = audioHash,
|
||||
transformProperties = transformProperties
|
||||
)
|
||||
|
||||
constructor(
|
||||
dataUri: Uri,
|
||||
contentType: String,
|
||||
transferState: Int,
|
||||
size: Long,
|
||||
width: Int,
|
||||
height: Int,
|
||||
fileName: String?,
|
||||
fastPreflightId: String?,
|
||||
voiceNote: Boolean,
|
||||
borderless: Boolean,
|
||||
videoGif: Boolean,
|
||||
quote: Boolean,
|
||||
caption: String?,
|
||||
stickerLocator: StickerLocator?,
|
||||
blurHash: BlurHash?,
|
||||
audioHash: AudioHash?,
|
||||
transformProperties: TransformProperties?
|
||||
) : super(
|
||||
contentType = contentType,
|
||||
transferState = transferState,
|
||||
size = size,
|
||||
fileName = fileName,
|
||||
cdnNumber = 0,
|
||||
location = null,
|
||||
key = null,
|
||||
relay = null,
|
||||
digest = null,
|
||||
incrementalDigest = null,
|
||||
fastPreflightId = fastPreflightId,
|
||||
voiceNote = voiceNote,
|
||||
borderless = borderless,
|
||||
videoGif = videoGif,
|
||||
width = width,
|
||||
height = height,
|
||||
incrementalMacChunkSize = 0,
|
||||
quote = quote,
|
||||
uploadTimestamp = 0,
|
||||
caption = caption,
|
||||
stickerLocator = stickerLocator,
|
||||
blurHash = blurHash,
|
||||
audioHash = audioHash,
|
||||
transformProperties = transformProperties
|
||||
) {
|
||||
uri = Objects.requireNonNull(dataUri)
|
||||
}
|
||||
|
||||
constructor(parcel: Parcel) : super(parcel) {
|
||||
uri = ParcelCompat.readParcelable(parcel, Uri::class.java.classLoader, Uri::class.java)!!
|
||||
}
|
||||
|
||||
override val uri: Uri
|
||||
override val publicUri: Uri? = null
|
||||
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
super.writeToParcel(dest, flags)
|
||||
dest.writeParcelable(uri, 0)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other != null && other is UriAttachment && other.uri == uri
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return uri.hashCode()
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ public class BorderlessImageView extends FrameLayout {
|
|||
image.setImageResource(glideRequests, slide, showControls, false);
|
||||
} else {
|
||||
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
image.setImageResource(glideRequests, slide, showControls, false, slide.asAttachment().getWidth(), slide.asAttachment().getHeight());
|
||||
image.setImageResource(glideRequests, slide, showControls, false, slide.asAttachment().width, slide.asAttachment().height);
|
||||
}
|
||||
|
||||
missingShade.setVisibility(showControls ? View.VISIBLE : View.GONE);
|
||||
|
|
|
@ -397,7 +397,7 @@ public class ThumbnailView extends FrameLayout {
|
|||
|
||||
Log.i(TAG, "loading part with id " + slide.asAttachment().getUri()
|
||||
+ ", progress " + slide.getTransferState() + ", fast preflight id: " +
|
||||
slide.asAttachment().getFastPreflightId());
|
||||
slide.asAttachment().fastPreflightId);
|
||||
|
||||
BlurHash previousBlurHash = this.slide != null ? this.slide.getPlaceholderBlur() : null;
|
||||
|
||||
|
@ -532,8 +532,8 @@ public class ThumbnailView extends FrameLayout {
|
|||
if (Util.equals(slide, other)) {
|
||||
|
||||
if (slide != null && other != null) {
|
||||
byte[] digestLeft = slide.asAttachment().getDigest();
|
||||
byte[] digestRight = other.asAttachment().getDigest();
|
||||
byte[] digestLeft = slide.asAttachment().digest;
|
||||
byte[] digestRight = other.asAttachment().digest;
|
||||
|
||||
return Arrays.equals(digestLeft, digestRight);
|
||||
}
|
||||
|
|
|
@ -2023,10 +2023,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
if (messageRecord.isMms()) {
|
||||
TextSlide slide = ((MmsMessageRecord) messageRecord).getSlideDeck().getTextSlide();
|
||||
|
||||
if (slide != null && (slide.asAttachment().getTransferState() == AttachmentTable.TRANSFER_PROGRESS_DONE || MessageRecordUtil.isScheduled(messageRecord))) {
|
||||
if (slide != null && (slide.asAttachment().transferState == AttachmentTable.TRANSFER_PROGRESS_DONE || MessageRecordUtil.isScheduled(messageRecord))) {
|
||||
message = getResources().getString(R.string.ConversationItem_read_more);
|
||||
action = () -> eventListener.onMoreTextClicked(conversationRecipient.getId(), messageRecord.getId(), messageRecord.isMms());
|
||||
} else if (slide != null && slide.asAttachment().getTransferState() == AttachmentTable.TRANSFER_PROGRESS_STARTED) {
|
||||
} else if (slide != null && slide.asAttachment().transferState == AttachmentTable.TRANSFER_PROGRESS_STARTED) {
|
||||
message = getResources().getString(R.string.ConversationItem_pending);
|
||||
action = () -> {};
|
||||
} else if (slide != null) {
|
||||
|
@ -2438,7 +2438,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
|
||||
for (Slide slide : slides) {
|
||||
ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(messageRecord.getId(),
|
||||
((DatabaseAttachment) slide.asAttachment()).getAttachmentId(),
|
||||
((DatabaseAttachment) slide.asAttachment()).attachmentId,
|
||||
true));
|
||||
}
|
||||
}
|
||||
|
@ -2457,7 +2457,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
Log.i(TAG, "Canceling push attachment downloads for " + slides.size() + " items");
|
||||
|
||||
for (Slide slide : slides) {
|
||||
final String queue = AttachmentDownloadJob.constructQueueString(((DatabaseAttachment) slide.asAttachment()).getAttachmentId());
|
||||
final String queue = AttachmentDownloadJob.constructQueueString(((DatabaseAttachment) slide.asAttachment()).attachmentId);
|
||||
jobManager.cancelAllInQueue(queue);
|
||||
}
|
||||
}
|
||||
|
@ -2477,8 +2477,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
}
|
||||
if (MediaUtil.isInstantVideoSupported(slide)) {
|
||||
final DatabaseAttachment databaseAttachment = (DatabaseAttachment) slide.asAttachment();
|
||||
if (databaseAttachment.getTransferState() != AttachmentTable.TRANSFER_PROGRESS_STARTED) {
|
||||
final AttachmentId attachmentId = databaseAttachment.getAttachmentId();
|
||||
if (databaseAttachment.transferState != AttachmentTable.TRANSFER_PROGRESS_STARTED) {
|
||||
final AttachmentId attachmentId = databaseAttachment.attachmentId;
|
||||
final JobManager jobManager = ApplicationDependencies.getJobManager();
|
||||
final String queue = AttachmentDownloadJob.constructQueueString(attachmentId);
|
||||
setup(v, slide);
|
||||
|
@ -2550,7 +2550,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
performClick();
|
||||
} else if (eventListener != null && hasSticker(messageRecord)) {
|
||||
//noinspection ConstantConditions
|
||||
eventListener.onStickerClicked(((MmsMessageRecord) messageRecord).getSlideDeck().getStickerSlide().asAttachment().getSticker());
|
||||
eventListener.onStickerClicked(((MmsMessageRecord) messageRecord).getSlideDeck().getStickerSlide().asAttachment().stickerLocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2617,7 +2617,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
messageRecord.getTimestamp(),
|
||||
mediaUri,
|
||||
slide.getContentType(),
|
||||
slide.asAttachment().getSize(),
|
||||
slide.asAttachment().size,
|
||||
slide.getCaption().orElse(null),
|
||||
false,
|
||||
false,
|
||||
|
@ -2626,8 +2626,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
MediaTable.Sorting.Newest,
|
||||
slide.isVideoGif(),
|
||||
new MediaIntentFactory.SharedElementArgs(
|
||||
slide.asAttachment().getWidth(),
|
||||
slide.asAttachment().getHeight(),
|
||||
slide.asAttachment().width,
|
||||
slide.asAttachment().height,
|
||||
mediaThumbnailStub.require().getCorners().getTopLeft(),
|
||||
mediaThumbnailStub.require().getCorners().getTopRight(),
|
||||
mediaThumbnailStub.require().getCorners().getBottomRight(),
|
||||
|
|
|
@ -175,7 +175,7 @@ data class MultiselectForwardFragmentArgs @JvmOverloads constructor(
|
|||
|
||||
if (mediaMessage.slideDeck.stickerSlide != null) {
|
||||
builder.withDataUri(mediaMessage.slideDeck.stickerSlide?.asAttachment()?.uri)
|
||||
builder.withStickerLocator(mediaMessage.slideDeck.stickerSlide?.asAttachment()?.sticker)
|
||||
builder.withStickerLocator(mediaMessage.slideDeck.stickerSlide?.asAttachment()?.stickerLocator)
|
||||
builder.withDataType(mediaMessage.slideDeck.stickerSlide?.asAttachment()?.contentType)
|
||||
}
|
||||
|
||||
|
@ -203,11 +203,11 @@ data class MultiselectForwardFragmentArgs @JvmOverloads constructor(
|
|||
height,
|
||||
size,
|
||||
0,
|
||||
isBorderless,
|
||||
isVideoGif,
|
||||
borderless,
|
||||
videoGif,
|
||||
Optional.empty(),
|
||||
Optional.ofNullable(caption),
|
||||
Optional.of(transformProperties)
|
||||
Optional.ofNullable(transformProperties)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2316,7 +2316,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
val quoteText = cursor.requireString(QUOTE_BODY)
|
||||
val quoteType = cursor.requireInt(QUOTE_TYPE)
|
||||
val quoteMissing = cursor.requireBoolean(QUOTE_MISSING)
|
||||
val quoteAttachments: List<Attachment> = associatedAttachments.filter { it.isQuote }.toList()
|
||||
val quoteAttachments: List<Attachment> = associatedAttachments.filter { it.quote }.toList()
|
||||
val quoteMentions: List<Mention> = parseQuoteMentions(cursor)
|
||||
val quoteBodyRanges: BodyRangeList? = parseQuoteBodyRanges(cursor)
|
||||
val quote: QuoteModel? = if (quoteId != QUOTE_NOT_PRESENT_ID && quoteAuthor > 0 && (!TextUtils.isEmpty(quoteText) || quoteAttachments.isNotEmpty())) {
|
||||
|
@ -2330,7 +2330,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
val previews: List<LinkPreview> = getLinkPreviews(cursor, associatedAttachments)
|
||||
val previewAttachments: Set<Attachment> = previews.filter { it.thumbnail.isPresent }.map { it.thumbnail.get() }.toSet()
|
||||
val attachments: List<Attachment> = associatedAttachments
|
||||
.filterNot { it.isQuote }
|
||||
.filterNot { it.quote }
|
||||
.filterNot { contactAttachments.contains(it) }
|
||||
.filterNot { previewAttachments.contains(it) }
|
||||
.sortedWith(DisplayOrderComparator())
|
||||
|
@ -5119,7 +5119,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
val bodyRanges = parseQuoteBodyRanges(cursor)
|
||||
|
||||
val attachments = attachments.getAttachments(cursor)
|
||||
val quoteAttachments: List<Attachment> = attachments.filter { it.isQuote }
|
||||
val quoteAttachments: List<Attachment> = attachments.filter { it.quote }
|
||||
val quoteDeck = SlideDeck(quoteAttachments)
|
||||
|
||||
return if (quoteId != QUOTE_NOT_PRESENT_ID && quoteAuthor > 0) {
|
||||
|
@ -5170,7 +5170,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
@JvmStatic
|
||||
fun buildSlideDeck(attachments: List<DatabaseAttachment>): SlideDeck {
|
||||
val messageAttachments = attachments
|
||||
.filterNot { it.isQuote }
|
||||
.filterNot { it.quote }
|
||||
.sortedWith(DisplayOrderComparator())
|
||||
|
||||
return SlideDeck(messageAttachments)
|
||||
|
|
|
@ -182,7 +182,7 @@ public final class GroupedThreadMediaLoader extends AsyncTaskLoader<GroupedThrea
|
|||
|
||||
@Override
|
||||
public int groupForRecord(@NonNull MediaTable.MediaRecord mediaRecord) {
|
||||
long size = mediaRecord.getAttachment().getSize();
|
||||
long size = mediaRecord.getAttachment().size;
|
||||
|
||||
if (size < MB) return SMALL;
|
||||
if (size < 20 * MB) return MEDIUM;
|
||||
|
|
|
@ -294,7 +294,7 @@ public class MmsMessageRecord extends MessageRecord {
|
|||
public @NonNull MmsMessageRecord withAttachments(@NonNull List<DatabaseAttachment> attachments) {
|
||||
Map<AttachmentId, DatabaseAttachment> attachmentIdMap = new HashMap<>();
|
||||
for (DatabaseAttachment attachment : attachments) {
|
||||
attachmentIdMap.put(attachment.getAttachmentId(), attachment);
|
||||
attachmentIdMap.put(attachment.attachmentId, attachment);
|
||||
}
|
||||
|
||||
List<Contact> contacts = updateContacts(getSharedContacts(), attachmentIdMap);
|
||||
|
@ -369,7 +369,7 @@ public class MmsMessageRecord extends MessageRecord {
|
|||
return null;
|
||||
}
|
||||
|
||||
List<DatabaseAttachment> quoteAttachments = attachments.stream().filter(Attachment::isQuote).collect(Collectors.toList());
|
||||
List<DatabaseAttachment> quoteAttachments = attachments.stream().filter(a -> a.quote).collect(Collectors.toList());
|
||||
|
||||
return quote.withAttachment(new SlideDeck(quoteAttachments));
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
|||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.ImageCompressionUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.MemoryFileDescriptor;
|
||||
import org.thoughtcrime.securesms.util.MemoryFileDescriptor.MemoryFileException;
|
||||
import org.thoughtcrime.securesms.video.InMemoryTranscoder;
|
||||
import org.thoughtcrime.securesms.video.StreamingTranscoder;
|
||||
|
@ -73,7 +72,7 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
boolean mms,
|
||||
int mmsSubscriptionId)
|
||||
{
|
||||
return new AttachmentCompressionJob(databaseAttachment.getAttachmentId(),
|
||||
return new AttachmentCompressionJob(databaseAttachment.attachmentId,
|
||||
MediaUtil.isVideo(databaseAttachment) && MediaConstraints.isVideoTranscodeAvailable(),
|
||||
mms,
|
||||
mmsSubscriptionId);
|
||||
|
@ -136,13 +135,13 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
throw new UndeliverableMessageException("Cannot find the specified attachment.");
|
||||
}
|
||||
|
||||
if (databaseAttachment.getTransformProperties().shouldSkipTransform()) {
|
||||
if (databaseAttachment.transformProperties.shouldSkipTransform()) {
|
||||
Log.i(TAG, "Skipping at the direction of the TransformProperties.");
|
||||
return;
|
||||
}
|
||||
|
||||
MediaConstraints mediaConstraints = mms ? MediaConstraints.getMmsMediaConstraints(mmsSubscriptionId)
|
||||
: MediaConstraints.getPushMediaConstraints(SentMediaQuality.fromCode(databaseAttachment.getTransformProperties().getSentMediaQuality()));
|
||||
: MediaConstraints.getPushMediaConstraints(SentMediaQuality.fromCode(databaseAttachment.transformProperties.sentMediaQuality));
|
||||
|
||||
compress(database, mediaConstraints, databaseAttachment);
|
||||
}
|
||||
|
@ -194,12 +193,12 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
@NonNull TranscoderCancelationSignal cancelationSignal)
|
||||
throws UndeliverableMessageException
|
||||
{
|
||||
AttachmentTable.TransformProperties transformProperties = attachment.getTransformProperties();
|
||||
AttachmentTable.TransformProperties transformProperties = attachment.transformProperties;
|
||||
|
||||
boolean allowSkipOnFailure = false;
|
||||
|
||||
if (!MediaConstraints.isVideoTranscodeAvailable()) {
|
||||
if (transformProperties.isVideoEdited()) {
|
||||
if (transformProperties.getVideoEdited()) {
|
||||
throw new UndeliverableMessageException("Video edited, but transcode is not available");
|
||||
}
|
||||
return attachment;
|
||||
|
@ -210,15 +209,15 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
notification.setIndeterminate(true);
|
||||
}
|
||||
|
||||
try (MediaDataSource dataSource = attachmentDatabase.mediaDataSourceFor(attachment.getAttachmentId(), false)) {
|
||||
try (MediaDataSource dataSource = attachmentDatabase.mediaDataSourceFor(attachment.attachmentId, false)) {
|
||||
if (dataSource == null) {
|
||||
throw new UndeliverableMessageException("Cannot get media data source for attachment.");
|
||||
}
|
||||
|
||||
allowSkipOnFailure = !transformProperties.isVideoEdited();
|
||||
allowSkipOnFailure = !transformProperties.getVideoEdited();
|
||||
TranscoderOptions options = null;
|
||||
if (transformProperties.isVideoTrim()) {
|
||||
options = new TranscoderOptions(transformProperties.getVideoTrimStartTimeUs(), transformProperties.getVideoTrimEndTimeUs());
|
||||
if (transformProperties.videoTrim) {
|
||||
options = new TranscoderOptions(transformProperties.videoTrimStartTimeUs, transformProperties.videoTrimEndTimeUs);
|
||||
}
|
||||
|
||||
if (FeatureFlags.useStreamingVideoMuxer()) {
|
||||
|
@ -228,7 +227,7 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
Log.i(TAG, "Compressing with streaming muxer");
|
||||
AttachmentSecret attachmentSecret = AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret();
|
||||
|
||||
File file = SignalDatabase.attachments().newFile();
|
||||
File file = SignalDatabase.attachments().newFile(context);
|
||||
file.deleteOnExit();
|
||||
|
||||
try {
|
||||
|
@ -258,9 +257,9 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
}
|
||||
}
|
||||
|
||||
attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId(), false);
|
||||
attachmentDatabase.markAttachmentAsTransformed(attachment.attachmentId, false);
|
||||
|
||||
return Objects.requireNonNull(attachmentDatabase.getAttachment(attachment.getAttachmentId()));
|
||||
return Objects.requireNonNull(attachmentDatabase.getAttachment(attachment.attachmentId));
|
||||
} else {
|
||||
Log.i(TAG, "Transcode was not required");
|
||||
}
|
||||
|
@ -279,14 +278,14 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
percent));
|
||||
}, cancelationSignal)) {
|
||||
attachmentDatabase.updateAttachmentData(attachment, mediaStream, true);
|
||||
attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId(), mediaStream.getFaststart());
|
||||
attachmentDatabase.markAttachmentAsTransformed(attachment.attachmentId, mediaStream.getFaststart());
|
||||
}
|
||||
|
||||
eventBus.postSticky(new PartProgressEvent(attachment,
|
||||
PartProgressEvent.Type.COMPRESSION,
|
||||
100,
|
||||
100));
|
||||
return Objects.requireNonNull(attachmentDatabase.getAttachment(attachment.getAttachmentId()));
|
||||
return Objects.requireNonNull(attachmentDatabase.getAttachment(attachment.attachmentId));
|
||||
} else {
|
||||
Log.i(TAG, "Transcode was not required (in-memory transcoder)");
|
||||
}
|
||||
|
@ -294,7 +293,7 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
}
|
||||
}
|
||||
} catch (VideoSourceException | EncodingException | MemoryFileException e) {
|
||||
if (attachment.getSize() > constraints.getVideoMaxSize(context)) {
|
||||
if (attachment.size > constraints.getVideoMaxSize(context)) {
|
||||
throw new UndeliverableMessageException("Duration not found, attachment too large to skip transcode", e);
|
||||
} else {
|
||||
if (allowSkipOnFailure) {
|
||||
|
@ -330,7 +329,7 @@ public final class AttachmentCompressionJob extends BaseJob {
|
|||
try {
|
||||
for (int size : mediaConstraints.getImageDimensionTargets(context)) {
|
||||
result = ImageCompressionUtil.compressWithinConstraints(context,
|
||||
attachment.getContentType(),
|
||||
attachment.contentType,
|
||||
new DecryptableStreamUriLoader.DecryptableUri(uri),
|
||||
size,
|
||||
mediaConstraints.getImageMaxSize(context),
|
||||
|
|
|
@ -119,8 +119,8 @@ public final class AttachmentDownloadJob extends BaseJob {
|
|||
final AttachmentTable database = SignalDatabase.attachments();
|
||||
final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId);
|
||||
final DatabaseAttachment attachment = database.getAttachment(attachmentId);
|
||||
final boolean pending = attachment != null && attachment.getTransferState() != AttachmentTable.TRANSFER_PROGRESS_DONE
|
||||
&& attachment.getTransferState() != AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE;
|
||||
final boolean pending = attachment != null && attachment.transferState != AttachmentTable.TRANSFER_PROGRESS_DONE
|
||||
&& attachment.transferState != AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE;
|
||||
|
||||
if (pending && (manual || AttachmentUtil.isAutoDownloadPermitted(context, attachment))) {
|
||||
Log.i(TAG, "onAdded() Marking attachment progress as 'started'");
|
||||
|
@ -168,7 +168,7 @@ public final class AttachmentDownloadJob extends BaseJob {
|
|||
Log.i(TAG, "Downloading push part " + attachmentId);
|
||||
database.setTransferState(messageId, attachmentId, AttachmentTable.TRANSFER_PROGRESS_STARTED);
|
||||
|
||||
if (attachment.getCdnNumber() != ReleaseChannel.CDN_NUMBER) {
|
||||
if (attachment.cdnNumber != ReleaseChannel.CDN_NUMBER) {
|
||||
retrieveAttachment(messageId, attachmentId, attachment);
|
||||
} else {
|
||||
retrieveUrlAttachment(messageId, attachmentId, attachment);
|
||||
|
@ -200,7 +200,7 @@ public final class AttachmentDownloadJob extends BaseJob {
|
|||
File attachmentFile = database.getOrCreateTransferFile(attachmentId);
|
||||
|
||||
try {
|
||||
if (attachment.getSize() > maxReceiveSize) {
|
||||
if (attachment.size > maxReceiveSize) {
|
||||
throw new MmsException("Attachment too large, failing download");
|
||||
}
|
||||
SignalServiceMessageReceiver messageReceiver = ApplicationDependencies.getSignalServiceMessageReceiver();
|
||||
|
@ -243,38 +243,38 @@ public final class AttachmentDownloadJob extends BaseJob {
|
|||
}
|
||||
|
||||
private SignalServiceAttachmentPointer createAttachmentPointer(Attachment attachment) throws InvalidPartException {
|
||||
if (TextUtils.isEmpty(attachment.getLocation())) {
|
||||
if (TextUtils.isEmpty(attachment.location)) {
|
||||
throw new InvalidPartException("empty content id");
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(attachment.getKey())) {
|
||||
if (TextUtils.isEmpty(attachment.key)) {
|
||||
throw new InvalidPartException("empty encrypted key");
|
||||
}
|
||||
|
||||
try {
|
||||
final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.getLocation());
|
||||
final byte[] key = Base64.decode(attachment.getKey());
|
||||
final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.location);
|
||||
final byte[] key = Base64.decode(attachment.key);
|
||||
|
||||
if (attachment.getDigest() != null) {
|
||||
Log.i(TAG, "Downloading attachment with digest: " + Hex.toString(attachment.getDigest()));
|
||||
if (attachment.digest != null) {
|
||||
Log.i(TAG, "Downloading attachment with digest: " + Hex.toString(attachment.digest));
|
||||
} else {
|
||||
Log.i(TAG, "Downloading attachment with no digest...");
|
||||
}
|
||||
|
||||
return new SignalServiceAttachmentPointer(attachment.getCdnNumber(), remoteId, null, key,
|
||||
Optional.of(Util.toIntExact(attachment.getSize())),
|
||||
return new SignalServiceAttachmentPointer(attachment.cdnNumber, remoteId, null, key,
|
||||
Optional.of(Util.toIntExact(attachment.size)),
|
||||
Optional.empty(),
|
||||
0, 0,
|
||||
Optional.ofNullable(attachment.getDigest()),
|
||||
Optional.ofNullable(attachment.digest),
|
||||
Optional.ofNullable(attachment.getIncrementalDigest()),
|
||||
attachment.getIncrementalMacChunkSize(),
|
||||
Optional.ofNullable(attachment.getFileName()),
|
||||
attachment.isVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
attachment.isVideoGif(),
|
||||
attachment.incrementalMacChunkSize,
|
||||
Optional.ofNullable(attachment.fileName),
|
||||
attachment.voiceNote,
|
||||
attachment.borderless,
|
||||
attachment.videoGif,
|
||||
Optional.empty(),
|
||||
Optional.ofNullable(attachment.getBlurHash()).map(BlurHash::getHash),
|
||||
attachment.getUploadTimestamp());
|
||||
Optional.ofNullable(attachment.blurHash).map(BlurHash::getHash),
|
||||
attachment.uploadTimestamp);
|
||||
} catch (IOException | ArithmeticException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new InvalidPartException(e);
|
||||
|
@ -286,7 +286,7 @@ public final class AttachmentDownloadJob extends BaseJob {
|
|||
final Attachment attachment)
|
||||
throws IOException
|
||||
{
|
||||
try (Response response = S3.getObject(Objects.requireNonNull(attachment.getFileName()))) {
|
||||
try (Response response = S3.getObject(Objects.requireNonNull(attachment.fileName))) {
|
||||
ResponseBody body = response.body();
|
||||
if (body != null) {
|
||||
if (body.contentLength() > FeatureFlags.maxAttachmentReceiveSizeBytes()) {
|
||||
|
|
|
@ -174,10 +174,10 @@ class AttachmentUploadJob private constructor(
|
|||
.withContentType(attachment.contentType)
|
||||
.withLength(attachment.size)
|
||||
.withFileName(attachment.fileName)
|
||||
.withVoiceNote(attachment.isVoiceNote)
|
||||
.withBorderless(attachment.isBorderless)
|
||||
.withGif(attachment.isVideoGif)
|
||||
.withFaststart(attachment.transformProperties.isMp4Faststart)
|
||||
.withVoiceNote(attachment.voiceNote)
|
||||
.withBorderless(attachment.borderless)
|
||||
.withGif(attachment.videoGif)
|
||||
.withFaststart(attachment.transformProperties?.mp4FastStart ?: false)
|
||||
.withWidth(attachment.width)
|
||||
.withHeight(attachment.height)
|
||||
.withUploadTimestamp(System.currentTimeMillis())
|
||||
|
|
|
@ -126,22 +126,22 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
throw new InvalidAttachmentException("Cannot find the specified attachment.");
|
||||
}
|
||||
|
||||
long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.getUploadTimestamp();
|
||||
if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.getLocation())) {
|
||||
long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.uploadTimestamp;
|
||||
if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.location)) {
|
||||
Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping.");
|
||||
return;
|
||||
} else if (databaseAttachment.getUploadTimestamp() > 0) {
|
||||
} else if (databaseAttachment.uploadTimestamp > 0) {
|
||||
Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: " + timeSinceUpload + " ms");
|
||||
}
|
||||
|
||||
Log.i(TAG, "Uploading attachment for message " + databaseAttachment.getMmsId() + " with ID " + databaseAttachment.getAttachmentId());
|
||||
Log.i(TAG, "Uploading attachment for message " + databaseAttachment.mmsId + " with ID " + databaseAttachment.attachmentId);
|
||||
|
||||
try (NotificationController notification = getNotificationForAttachment(databaseAttachment)) {
|
||||
try (SignalServiceAttachmentStream localAttachment = getAttachmentFor(databaseAttachment, notification, resumableUploadSpec)) {
|
||||
SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment);
|
||||
Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.getFastPreflightId()).get();
|
||||
Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.fastPreflightId).get();
|
||||
|
||||
database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment, remoteAttachment.getUploadTimestamp());
|
||||
database.updateAttachmentAfterUpload(databaseAttachment.attachmentId, attachment, remoteAttachment.getUploadTimestamp());
|
||||
}
|
||||
} catch (NonSuccessfulResumableUploadResponseCodeException e) {
|
||||
if (e.getCode() == 400) {
|
||||
|
@ -152,7 +152,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
}
|
||||
|
||||
private @Nullable NotificationController getNotificationForAttachment(@NonNull Attachment attachment) {
|
||||
if (attachment.getSize() >= FOREGROUND_LIMIT) {
|
||||
if (attachment.size >= FOREGROUND_LIMIT) {
|
||||
try {
|
||||
return ForegroundServiceUtil.startGenericTaskWhenCapable(context, context.getString(R.string.AttachmentUploadJob_uploading_media));
|
||||
} catch (UnableToStartException e) {
|
||||
|
@ -179,7 +179,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
}
|
||||
|
||||
private @NonNull SignalServiceAttachmentStream getAttachmentFor(Attachment attachment, @Nullable NotificationController notification, @Nullable ResumableUploadSpec resumableUploadSpec) throws InvalidAttachmentException {
|
||||
if (attachment.getUri() == null || attachment.getSize() == 0) {
|
||||
if (attachment.getUri() == null || attachment.size == 0) {
|
||||
throw new InvalidAttachmentException(new IOException("Assertion failed, outgoing attachment has no data!"));
|
||||
}
|
||||
|
||||
|
@ -187,17 +187,17 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
InputStream is = PartAuthority.getAttachmentStream(context, attachment.getUri());
|
||||
SignalServiceAttachment.Builder builder = SignalServiceAttachment.newStreamBuilder()
|
||||
.withStream(is)
|
||||
.withContentType(attachment.getContentType())
|
||||
.withLength(attachment.getSize())
|
||||
.withFileName(attachment.getFileName())
|
||||
.withVoiceNote(attachment.isVoiceNote())
|
||||
.withBorderless(attachment.isBorderless())
|
||||
.withGif(attachment.isVideoGif())
|
||||
.withFaststart(attachment.getTransformProperties().isMp4Faststart())
|
||||
.withWidth(attachment.getWidth())
|
||||
.withHeight(attachment.getHeight())
|
||||
.withContentType(attachment.contentType)
|
||||
.withLength(attachment.size)
|
||||
.withFileName(attachment.fileName)
|
||||
.withVoiceNote(attachment.voiceNote)
|
||||
.withBorderless(attachment.borderless)
|
||||
.withGif(attachment.videoGif)
|
||||
.withFaststart(attachment.transformProperties.mp4FastStart)
|
||||
.withWidth(attachment.width)
|
||||
.withHeight(attachment.height)
|
||||
.withUploadTimestamp(System.currentTimeMillis())
|
||||
.withCaption(attachment.getCaption())
|
||||
.withCaption(attachment.caption)
|
||||
.withCancelationSignal(this::isCanceled)
|
||||
.withResumableUploadSpec(resumableUploadSpec)
|
||||
.withListener(new SignalServiceAttachment.ProgressListener() {
|
||||
|
@ -214,9 +214,9 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
return isCanceled();
|
||||
}
|
||||
});
|
||||
if (MediaUtil.isImageType(attachment.getContentType())) {
|
||||
if (MediaUtil.isImageType(attachment.contentType)) {
|
||||
return builder.withBlurHash(getImageBlurHash(attachment)).build();
|
||||
} else if (MediaUtil.isVideoType(attachment.getContentType())) {
|
||||
} else if (MediaUtil.isVideoType(attachment.contentType)) {
|
||||
return builder.withBlurHash(getVideoBlurHash(attachment)).build();
|
||||
} else {
|
||||
return builder.build();
|
||||
|
@ -227,7 +227,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
}
|
||||
|
||||
private @Nullable String getImageBlurHash(@NonNull Attachment attachment) throws IOException {
|
||||
if (attachment.getBlurHash() != null) return attachment.getBlurHash().getHash();
|
||||
if (attachment.blurHash != null) return attachment.blurHash.getHash();
|
||||
if (attachment.getUri() == null) return null;
|
||||
|
||||
try (InputStream inputStream = PartAuthority.getAttachmentStream(context, attachment.getUri())) {
|
||||
|
@ -236,8 +236,8 @@ public final class LegacyAttachmentUploadJob extends BaseJob {
|
|||
}
|
||||
|
||||
private @Nullable String getVideoBlurHash(@NonNull Attachment attachment) throws IOException {
|
||||
if (attachment.getBlurHash() != null) {
|
||||
return attachment.getBlurHash().getHash();
|
||||
if (attachment.blurHash != null) {
|
||||
return attachment.blurHash.getHash();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
|
|
|
@ -285,21 +285,21 @@ public final class MmsSendJob extends SendJob {
|
|||
try {
|
||||
if (attachment.getUri() == null) throw new IOException("Assertion failed, attachment for outgoing MMS has no data!");
|
||||
|
||||
String fileName = attachment.getFileName();
|
||||
String fileName = attachment.fileName;
|
||||
PduPart part = new PduPart();
|
||||
|
||||
if (fileName == null) {
|
||||
fileName = String.valueOf(Math.abs(new SecureRandom().nextLong()));
|
||||
String fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(attachment.getContentType());
|
||||
String fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(attachment.contentType);
|
||||
|
||||
if (fileExtension != null) fileName = fileName + "." + fileExtension;
|
||||
}
|
||||
|
||||
if (attachment.getContentType().startsWith("text")) {
|
||||
if (attachment.contentType.startsWith("text")) {
|
||||
part.setCharset(CharacterSets.UTF_8);
|
||||
}
|
||||
|
||||
part.setContentType(attachment.getContentType().getBytes());
|
||||
part.setContentType(attachment.contentType.getBytes());
|
||||
part.setContentLocation(fileName.getBytes());
|
||||
part.setName(fileName.getBytes());
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public final class PushDistributionListSendJob extends PushSendJob {
|
|||
|
||||
if (!message.getStoryType().isTextStory()) {
|
||||
DatabaseAttachment storyAttachment = (DatabaseAttachment) message.getAttachments().get(0);
|
||||
SignalDatabase.attachments().updateAttachmentCaption(storyAttachment.getAttachmentId(), message.getBody());
|
||||
SignalDatabase.attachments().updateAttachmentCaption(storyAttachment.attachmentId, message.getBody());
|
||||
}
|
||||
|
||||
Set<String> attachmentUploadIds = enqueueCompressingAndUploadAttachmentsChains(jobManager, message);
|
||||
|
|
|
@ -197,20 +197,20 @@ public abstract class PushSendJob extends SendJob {
|
|||
|
||||
protected SignalServiceAttachment getAttachmentFor(Attachment attachment) {
|
||||
try {
|
||||
if (attachment.getUri() == null || attachment.getSize() == 0) throw new IOException("Assertion failed, outgoing attachment has no data!");
|
||||
if (attachment.getUri() == null || attachment.size == 0) throw new IOException("Assertion failed, outgoing attachment has no data!");
|
||||
InputStream is = PartAuthority.getAttachmentStream(context, attachment.getUri());
|
||||
return SignalServiceAttachment.newStreamBuilder()
|
||||
.withStream(is)
|
||||
.withContentType(attachment.getContentType())
|
||||
.withLength(attachment.getSize())
|
||||
.withFileName(attachment.getFileName())
|
||||
.withVoiceNote(attachment.isVoiceNote())
|
||||
.withBorderless(attachment.isBorderless())
|
||||
.withGif(attachment.isVideoGif())
|
||||
.withFaststart(attachment.getTransformProperties().isMp4Faststart())
|
||||
.withWidth(attachment.getWidth())
|
||||
.withHeight(attachment.getHeight())
|
||||
.withCaption(attachment.getCaption())
|
||||
.withContentType(attachment.contentType)
|
||||
.withLength(attachment.size)
|
||||
.withFileName(attachment.fileName)
|
||||
.withVoiceNote(attachment.voiceNote)
|
||||
.withBorderless(attachment.borderless)
|
||||
.withGif(attachment.videoGif)
|
||||
.withFaststart(attachment.transformProperties.mp4FastStart)
|
||||
.withWidth(attachment.width)
|
||||
.withHeight(attachment.height)
|
||||
.withCaption(attachment.caption)
|
||||
.withListener(new SignalServiceAttachment.ProgressListener() {
|
||||
@Override
|
||||
public void onAttachmentProgress(long total, long progress) {
|
||||
|
@ -246,7 +246,7 @@ public abstract class PushSendJob extends SendJob {
|
|||
.toList());
|
||||
|
||||
return new HashSet<>(Stream.of(attachments).map(a -> {
|
||||
AttachmentUploadJob attachmentUploadJob = new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId());
|
||||
AttachmentUploadJob attachmentUploadJob = new AttachmentUploadJob(((DatabaseAttachment) a).attachmentId);
|
||||
|
||||
jobManager.startChain(AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, false, -1))
|
||||
.then(attachmentUploadJob)
|
||||
|
@ -262,22 +262,22 @@ public abstract class PushSendJob extends SendJob {
|
|||
}
|
||||
|
||||
protected @Nullable SignalServiceAttachment getAttachmentPointerFor(Attachment attachment) {
|
||||
if (TextUtils.isEmpty(attachment.getLocation())) {
|
||||
if (TextUtils.isEmpty(attachment.location)) {
|
||||
Log.w(TAG, "empty content id");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(attachment.getKey())) {
|
||||
if (TextUtils.isEmpty(attachment.key)) {
|
||||
Log.w(TAG, "empty encrypted key");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.getLocation());
|
||||
final byte[] key = Base64.decode(attachment.getKey());
|
||||
final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.location);
|
||||
final byte[] key = Base64.decode(attachment.key);
|
||||
|
||||
int width = attachment.getWidth();
|
||||
int height = attachment.getHeight();
|
||||
int width = attachment.width;
|
||||
int height = attachment.height;
|
||||
|
||||
if ((width == 0 || height == 0) && MediaUtil.hasVideoThumbnail(context, attachment.getUri())) {
|
||||
Bitmap thumbnail = MediaUtil.getVideoThumbnail(context, attachment.getUri(), 1000);
|
||||
|
@ -288,24 +288,24 @@ public abstract class PushSendJob extends SendJob {
|
|||
}
|
||||
}
|
||||
|
||||
return new SignalServiceAttachmentPointer(attachment.getCdnNumber(),
|
||||
return new SignalServiceAttachmentPointer(attachment.cdnNumber,
|
||||
remoteId,
|
||||
attachment.getContentType(),
|
||||
attachment.contentType,
|
||||
key,
|
||||
Optional.of(Util.toIntExact(attachment.getSize())),
|
||||
Optional.of(Util.toIntExact(attachment.size)),
|
||||
Optional.empty(),
|
||||
width,
|
||||
height,
|
||||
Optional.ofNullable(attachment.getDigest()),
|
||||
Optional.ofNullable(attachment.digest),
|
||||
Optional.ofNullable(attachment.getIncrementalDigest()),
|
||||
attachment.getIncrementalMacChunkSize(),
|
||||
Optional.ofNullable(attachment.getFileName()),
|
||||
attachment.isVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
attachment.isVideoGif(),
|
||||
Optional.ofNullable(attachment.getCaption()),
|
||||
Optional.ofNullable(attachment.getBlurHash()).map(BlurHash::getHash),
|
||||
attachment.getUploadTimestamp());
|
||||
attachment.incrementalMacChunkSize,
|
||||
Optional.ofNullable(attachment.fileName),
|
||||
attachment.voiceNote,
|
||||
attachment.borderless,
|
||||
attachment.videoGif,
|
||||
Optional.ofNullable(attachment.caption),
|
||||
Optional.ofNullable(attachment.blurHash).map(BlurHash::getHash),
|
||||
attachment.uploadTimestamp);
|
||||
} catch (IOException | ArithmeticException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
|
@ -353,7 +353,7 @@ public abstract class PushSendJob extends SendJob {
|
|||
Optional<Attachment> localQuoteAttachment = message.getOutgoingQuote()
|
||||
.getAttachments()
|
||||
.stream()
|
||||
.filter(a -> !MediaUtil.isViewOnceType(a.getContentType()))
|
||||
.filter(a -> !MediaUtil.isViewOnceType(a.contentType))
|
||||
.findFirst();
|
||||
|
||||
if (localQuoteAttachment.isPresent()) {
|
||||
|
@ -363,13 +363,13 @@ public abstract class PushSendJob extends SendJob {
|
|||
SignalServiceAttachment thumbnail = null;
|
||||
|
||||
try {
|
||||
if (MediaUtil.isImageType(attachment.getContentType()) && attachment.getUri() != null) {
|
||||
thumbnailData = ImageCompressionUtil.compress(context, attachment.getContentType(), new DecryptableUri(attachment.getUri()), 100, 50);
|
||||
} else if (Build.VERSION.SDK_INT >= 23 && MediaUtil.isVideoType(attachment.getContentType()) && attachment.getUri() != null) {
|
||||
if (MediaUtil.isImageType(attachment.contentType) && attachment.getUri() != null) {
|
||||
thumbnailData = ImageCompressionUtil.compress(context, attachment.contentType, new DecryptableUri(attachment.getUri()), 100, 50);
|
||||
} else if (Build.VERSION.SDK_INT >= 23 && MediaUtil.isVideoType(attachment.contentType) && attachment.getUri() != null) {
|
||||
Bitmap bitmap = MediaUtil.getVideoThumbnail(context, attachment.getUri(), 1000);
|
||||
|
||||
if (bitmap != null) {
|
||||
thumbnailData = ImageCompressionUtil.compress(context, attachment.getContentType(), new DecryptableUri(attachment.getUri()), 100, 50);
|
||||
thumbnailData = ImageCompressionUtil.compress(context, attachment.contentType, new DecryptableUri(attachment.getUri()), 100, 50);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,8 +385,8 @@ public abstract class PushSendJob extends SendJob {
|
|||
thumbnail = builder.build();
|
||||
}
|
||||
|
||||
quoteAttachments.add(new SignalServiceDataMessage.Quote.QuotedAttachment(attachment.isVideoGif() ? MediaUtil.IMAGE_GIF : attachment.getContentType(),
|
||||
attachment.getFileName(),
|
||||
quoteAttachments.add(new SignalServiceDataMessage.Quote.QuotedAttachment(attachment.videoGif ? MediaUtil.IMAGE_GIF : attachment.contentType,
|
||||
attachment.fileName,
|
||||
thumbnail));
|
||||
} catch (BitmapDecodingException e) {
|
||||
Log.w(TAG, e);
|
||||
|
@ -412,10 +412,10 @@ public abstract class PushSendJob extends SendJob {
|
|||
}
|
||||
|
||||
try {
|
||||
byte[] packId = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackId());
|
||||
byte[] packKey = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackKey());
|
||||
int stickerId = stickerAttachment.getSticker().getStickerId();
|
||||
StickerRecord record = SignalDatabase.stickers().getSticker(stickerAttachment.getSticker().getPackId(), stickerId, false);
|
||||
byte[] packId = Hex.fromStringCondensed(stickerAttachment.stickerLocator.packId);
|
||||
byte[] packKey = Hex.fromStringCondensed(stickerAttachment.stickerLocator.packKey);
|
||||
int stickerId = stickerAttachment.stickerLocator.stickerId;
|
||||
StickerRecord record = SignalDatabase.stickers().getSticker(stickerAttachment.stickerLocator.packId, stickerId, false);
|
||||
String emoji = record != null ? record.getEmoji() : null;
|
||||
SignalServiceAttachment attachment = getAttachmentPointerFor(stickerAttachment);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public abstract class SendJob extends BaseJob {
|
|||
protected String buildAttachmentString(@NonNull List<Attachment> attachments) {
|
||||
List<String> strings = attachments.stream().map(attachment -> {
|
||||
if (attachment instanceof DatabaseAttachment) {
|
||||
return ((DatabaseAttachment) attachment).getAttachmentId().toString();
|
||||
return ((DatabaseAttachment) attachment).attachmentId.toString();
|
||||
} else if (attachment.getUri() != null) {
|
||||
return attachment.getUri().toString();
|
||||
} else {
|
||||
|
|
|
@ -45,7 +45,7 @@ public class LinkPreview implements Parcelable {
|
|||
this.description = description;
|
||||
this.date = date;
|
||||
this.thumbnail = Optional.of(thumbnail);
|
||||
this.attachmentId = thumbnail.getAttachmentId();
|
||||
this.attachmentId = thumbnail.attachmentId;
|
||||
}
|
||||
|
||||
public LinkPreview(@NonNull String url, @NonNull String title, @NonNull String description, long date, @NonNull Optional<Attachment> thumbnail) {
|
||||
|
|
|
@ -101,7 +101,7 @@ final class MediaActions {
|
|||
attachments.add(new SaveAttachmentTask.Attachment(mediaRecord.getAttachment().getUri(),
|
||||
mediaRecord.getContentType(),
|
||||
mediaRecord.getDate(),
|
||||
mediaRecord.getAttachment().getFileName()));
|
||||
mediaRecord.getAttachment().fileName));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
|
|||
}
|
||||
|
||||
public void toggleSelection(@NonNull MediaRecord mediaRecord) {
|
||||
AttachmentId attachmentId = mediaRecord.getAttachment().getAttachmentId();
|
||||
AttachmentId attachmentId = mediaRecord.getAttachment().attachmentId;
|
||||
MediaTable.MediaRecord removed = selected.remove(attachmentId);
|
||||
if (removed == null) {
|
||||
selected.put(attachmentId, mediaRecord);
|
||||
|
@ -219,7 +219,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
|
|||
public long getSelectedMediaTotalFileSize() {
|
||||
//noinspection ConstantConditions attacment cannot be null if selected
|
||||
return Stream.of(selected.values())
|
||||
.collect(Collectors.summingLong(a -> a.getAttachment().getSize()));
|
||||
.collect(Collectors.summingLong(a -> a.getAttachment().size));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -238,7 +238,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
|
|||
int sectionItemCount = media.getSectionItemCount(section);
|
||||
for (int item = 0; item < sectionItemCount; item++) {
|
||||
MediaRecord mediaRecord = media.get(section, item);
|
||||
selected.put(mediaRecord.getAttachment().getAttachmentId(), mediaRecord);
|
||||
selected.put(mediaRecord.getAttachment().attachmentId, mediaRecord);
|
||||
}
|
||||
}
|
||||
this.notifyItemRangeChanged(0, getItemCount(), PAYLOAD_SELECTED);
|
||||
|
@ -282,7 +282,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
|
|||
}
|
||||
|
||||
protected boolean isSelected() {
|
||||
return selected.containsKey(mediaRecord.getAttachment().getAttachmentId());
|
||||
return selected.containsKey(mediaRecord.getAttachment().attachmentId);
|
||||
}
|
||||
|
||||
protected void updateSelectedView() {
|
||||
|
@ -539,11 +539,11 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
|
|||
throw new AssertionError();
|
||||
}
|
||||
|
||||
isVoiceNote = slide.asAttachment().isVoiceNote();
|
||||
isVoiceNote = slide.asAttachment().voiceNote;
|
||||
|
||||
super.bind(context, mediaRecord, slide);
|
||||
|
||||
long mmsId = Objects.requireNonNull(mediaRecord.getAttachment()).getMmsId();
|
||||
long mmsId = Objects.requireNonNull(mediaRecord.getAttachment()).mmsId;
|
||||
|
||||
audioItemListener.unregisterPlaybackStateObserver(audioView.getPlaybackStateObserver());
|
||||
audioView.setAudio((AudioSlide) slide, new AudioViewCallbacksAdapter(audioItemListener, mmsId), true, true);
|
||||
|
|
|
@ -247,17 +247,17 @@ public final class MediaOverviewPageFragment extends Fragment
|
|||
mediaRecord.getDate(),
|
||||
Objects.requireNonNull(mediaRecord.getAttachment().getUri()),
|
||||
mediaRecord.getContentType(),
|
||||
mediaRecord.getAttachment().getSize(),
|
||||
mediaRecord.getAttachment().getCaption(),
|
||||
mediaRecord.getAttachment().size,
|
||||
mediaRecord.getAttachment().caption,
|
||||
true,
|
||||
true,
|
||||
threadId == MediaTable.ALL_THREADS,
|
||||
true,
|
||||
sorting,
|
||||
attachment.isVideoGif(),
|
||||
attachment.videoGif,
|
||||
new MediaIntentFactory.SharedElementArgs(
|
||||
attachment.getWidth(),
|
||||
attachment.getHeight(),
|
||||
attachment.width,
|
||||
attachment.height,
|
||||
DimensionUnit.DP.toDp(12),
|
||||
DimensionUnit.DP.toDp(12),
|
||||
DimensionUnit.DP.toDp(12),
|
||||
|
|
|
@ -77,7 +77,7 @@ object MediaIntentFactory {
|
|||
leftIsRecent,
|
||||
allMediaInRail = allMediaInRail,
|
||||
sorting = MediaTable.Sorting.Newest,
|
||||
isVideoGif = attachment.isVideoGif,
|
||||
isVideoGif = attachment.videoGif,
|
||||
sharedElementArgs = SharedElementArgs(
|
||||
attachment.width,
|
||||
attachment.height,
|
||||
|
|
|
@ -31,8 +31,8 @@ class MediaPreviewV2Adapter(fragment: Fragment) : FragmentStateAdapter(fragment)
|
|||
MediaPreviewFragment.DATA_URI to attachment.uri,
|
||||
MediaPreviewFragment.DATA_CONTENT_TYPE to contentType,
|
||||
MediaPreviewFragment.DATA_SIZE to attachment.size,
|
||||
MediaPreviewFragment.AUTO_PLAY to attachment.isVideoGif,
|
||||
MediaPreviewFragment.VIDEO_GIF to attachment.isVideoGif
|
||||
MediaPreviewFragment.AUTO_PLAY to attachment.videoGif,
|
||||
MediaPreviewFragment.VIDEO_GIF to attachment.videoGif
|
||||
)
|
||||
val fragment = if (MediaUtil.isVideo(contentType)) {
|
||||
VideoMediaPreviewFragment()
|
||||
|
|
|
@ -331,7 +331,7 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
|
|||
}
|
||||
|
||||
private fun bindMediaPreviewPlaybackControls(currentItem: MediaTable.MediaRecord, currentFragment: MediaPreviewFragment?) {
|
||||
val mediaType: MediaPreviewPlayerControlView.MediaMode = if (currentItem.attachment?.isVideoGif == true) {
|
||||
val mediaType: MediaPreviewPlayerControlView.MediaMode = if (currentItem.attachment?.videoGif == true) {
|
||||
MediaPreviewPlayerControlView.MediaMode.IMAGE
|
||||
} else {
|
||||
MediaPreviewPlayerControlView.MediaMode.fromString(currentItem.contentType)
|
||||
|
|
|
@ -127,8 +127,8 @@ fun MediaTable.MediaRecord.toMedia(): Media? {
|
|||
attachment.height,
|
||||
attachment.size,
|
||||
0,
|
||||
attachment.isBorderless,
|
||||
attachment.isVideoGif,
|
||||
attachment.borderless,
|
||||
attachment.videoGif,
|
||||
Optional.empty(),
|
||||
Optional.ofNullable(attachment.caption),
|
||||
Optional.empty()
|
||||
|
|
|
@ -100,7 +100,7 @@ public class MediaUploadRepository {
|
|||
return oldProperties == newProperties;
|
||||
}
|
||||
|
||||
return !newProperties.isVideoEdited() && oldProperties.getSentMediaQuality() == newProperties.getSentMediaQuality();
|
||||
return !newProperties.getVideoEdited() && oldProperties.sentMediaQuality == newProperties.sentMediaQuality;
|
||||
}
|
||||
|
||||
public void cancelUpload(@NonNull Media media) {
|
||||
|
|
|
@ -109,7 +109,7 @@ class MediaSelectionRepository(context: Context) {
|
|||
val updatedMedia = oldToNewMediaMap.values.toList()
|
||||
|
||||
for (media in updatedMedia) {
|
||||
Log.w(TAG, media.uri.toString() + " : " + media.transformProperties.map { t: TransformProperties -> "" + t.isVideoTrim }.orElse("null"))
|
||||
Log.w(TAG, media.uri.toString() + " : " + media.transformProperties.map { t: TransformProperties -> "" + t.videoTrim }.orElse("null"))
|
||||
}
|
||||
|
||||
val singleRecipient: Recipient? = singleContact?.let { Recipient.resolved(it.recipientId) }
|
||||
|
|
|
@ -246,15 +246,15 @@ public class LegacyMigrationJob extends MigrationJob {
|
|||
|
||||
Log.i(TAG, pendingAttachments.size() + " pending parts.");
|
||||
for (DatabaseAttachment attachment : pendingAttachments) {
|
||||
final MmsReader reader = MessageTable.mmsReaderFor(mmsDb.getMessageCursor(attachment.getMmsId()));
|
||||
final MmsReader reader = MessageTable.mmsReaderFor(mmsDb.getMessageCursor(attachment.mmsId));
|
||||
final MessageRecord record = reader.getNext();
|
||||
|
||||
if (attachment.hasData()) {
|
||||
Log.i(TAG, "corrected a pending media part " + attachment.getAttachmentId() + "that already had data.");
|
||||
attachmentDb.setTransferState(attachment.getMmsId(), attachment.getAttachmentId(), AttachmentTable.TRANSFER_PROGRESS_DONE);
|
||||
if (attachment.hasData) {
|
||||
Log.i(TAG, "corrected a pending media part " + attachment.attachmentId + "that already had data.");
|
||||
attachmentDb.setTransferState(attachment.mmsId, attachment.attachmentId, AttachmentTable.TRANSFER_PROGRESS_DONE);
|
||||
} else if (record != null && !record.isOutgoing() && record.isPush()) {
|
||||
Log.i(TAG, "queuing new attachment download job for incoming push part " + attachment.getAttachmentId() + ".");
|
||||
ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(attachment.getMmsId(), attachment.getAttachmentId(), false));
|
||||
Log.i(TAG, "queuing new attachment download job for incoming push part " + attachment.attachmentId + ".");
|
||||
ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(attachment.mmsId, attachment.attachmentId, false));
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ public class AttachmentManager {
|
|||
result.set(true);
|
||||
} else {
|
||||
Attachment attachment = slide.asAttachment();
|
||||
result.deferTo(thumbnail.setImageResource(glideRequests, slide, false, true, attachment.getWidth(), attachment.getHeight()));
|
||||
result.deferTo(thumbnail.setImageResource(glideRequests, slide, false, true, attachment.width, attachment.height));
|
||||
removableMediaView.display(thumbnail, mediaType == SlideFactory.MediaType.IMAGE);
|
||||
}
|
||||
|
||||
|
@ -546,7 +546,7 @@ public class AttachmentManager {
|
|||
MediaIntentFactory.UNKNOWN_TIMESTAMP,
|
||||
slide.getUri(),
|
||||
slide.getContentType(),
|
||||
slide.asAttachment().getSize(),
|
||||
slide.asAttachment().size,
|
||||
slide.getCaption().orElse(null),
|
||||
false,
|
||||
false,
|
||||
|
|
|
@ -14,7 +14,7 @@ public class GifSlide extends ImageSlide {
|
|||
|
||||
public GifSlide(Attachment attachment) {
|
||||
super(attachment);
|
||||
this.borderless = attachment.isBorderless();
|
||||
this.borderless = attachment.borderless;
|
||||
}
|
||||
|
||||
public GifSlide(Context context, Uri uri, long size, int width, int height) {
|
||||
|
|
|
@ -40,7 +40,7 @@ public class ImageSlide extends Slide {
|
|||
|
||||
public ImageSlide(@NonNull Attachment attachment) {
|
||||
super(attachment);
|
||||
this.borderless = attachment.isBorderless();
|
||||
this.borderless = attachment.borderless;
|
||||
}
|
||||
|
||||
public ImageSlide(Context context, Uri uri, long size, int width, int height, @Nullable BlurHash blurHash) {
|
||||
|
|
|
@ -75,7 +75,7 @@ public abstract class MediaConstraints {
|
|||
|
||||
public boolean isSatisfied(@NonNull Context context, @NonNull Attachment attachment) {
|
||||
try {
|
||||
long size = attachment.getSize();
|
||||
long size = attachment.size;
|
||||
if (size > getMaxAttachmentSize()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public class PartAuthority {
|
|||
case PART_ROW:
|
||||
Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId());
|
||||
|
||||
if (attachment != null) return attachment.getFileName();
|
||||
if (attachment != null) return attachment.fileName;
|
||||
else return null;
|
||||
case PERSISTENT_ROW:
|
||||
return DeprecatedPersistentBlobProvider.getFileName(context, uri);
|
||||
|
@ -115,7 +115,7 @@ public class PartAuthority {
|
|||
case PART_ROW:
|
||||
Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId());
|
||||
|
||||
if (attachment != null) return attachment.getSize();
|
||||
if (attachment != null) return attachment.size;
|
||||
else return null;
|
||||
case PERSISTENT_ROW:
|
||||
return DeprecatedPersistentBlobProvider.getFileSize(context, uri);
|
||||
|
@ -133,7 +133,7 @@ public class PartAuthority {
|
|||
case PART_ROW:
|
||||
Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId());
|
||||
|
||||
if (attachment != null) return attachment.getContentType();
|
||||
if (attachment != null) return attachment.contentType;
|
||||
else return null;
|
||||
case PERSISTENT_ROW:
|
||||
return DeprecatedPersistentBlobProvider.getMimeType(context, uri);
|
||||
|
@ -151,7 +151,7 @@ public class PartAuthority {
|
|||
case PART_ROW:
|
||||
Attachment attachment = SignalDatabase.attachments().getAttachment(new PartUriParser(uri).getPartId());
|
||||
|
||||
if (attachment != null) return attachment.isVideoGif();
|
||||
if (attachment != null) return attachment.videoGif;
|
||||
else return false;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -46,7 +46,7 @@ public abstract class Slide {
|
|||
}
|
||||
|
||||
public String getContentType() {
|
||||
return attachment.getContentType();
|
||||
return attachment.contentType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -69,21 +69,21 @@ public abstract class Slide {
|
|||
|
||||
@NonNull
|
||||
public Optional<String> getCaption() {
|
||||
return Optional.ofNullable(attachment.getCaption());
|
||||
return Optional.ofNullable(attachment.caption);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Optional<String> getFileName() {
|
||||
return Optional.ofNullable(attachment.getFileName());
|
||||
return Optional.ofNullable(attachment.fileName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFastPreflightId() {
|
||||
return attachment.getFastPreflightId();
|
||||
return attachment.fastPreflightId;
|
||||
}
|
||||
|
||||
public long getFileSize() {
|
||||
return attachment.getSize();
|
||||
return attachment.size;
|
||||
}
|
||||
|
||||
public boolean hasImage() {
|
||||
|
@ -117,7 +117,7 @@ public abstract class Slide {
|
|||
}
|
||||
|
||||
public boolean isVideoGif() {
|
||||
return hasVideo() && attachment.isVideoGif();
|
||||
return hasVideo() && attachment.videoGif;
|
||||
}
|
||||
|
||||
public @NonNull String getContentDescription(@NonNull Context context) { return ""; }
|
||||
|
@ -136,7 +136,7 @@ public abstract class Slide {
|
|||
}
|
||||
|
||||
public int getTransferState() {
|
||||
return attachment.getTransferState();
|
||||
return attachment.transferState;
|
||||
}
|
||||
|
||||
public @DrawableRes int getPlaceholderRes(Theme theme) {
|
||||
|
@ -144,7 +144,7 @@ public abstract class Slide {
|
|||
}
|
||||
|
||||
public @Nullable BlurHash getPlaceholderBlur() {
|
||||
return attachment.getBlurHash();
|
||||
return attachment.blurHash;
|
||||
}
|
||||
|
||||
public boolean hasPlaceholder() {
|
||||
|
|
|
@ -23,12 +23,12 @@ public class StickerSlide extends Slide {
|
|||
|
||||
public StickerSlide(@NonNull Attachment attachment) {
|
||||
super(attachment);
|
||||
this.stickerLocator = Objects.requireNonNull(attachment.getSticker());
|
||||
this.stickerLocator = Objects.requireNonNull(attachment.stickerLocator);
|
||||
}
|
||||
|
||||
public StickerSlide(Context context, Uri uri, long size, @NonNull StickerLocator stickerLocator, @NonNull String contentType) {
|
||||
super(constructAttachmentFromUri(context, uri, contentType, size, WIDTH, HEIGHT, true, null, null, stickerLocator, null, null, false, false, false, false));
|
||||
this.stickerLocator = Objects.requireNonNull(attachment.getSticker());
|
||||
this.stickerLocator = Objects.requireNonNull(attachment.stickerLocator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,6 +52,6 @@ public class StickerSlide extends Slide {
|
|||
}
|
||||
|
||||
public @Nullable String getEmoji() {
|
||||
return stickerLocator.getEmoji();
|
||||
return stickerLocator.emoji;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,8 +134,8 @@ public final class PartProvider extends BaseContentProvider {
|
|||
DatabaseAttachment attachment = SignalDatabase.attachments().getAttachment(partUriParser.getPartId());
|
||||
|
||||
if (attachment != null) {
|
||||
Log.i(TAG, "getType() called: " + uri + " It's " + attachment.getContentType());
|
||||
return attachment.getContentType();
|
||||
Log.i(TAG, "getType() called: " + uri + " It's " + attachment.contentType);
|
||||
return attachment.contentType;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,15 +163,15 @@ public final class PartProvider extends BaseContentProvider {
|
|||
|
||||
if (attachment == null) return null;
|
||||
|
||||
long fileSize = attachment.getSize();
|
||||
long fileSize = attachment.size;
|
||||
|
||||
if (fileSize <= 0) {
|
||||
Log.w(TAG, "Empty file " + fileSize);
|
||||
return null;
|
||||
}
|
||||
|
||||
String fileName = attachment.getFileName() != null ? attachment.getFileName()
|
||||
: createFileNameForMimeType(attachment.getContentType());
|
||||
String fileName = attachment.fileName != null ? attachment.fileName
|
||||
: createFileNameForMimeType(attachment.contentType);
|
||||
|
||||
return createCursor(projection, fileName, fileSize);
|
||||
} else {
|
||||
|
@ -229,9 +229,9 @@ public final class PartProvider extends BaseContentProvider {
|
|||
@Override
|
||||
public long onGetSize() throws ErrnoException {
|
||||
DatabaseAttachment attachment = attachments.getAttachment(attachmentId);
|
||||
if (attachment != null && attachment.getSize() > 0) {
|
||||
if (attachment != null && attachment.size > 0) {
|
||||
Log.i(TAG, attachmentId + ":getSize");
|
||||
return attachment.getSize();
|
||||
return attachment.size;
|
||||
} else {
|
||||
Log.w(TAG, attachmentId + ":getSize:attachment is null or size is 0");
|
||||
throw new ErrnoException("Attachment is invalid", OsConstants.ENOENT);
|
||||
|
@ -242,7 +242,7 @@ public final class PartProvider extends BaseContentProvider {
|
|||
public int onRead(long offset, int size, byte[] data) throws ErrnoException {
|
||||
try {
|
||||
DatabaseAttachment attachment = attachments.getAttachment(attachmentId);
|
||||
if (attachment == null || attachment.getSize() <= 0) {
|
||||
if (attachment == null || attachment.size <= 0) {
|
||||
Log.w(TAG, attachmentId + ":onRead:attachment is null or size is 0");
|
||||
throw new ErrnoException("Attachment is invalid", OsConstants.ENOENT);
|
||||
}
|
||||
|
|
|
@ -95,8 +95,8 @@ public class ViewOnceMessageView extends LinearLayout {
|
|||
}
|
||||
|
||||
Attachment attachment = messageRecord.getSlideDeck().getThumbnailSlide().asAttachment();
|
||||
return attachment.getTransferState() == AttachmentTable.TRANSFER_PROGRESS_FAILED ||
|
||||
attachment.getTransferState() == AttachmentTable.TRANSFER_PROGRESS_PENDING;
|
||||
return attachment.transferState == AttachmentTable.TRANSFER_PROGRESS_FAILED ||
|
||||
attachment.transferState == AttachmentTable.TRANSFER_PROGRESS_PENDING;
|
||||
}
|
||||
|
||||
public void setMessage(@NonNull MmsMessageRecord message, boolean hasWallpaper) {
|
||||
|
@ -169,7 +169,7 @@ public class ViewOnceMessageView extends LinearLayout {
|
|||
if (messageRecord.getSlideDeck().getThumbnailSlide() == null) return false;
|
||||
|
||||
Attachment attachment = messageRecord.getSlideDeck().getThumbnailSlide().asAttachment();
|
||||
return attachment.getTransferState() == AttachmentTable.TRANSFER_PROGRESS_STARTED;
|
||||
return attachment.transferState == AttachmentTable.TRANSFER_PROGRESS_STARTED;
|
||||
}
|
||||
|
||||
private @NonNull String formatFileSize(@NonNull MmsMessageRecord messageRecord) {
|
||||
|
|
|
@ -329,15 +329,15 @@ public final class MultiShareSender {
|
|||
: thumbnail.getUri() == null
|
||||
? null
|
||||
: new ImageSlide(context,
|
||||
thumbnail.getUri(),
|
||||
thumbnail.getContentType(),
|
||||
thumbnail.getSize(),
|
||||
thumbnail.getWidth(),
|
||||
thumbnail.getHeight(),
|
||||
thumbnail.isBorderless(),
|
||||
thumbnail.getCaption(),
|
||||
thumbnail.getBlurHash(),
|
||||
thumbnail.getTransformProperties()).asAttachment()
|
||||
thumbnail.getUri(),
|
||||
thumbnail.contentType,
|
||||
thumbnail.size,
|
||||
thumbnail.width,
|
||||
thumbnail.height,
|
||||
thumbnail.borderless,
|
||||
thumbnail.caption,
|
||||
thumbnail.blurHash,
|
||||
thumbnail.transformProperties).asAttachment()
|
||||
)
|
||||
));
|
||||
}
|
||||
|
@ -345,17 +345,17 @@ public final class MultiShareSender {
|
|||
|
||||
private static Slide ensureDefaultQuality(@NonNull Context context, @NonNull ImageSlide imageSlide) {
|
||||
Attachment attachment = imageSlide.asAttachment();
|
||||
if (attachment.getTransformProperties().getSentMediaQuality() == SentMediaQuality.HIGH.getCode()) {
|
||||
if (attachment.transformProperties.sentMediaQuality == SentMediaQuality.HIGH.getCode()) {
|
||||
return new ImageSlide(
|
||||
context,
|
||||
attachment.getUri(),
|
||||
attachment.getContentType(),
|
||||
attachment.getSize(),
|
||||
attachment.getWidth(),
|
||||
attachment.getHeight(),
|
||||
attachment.isBorderless(),
|
||||
attachment.getCaption(),
|
||||
attachment.getBlurHash(),
|
||||
attachment.contentType,
|
||||
attachment.size,
|
||||
attachment.width,
|
||||
attachment.height,
|
||||
attachment.borderless,
|
||||
attachment.caption,
|
||||
attachment.blurHash,
|
||||
AttachmentTable.TransformProperties.empty()
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -344,7 +344,7 @@ public class MessageSender {
|
|||
List<AttachmentId> attachmentIds = new ArrayList<>(preUploadAttachmentIds.size());
|
||||
|
||||
for (int i = 0; i < preUploadAttachments.size(); i++) {
|
||||
AttachmentId attachmentId = attachmentDatabase.insertAttachmentForPreUpload(preUploadAttachments.get(i)).getAttachmentId();
|
||||
AttachmentId attachmentId = attachmentDatabase.insertAttachmentForPreUpload(preUploadAttachments.get(i)).attachmentId;
|
||||
attachmentCopies.get(i).add(attachmentId);
|
||||
attachmentIds.add(attachmentId);
|
||||
}
|
||||
|
@ -418,14 +418,14 @@ public class MessageSender {
|
|||
DatabaseAttachment databaseAttachment = attachmentDatabase.insertAttachmentForPreUpload(attachment);
|
||||
|
||||
Job compressionJob = AttachmentCompressionJob.fromAttachment(databaseAttachment, false, -1);
|
||||
Job uploadJob = new AttachmentUploadJob(databaseAttachment.getAttachmentId());
|
||||
Job uploadJob = new AttachmentUploadJob(databaseAttachment.attachmentId);
|
||||
|
||||
ApplicationDependencies.getJobManager()
|
||||
.startChain(compressionJob)
|
||||
.then(uploadJob)
|
||||
.enqueue();
|
||||
|
||||
return new PreUploadResult(media, databaseAttachment.getAttachmentId(), Arrays.asList(compressionJob.getId(), uploadJob.getId()));
|
||||
return new PreUploadResult(media, databaseAttachment.attachmentId, Arrays.asList(compressionJob.getId(), uploadJob.getId()));
|
||||
} catch (MmsException e) {
|
||||
Log.w(TAG, "preUploadPushAttachment() - Failed to upload!", e);
|
||||
return null;
|
||||
|
@ -645,7 +645,7 @@ public class MessageSender {
|
|||
.toList();
|
||||
|
||||
List<AttachmentMarkUploadedJob> fakeUploadJobs = Stream.of(attachments)
|
||||
.map(a -> new AttachmentMarkUploadedJob(messageId, ((DatabaseAttachment) a).getAttachmentId()))
|
||||
.map(a -> new AttachmentMarkUploadedJob(messageId, ((DatabaseAttachment) a).attachmentId))
|
||||
.toList();
|
||||
|
||||
ApplicationDependencies.getJobManager().startChain(compressionJobs)
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.thoughtcrime.securesms.attachments.AttachmentId
|
|||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
|
||||
import org.thoughtcrime.securesms.attachments.UriAttachment
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager
|
||||
import org.thoughtcrime.securesms.jobs.AttachmentCompressionJob
|
||||
|
@ -43,7 +44,7 @@ class UploadDependencyGraph private constructor(
|
|||
*/
|
||||
private data class AttachmentKey<A : Attachment>(
|
||||
val attachment: A,
|
||||
private val transformProperties: AttachmentTable.TransformProperties = attachment.transformProperties
|
||||
private val transformProperties: AttachmentTable.TransformProperties = attachment.transformProperties ?: AttachmentTable.TransformProperties.empty()
|
||||
)
|
||||
|
||||
private var hasConsumedJobQueue = false
|
||||
|
@ -75,14 +76,14 @@ class UploadDependencyGraph private constructor(
|
|||
* Allows representation of a unique database attachment by its internal id and its transform properties.
|
||||
*/
|
||||
private fun DatabaseAttachment.asDatabaseAttachmentKey(): AttachmentKey<DatabaseAttachment> {
|
||||
return AttachmentKey(this, this.transformProperties)
|
||||
return AttachmentKey(this, this.transformProperties ?: TransformProperties.empty())
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows representation of a unique URI attachment by its internal Uri and its transform properties.
|
||||
*/
|
||||
private fun UriAttachment.asUriAttachmentKey(): AttachmentKey<UriAttachment> {
|
||||
return AttachmentKey(this, transformProperties)
|
||||
return AttachmentKey(this, transformProperties ?: TransformProperties.empty())
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,7 +120,7 @@ class UploadDependencyGraph private constructor(
|
|||
message.linkPreviews.mapNotNull { it.thumbnail.orElse(null) } +
|
||||
message.sharedContacts.mapNotNull { it.avatar?.attachment }
|
||||
|
||||
val uniqueAttachments: Set<AttachmentKey<Attachment>> = attachmentList.map { AttachmentKey(it, it.transformProperties) }.toSet()
|
||||
val uniqueAttachments: Set<AttachmentKey<Attachment>> = attachmentList.map { AttachmentKey(it, it.transformProperties ?: TransformProperties.empty()) }.toSet()
|
||||
|
||||
for (attachmentKey in uniqueAttachments) {
|
||||
when (val attachment = attachmentKey.attachment) {
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
package org.thoughtcrime.securesms.stickers;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class StickerLocator implements Parcelable {
|
||||
|
||||
private final String packId;
|
||||
private final String packKey;
|
||||
private final int stickerId;
|
||||
private final String emoji;
|
||||
|
||||
public StickerLocator(@NonNull String packId, @NonNull String packKey, int stickerId, @Nullable String emoji) {
|
||||
this.packId = packId;
|
||||
this.packKey = packKey;
|
||||
this.stickerId = stickerId;
|
||||
this.emoji = emoji;
|
||||
}
|
||||
|
||||
private StickerLocator(Parcel in) {
|
||||
packId = in.readString();
|
||||
packKey = in.readString();
|
||||
stickerId = in.readInt();
|
||||
emoji = in.readString();
|
||||
}
|
||||
|
||||
public @NonNull String getPackId() {
|
||||
return packId;
|
||||
}
|
||||
|
||||
public @NonNull String getPackKey() {
|
||||
return packKey;
|
||||
}
|
||||
|
||||
public int getStickerId() {
|
||||
return stickerId;
|
||||
}
|
||||
|
||||
public @Nullable String getEmoji() {
|
||||
return emoji;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(packId);
|
||||
dest.writeString(packKey);
|
||||
dest.writeInt(stickerId);
|
||||
dest.writeString(emoji);
|
||||
}
|
||||
|
||||
public static final Creator<StickerLocator> CREATOR = new Creator<StickerLocator>() {
|
||||
@Override
|
||||
public StickerLocator createFromParcel(Parcel in) {
|
||||
return new StickerLocator(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StickerLocator[] newArray(int size) {
|
||||
return new StickerLocator[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.thoughtcrime.securesms.stickers
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class StickerLocator(
|
||||
@JvmField
|
||||
val packId: String,
|
||||
@JvmField
|
||||
val packKey: String,
|
||||
@JvmField
|
||||
val stickerId: Int,
|
||||
@JvmField
|
||||
val emoji: String?
|
||||
) : Parcelable
|
|
@ -246,7 +246,7 @@ object Stories {
|
|||
return if (MediaUtil.isVideo(media.mimeType)) {
|
||||
val mediaDuration = if (media.duration == 0L && media.transformProperties.map(TransformProperties::shouldSkipTransform).orElse(true)) {
|
||||
getVideoDuration(media.uri)
|
||||
} else if (media.transformProperties.map { it.isVideoTrim }.orElse(false)) {
|
||||
} else if (media.transformProperties.map { it.videoTrim }.orElse(false)) {
|
||||
TimeUnit.MICROSECONDS.toMillis(media.transformProperties.get().videoTrimEndTimeUs - media.transformProperties.get().videoTrimStartTimeUs)
|
||||
} else {
|
||||
media.duration
|
||||
|
|
|
@ -41,18 +41,18 @@ class StoryPostViewModel(private val repository: StoryTextPostRepository) : View
|
|||
store.update { StoryPostState.None() }
|
||||
} else if (storyPostContent.isVideo()) {
|
||||
store.update {
|
||||
val shouldSkipTransform = storyPostContent.attachment.transformProperties.shouldSkipTransform()
|
||||
val shouldSkipTransform = storyPostContent.attachment.transformProperties?.shouldSkipTransform() == true
|
||||
|
||||
val clipStart: Duration = if (shouldSkipTransform) {
|
||||
0L.microseconds
|
||||
} else {
|
||||
storyPostContent.attachment.transformProperties.videoTrimStartTimeUs.microseconds
|
||||
storyPostContent.attachment.transformProperties?.videoTrimStartTimeUs?.microseconds ?: 0L.microseconds
|
||||
}
|
||||
|
||||
val clipEnd: Duration = if (shouldSkipTransform) {
|
||||
0L.microseconds
|
||||
} else {
|
||||
storyPostContent.attachment.transformProperties.videoTrimEndTimeUs.microseconds
|
||||
storyPostContent.attachment.transformProperties?.videoTrimEndTimeUs?.microseconds ?: 0L.microseconds
|
||||
}
|
||||
|
||||
StoryPostState.VideoPost(
|
||||
|
|
|
@ -37,15 +37,15 @@ public class AttachmentUtil {
|
|||
}
|
||||
|
||||
Set<String> allowedTypes = getAllowedAutoDownloadTypes(context);
|
||||
String contentType = attachment.getContentType();
|
||||
String contentType = attachment.contentType;
|
||||
|
||||
if (attachment.isVoiceNote() ||
|
||||
(MediaUtil.isAudio(attachment) && TextUtils.isEmpty(attachment.getFileName())) ||
|
||||
MediaUtil.isLongTextType(attachment.getContentType()) ||
|
||||
if (attachment.voiceNote ||
|
||||
(MediaUtil.isAudio(attachment) && TextUtils.isEmpty(attachment.fileName)) ||
|
||||
MediaUtil.isLongTextType(attachment.contentType) ||
|
||||
attachment.isSticker())
|
||||
{
|
||||
return true;
|
||||
} else if (attachment.isVideoGif()) {
|
||||
} else if (attachment.videoGif) {
|
||||
boolean allowed = NotInCallConstraint.isNotInConnectedCall() && allowedTypes.contains("image");
|
||||
if (!allowed) {
|
||||
Log.w(TAG, "Not auto downloading. inCall: " + NotInCallConstraint.isNotInConnectedCall() + " allowedType: " + allowedTypes.contains("image"));
|
||||
|
@ -74,8 +74,8 @@ public class AttachmentUtil {
|
|||
public static void deleteAttachment(@NonNull Context context,
|
||||
@NonNull DatabaseAttachment attachment)
|
||||
{
|
||||
AttachmentId attachmentId = attachment.getAttachmentId();
|
||||
long mmsId = attachment.getMmsId();
|
||||
AttachmentId attachmentId = attachment.attachmentId;
|
||||
long mmsId = attachment.mmsId;
|
||||
int attachmentCount = SignalDatabase.attachments()
|
||||
.getAttachmentsForMessage(mmsId)
|
||||
.size();
|
||||
|
@ -104,7 +104,7 @@ public class AttachmentUtil {
|
|||
@WorkerThread
|
||||
private static boolean isFromTrustedConversation(@NonNull Context context, @NonNull DatabaseAttachment attachment) {
|
||||
try {
|
||||
MessageRecord message = SignalDatabase.messages().getMessageRecord(attachment.getMmsId());
|
||||
MessageRecord message = SignalDatabase.messages().getMessageRecord(attachment.mmsId);
|
||||
|
||||
Recipient fromRecipient = message.getFromRecipient();
|
||||
Recipient toRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId());
|
||||
|
|
|
@ -100,7 +100,7 @@ public class MediaUtil {
|
|||
return new StickerSlide(attachment);
|
||||
}
|
||||
|
||||
switch (getSlideTypeFromContentType(attachment.getContentType())) {
|
||||
switch (getSlideTypeFromContentType(attachment.contentType)) {
|
||||
case GIF : return new GifSlide(attachment);
|
||||
case IMAGE : return new ImageSlide(attachment);
|
||||
case VIDEO : return new VideoSlide(attachment);
|
||||
|
@ -262,31 +262,31 @@ public class MediaUtil {
|
|||
}
|
||||
|
||||
public static boolean isGif(Attachment attachment) {
|
||||
return isGif(attachment.getContentType());
|
||||
return isGif(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isJpeg(Attachment attachment) {
|
||||
return isJpegType(attachment.getContentType());
|
||||
return isJpegType(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isHeic(Attachment attachment) {
|
||||
return isHeicType(attachment.getContentType());
|
||||
return isHeicType(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isHeif(Attachment attachment) {
|
||||
return isHeifType(attachment.getContentType());
|
||||
return isHeifType(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isImage(Attachment attachment) {
|
||||
return isImageType(attachment.getContentType());
|
||||
return isImageType(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isAudio(Attachment attachment) {
|
||||
return isAudioType(attachment.getContentType());
|
||||
return isAudioType(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isVideo(Attachment attachment) {
|
||||
return isVideoType(attachment.getContentType());
|
||||
return isVideoType(attachment.contentType);
|
||||
}
|
||||
|
||||
public static boolean isVideo(String contentType) {
|
||||
|
@ -473,7 +473,7 @@ public class MediaUtil {
|
|||
}
|
||||
final Attachment attachment = slide.asAttachment();
|
||||
final boolean isIncremental = attachment.getIncrementalDigest() != null;
|
||||
final boolean hasIncrementalMacChunkSizeDefined = attachment.getIncrementalMacChunkSize() > 0;
|
||||
final boolean hasIncrementalMacChunkSizeDefined = attachment.incrementalMacChunkSize > 0;
|
||||
final boolean contentTypeSupported = isVideoType(slide.getContentType());
|
||||
return isIncremental && contentTypeSupported && hasIncrementalMacChunkSizeDefined;
|
||||
}
|
||||
|
|
|
@ -58,13 +58,14 @@ class PartDataSource implements DataSource {
|
|||
|
||||
final boolean hasIncrementalDigest = attachment.getIncrementalDigest() != null;
|
||||
final boolean inProgress = attachment.isInProgress();
|
||||
final String attachmentKey = attachment.getKey();
|
||||
final boolean hasData = attachment.hasData();
|
||||
final String attachmentKey = attachment.key;
|
||||
final boolean hasData = attachment.hasData;
|
||||
|
||||
if (inProgress && !hasData && hasIncrementalDigest && attachmentKey != null && FeatureFlags.instantVideoPlayback()) {
|
||||
final byte[] decode = Base64.decode(attachmentKey);
|
||||
final File transferFile = attachmentDatabase.getOrCreateTransferFile(attachment.getAttachmentId());
|
||||
final File transferFile = attachmentDatabase.getOrCreateTransferFile(attachment.attachmentId);
|
||||
try {
|
||||
this.inputStream = AttachmentCipherInputStream.createForAttachment(transferFile, attachment.getSize(), decode, attachment.getDigest(), attachment.getIncrementalDigest(), attachment.getIncrementalMacChunkSize());
|
||||
this.inputStream = AttachmentCipherInputStream.createForAttachment(transferFile, attachment.size, decode, attachment.digest, attachment.getIncrementalDigest(), attachment.incrementalMacChunkSize);
|
||||
|
||||
long skipped = 0;
|
||||
while (skipped < dataSpec.position) {
|
||||
|
@ -81,8 +82,8 @@ class PartDataSource implements DataSource {
|
|||
|
||||
Log.d(TAG, "Successfully loaded completed attachment file.");
|
||||
} else {
|
||||
throw new IOException("Ineligible " + attachment.getAttachmentId().toString()
|
||||
+ "\nTransfer state: " + attachment.getTransferState()
|
||||
throw new IOException("Ineligible " + attachment.attachmentId.toString()
|
||||
+ "\nTransfer state: " + attachment.transferState
|
||||
+ "\nIncremental Digest Present: " + hasIncrementalDigest
|
||||
+ "\nAttachment Key Non-Empty: " + (attachmentKey != null && !attachmentKey.isEmpty()));
|
||||
}
|
||||
|
@ -91,9 +92,9 @@ class PartDataSource implements DataSource {
|
|||
listener.onTransferStart(this, dataSpec, false);
|
||||
}
|
||||
|
||||
if (attachment.getSize() - dataSpec.position <= 0) throw new EOFException("No more data");
|
||||
if (attachment.size - dataSpec.position <= 0) throw new EOFException("No more data");
|
||||
|
||||
return attachment.getSize() - dataSpec.position;
|
||||
return attachment.size - dataSpec.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,8 +21,8 @@ public class AttachmentDatabaseTransformPropertiesTest {
|
|||
|
||||
AttachmentTable.TransformProperties properties = AttachmentTable.TransformProperties.parse(json);
|
||||
|
||||
assertEquals(0, properties.getSentMediaQuality());
|
||||
assertEquals(SentMediaQuality.STANDARD, SentMediaQuality.fromCode(properties.getSentMediaQuality()));
|
||||
assertEquals(0, properties.sentMediaQuality);
|
||||
assertEquals(SentMediaQuality.STANDARD, SentMediaQuality.fromCode(properties.sentMediaQuality));
|
||||
}
|
||||
|
||||
}
|
|
@ -228,35 +228,35 @@ class UploadDependencyGraphTest {
|
|||
|
||||
private fun getAttachmentForPreUpload(id: Long, attachment: Attachment): DatabaseAttachment {
|
||||
return DatabaseAttachment(
|
||||
AttachmentId(id, id),
|
||||
AttachmentTable.PREUPLOAD_MESSAGE_ID,
|
||||
false,
|
||||
false,
|
||||
attachment.contentType,
|
||||
AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
attachment.size,
|
||||
attachment.fileName,
|
||||
attachment.cdnNumber,
|
||||
attachment.location,
|
||||
attachment.key,
|
||||
attachment.relay,
|
||||
attachment.digest,
|
||||
attachment.incrementalDigest,
|
||||
attachment.incrementalMacChunkSize,
|
||||
attachment.fastPreflightId,
|
||||
attachment.isVoiceNote,
|
||||
attachment.isBorderless,
|
||||
attachment.isVideoGif,
|
||||
attachment.width,
|
||||
attachment.height,
|
||||
attachment.isQuote,
|
||||
attachment.caption,
|
||||
attachment.sticker,
|
||||
attachment.blurHash,
|
||||
attachment.audioHash,
|
||||
attachment.transformProperties,
|
||||
0,
|
||||
attachment.uploadTimestamp
|
||||
attachmentId = AttachmentId(id, id),
|
||||
mmsId = AttachmentTable.PREUPLOAD_MESSAGE_ID,
|
||||
hasData = false,
|
||||
hasThumbnail = false,
|
||||
contentType = attachment.contentType,
|
||||
transferProgress = AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
size = attachment.size,
|
||||
fileName = attachment.fileName,
|
||||
cdnNumber = attachment.cdnNumber,
|
||||
location = attachment.location,
|
||||
key = attachment.key,
|
||||
relay = attachment.relay,
|
||||
digest = attachment.digest,
|
||||
incrementalDigest = attachment.incrementalDigest,
|
||||
incrementalMacChunkSize = attachment.incrementalMacChunkSize,
|
||||
fastPreflightId = attachment.fastPreflightId,
|
||||
voiceNote = attachment.voiceNote,
|
||||
borderless = attachment.borderless,
|
||||
videoGif = attachment.videoGif,
|
||||
width = attachment.width,
|
||||
height = attachment.height,
|
||||
quote = attachment.quote,
|
||||
caption = attachment.caption,
|
||||
stickerLocator = attachment.stickerLocator,
|
||||
blurHash = attachment.blurHash,
|
||||
audioHash = attachment.audioHash,
|
||||
transformProperties = attachment.transformProperties,
|
||||
displayOrder = 0,
|
||||
uploadTimestamp = attachment.uploadTimestamp
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,23 @@ inline fun <K, V> Cursor.readToMap(predicate: (Pair<K, V>) -> Boolean = { true }
|
|||
return readToList(predicate, mapper).associate { it }
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the cursor by the given key, and returns a map of keys to lists of values.
|
||||
*/
|
||||
inline fun <K, V> Cursor.groupBy(mapper: (Cursor) -> Pair<K, V>): Map<K, List<V>> {
|
||||
val map: MutableMap<K, MutableList<V>> = mutableMapOf()
|
||||
|
||||
use {
|
||||
while (moveToNext()) {
|
||||
val pair = mapper(this)
|
||||
val list = map.getOrPut(pair.first) { mutableListOf() }
|
||||
list += pair.second
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
inline fun <T> Cursor.readToSet(predicate: (T) -> Boolean = { true }, mapper: (Cursor) -> T): Set<T> {
|
||||
val set = mutableSetOf<T>()
|
||||
use {
|
||||
|
|
Loading…
Add table
Reference in a new issue