diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt index 746e429dcb..af351f00ab 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt @@ -61,8 +61,8 @@ class AttachmentTableTest { false ) - val attachment1Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment.attachmentId, AttachmentTable.DATA) - val attachment2Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment2.attachmentId, AttachmentTable.DATA) + val attachment1Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment.attachmentId, AttachmentTable.DATA_FILE) + val attachment2Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment2.attachmentId, AttachmentTable.DATA_FILE) assertNotEquals(attachment1Info, attachment2Info) } @@ -89,8 +89,8 @@ class AttachmentTableTest { true ) - val attachment1Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment.attachmentId, AttachmentTable.DATA) - val attachment2Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment2.attachmentId, AttachmentTable.DATA) + val attachment1Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment.attachmentId, AttachmentTable.DATA_FILE) + val attachment2Info = SignalDatabase.attachments.getAttachmentDataFileInfo(attachment2.attachmentId, AttachmentTable.DATA_FILE) assertNotEquals(attachment1Info, attachment2Info) } @@ -124,9 +124,9 @@ class AttachmentTableTest { SignalDatabase.attachments.updateAttachmentData(standardDatabaseAttachment, createMediaStream(compressedData), false) // THEN - val previousInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(previousDatabaseAttachmentId, AttachmentTable.DATA)!! - val standardInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(standardDatabaseAttachment.attachmentId, AttachmentTable.DATA)!! - val highInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(highDatabaseAttachment.attachmentId, AttachmentTable.DATA)!! + val previousInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(previousDatabaseAttachmentId, AttachmentTable.DATA_FILE)!! + val standardInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(standardDatabaseAttachment.attachmentId, AttachmentTable.DATA_FILE)!! + val highInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(highDatabaseAttachment.attachmentId, AttachmentTable.DATA_FILE)!! assertNotEquals(standardInfo, highInfo) standardInfo.file assertIs previousInfo.file @@ -158,9 +158,9 @@ class AttachmentTableTest { val secondHighDatabaseAttachment = SignalDatabase.attachments.insertAttachmentForPreUpload(secondHighQualityPreUpload) // THEN - val standardInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(standardDatabaseAttachment.attachmentId, AttachmentTable.DATA)!! - val highInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(highDatabaseAttachment.attachmentId, AttachmentTable.DATA)!! - val secondHighInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(secondHighDatabaseAttachment.attachmentId, AttachmentTable.DATA)!! + val standardInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(standardDatabaseAttachment.attachmentId, AttachmentTable.DATA_FILE)!! + val highInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(highDatabaseAttachment.attachmentId, AttachmentTable.DATA_FILE)!! + val secondHighInfo = SignalDatabase.attachments.getAttachmentDataFileInfo(secondHighDatabaseAttachment.attachmentId, AttachmentTable.DATA_FILE)!! highInfo.file assertIsNot standardInfo.file secondHighInfo.file assertIs highInfo.file diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/EditMessageSyncProcessorTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/EditMessageSyncProcessorTest.kt index 82bb5ccc70..6875886c7c 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/EditMessageSyncProcessorTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/EditMessageSyncProcessorTest.kt @@ -39,7 +39,6 @@ class EditMessageSyncProcessorTest { ) private val IGNORE_ATTACHMENT_COLUMNS = listOf( - AttachmentTable.UNIQUE_ID, AttachmentTable.TRANSFER_FILE ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt index 7271ae9b28..0330e91e6c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt @@ -31,13 +31,11 @@ abstract class Attachment( @JvmField val cdnNumber: Int, @JvmField - val location: String?, + val remoteLocation: String?, @JvmField - val key: String?, + val remoteKey: String?, @JvmField - val relay: String?, - @JvmField - val digest: ByteArray?, + val remoteDigest: ByteArray?, @JvmField val incrementalDigest: ByteArray?, @JvmField @@ -79,10 +77,9 @@ abstract class Attachment( size = parcel.readLong(), fileName = parcel.readString(), cdnNumber = parcel.readInt(), - location = parcel.readString(), - key = parcel.readString(), - relay = parcel.readString(), - digest = ParcelUtil.readByteArray(parcel), + remoteLocation = parcel.readString(), + remoteKey = parcel.readString(), + remoteDigest = ParcelUtil.readByteArray(parcel), incrementalDigest = ParcelUtil.readByteArray(parcel), fastPreflightId = parcel.readString(), voiceNote = ParcelUtil.readBoolean(parcel), @@ -107,10 +104,9 @@ abstract class Attachment( dest.writeLong(size) dest.writeString(fileName) dest.writeInt(cdnNumber) - dest.writeString(location) - dest.writeString(key) - dest.writeString(relay) - ParcelUtil.writeByteArray(dest, digest) + dest.writeString(remoteLocation) + dest.writeString(remoteKey) + ParcelUtil.writeByteArray(dest, remoteDigest) ParcelUtil.writeByteArray(dest, incrementalDigest) dest.writeString(fastPreflightId) ParcelUtil.writeBoolean(dest, voiceNote) diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentId.java b/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentId.java deleted file mode 100644 index d8d5e1057e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentId.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.thoughtcrime.securesms.attachments; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.thoughtcrime.securesms.util.Util; - -public class AttachmentId implements Parcelable { - - @JsonProperty - private final long rowId; - - @JsonProperty - private final long uniqueId; - - public AttachmentId(@JsonProperty("rowId") long rowId, @JsonProperty("uniqueId") long uniqueId) { - this.rowId = rowId; - this.uniqueId = uniqueId; - } - - private AttachmentId(Parcel in) { - this.rowId = in.readLong(); - this.uniqueId = in.readLong(); - } - - public long getRowId() { - return rowId; - } - - public long getUniqueId() { - return uniqueId; - } - - public String[] toStrings() { - return new String[] {String.valueOf(rowId), String.valueOf(uniqueId)}; - } - - public @NonNull String toString() { - return "AttachmentId::(" + rowId + ", " + uniqueId + ")"; - } - - public boolean isValid() { - return rowId >= 0 && uniqueId >= 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AttachmentId attachmentId = (AttachmentId)o; - - if (rowId != attachmentId.rowId) return false; - return uniqueId == attachmentId.uniqueId; - } - - @Override - public int hashCode() { - return Util.hashCode(rowId, uniqueId); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(rowId); - dest.writeLong(uniqueId); - } - - public static final Creator CREATOR = new Creator() { - @Override - public AttachmentId createFromParcel(Parcel in) { - return new AttachmentId(in); - } - - @Override - public AttachmentId[] newArray(int size) { - return new AttachmentId[size]; - } - }; - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentId.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentId.kt new file mode 100644 index 0000000000..981ba5d880 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentId.kt @@ -0,0 +1,20 @@ +package org.thoughtcrime.securesms.attachments + +import android.os.Parcelable +import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.parcelize.Parcelize + +@Parcelize +data class AttachmentId( + @JsonProperty("rowId") + @JvmField + val id: Long +) : Parcelable { + + val isValid: Boolean + get() = id >= 0 + + override fun toString(): String { + return "AttachmentId::$id" + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt index 073a051262..fa1570a529 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt @@ -37,7 +37,6 @@ class DatabaseAttachment : Attachment { cdnNumber: Int, location: String?, key: String?, - relay: String?, digest: ByteArray?, incrementalDigest: ByteArray?, incrementalMacChunkSize: Int, @@ -61,10 +60,9 @@ class DatabaseAttachment : Attachment { size = size, fileName = fileName, cdnNumber = cdnNumber, - location = location, - key = key, - relay = relay, - digest = digest, + remoteLocation = location, + remoteKey = key, + remoteDigest = digest, incrementalDigest = incrementalDigest, fastPreflightId = fastPreflightId, voiceNote = voiceNote, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt index 003ca5ecdd..92d533c84f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt @@ -22,7 +22,6 @@ class PointerAttachment : Attachment { cdnNumber: Int, location: String, key: String?, - relay: String?, digest: ByteArray?, incrementalDigest: ByteArray?, incrementalMacChunkSize: Int, @@ -42,10 +41,9 @@ class PointerAttachment : Attachment { size = size, fileName = fileName, cdnNumber = cdnNumber, - location = location, - key = key, - relay = relay, - digest = digest, + remoteLocation = location, + remoteKey = key, + remoteDigest = digest, incrementalDigest = incrementalDigest, fastPreflightId = fastPreflightId, voiceNote = voiceNote, @@ -103,7 +101,6 @@ class PointerAttachment : Attachment { 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, @@ -133,7 +130,6 @@ class PointerAttachment : Attachment { 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, @@ -171,7 +167,6 @@ class PointerAttachment : Attachment { 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, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt index 857c96f03d..ef7a371ff0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt @@ -18,10 +18,9 @@ class TombstoneAttachment : Attachment { size = 0, fileName = null, cdnNumber = 0, - location = null, - key = null, - relay = null, - digest = null, + remoteLocation = null, + remoteKey = null, + remoteDigest = null, incrementalDigest = null, fastPreflightId = null, voiceNote = false, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt index 800707b053..f158bd367a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt @@ -70,10 +70,9 @@ class UriAttachment : Attachment { size = size, fileName = fileName, cdnNumber = 0, - location = null, - key = null, - relay = null, - digest = null, + remoteLocation = null, + remoteKey = null, + remoteDigest = null, incrementalDigest = null, fastPreflightId = fastPreflightId, voiceNote = voiceNote, diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupCountQueries.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupCountQueries.kt index 8bbba04bab..4ae57007e3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupCountQueries.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupCountQueries.kt @@ -21,7 +21,7 @@ object BackupCountQueries { @get:JvmStatic val attachmentCount: String = """ SELECT COUNT(*) FROM ${AttachmentTable.TABLE_NAME} - INNER JOIN ${MessageTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID} + INNER JOIN ${MessageTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID} WHERE ${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} <= 0 AND ${MessageTable.TABLE_NAME}.${MessageTable.VIEW_ONCE} <= 0 """ } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupFrameOutputStream.java b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupFrameOutputStream.java index 0da664e6e7..0e943104f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupFrameOutputStream.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupFrameOutputStream.java @@ -119,8 +119,7 @@ class BackupFrameOutputStream extends FullBackupBase.BackupStream { try { write(outputStream, new BackupFrame.Builder() .attachment(new Attachment.Builder() - .rowId(attachmentId.getRowId()) - .attachmentId(attachmentId.getUniqueId()) + .rowId(attachmentId.id) .length(Util.toIntExact(size)) .build()) .build()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java index e4a7df5da9..3132b28b5f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java @@ -167,7 +167,7 @@ public class FullBackupExporter extends FullBackupBase { } else if (table.equals(GroupReceiptTable.TABLE_NAME)) { count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMmsMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(GroupReceiptTable.MMS_ID))), null, count, estimatedCount, cancellationSignal); } else if (table.equals(AttachmentTable.TABLE_NAME)) { - count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMmsMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.MMS_ID))), (cursor, innerCount) -> exportAttachment(attachmentSecret, cursor, outputStream, innerCount, estimatedCount), count, estimatedCount, cancellationSignal); + count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMmsMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.MESSAGE_ID))), (cursor, innerCount) -> exportAttachment(attachmentSecret, cursor, outputStream, innerCount, estimatedCount), count, estimatedCount, cancellationSignal); } else if (table.equals(StickerTable.TABLE_NAME)) { count = exportTable(table, input, outputStream, cursor -> true, (cursor, innerCount) -> exportSticker(attachmentSecret, cursor, outputStream, innerCount, estimatedCount), count, estimatedCount, cancellationSignal); } else if (!TABLE_CONTENT_BLOCKLIST.contains(table)) { @@ -444,11 +444,10 @@ public class FullBackupExporter extends FullBackupBase { long estimatedCount) throws IOException { - long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.ROW_ID)); - long uniqueId = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.UNIQUE_ID)); - long size = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.SIZE)); + long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.ID)); + long size = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.DATA_SIZE)); - String data = cursor.getString(cursor.getColumnIndexOrThrow(AttachmentTable.DATA)); + String data = cursor.getString(cursor.getColumnIndexOrThrow(AttachmentTable.DATA_FILE)); byte[] random = cursor.getBlob(cursor.getColumnIndexOrThrow(AttachmentTable.DATA_RANDOM)); if (!TextUtils.isEmpty(data)) { @@ -457,14 +456,14 @@ public class FullBackupExporter extends FullBackupBase { if (size <= 0 || fileLength != dbLength) { size = calculateVeryOldStreamLength(attachmentSecret, random, data); - Log.w(TAG, "Needed size calculation! Manual: " + size + " File: " + fileLength + " DB: " + dbLength + " ID: " + new AttachmentId(rowId, uniqueId)); + Log.w(TAG, "Needed size calculation! Manual: " + size + " File: " + fileLength + " DB: " + dbLength + " ID: " + new AttachmentId(rowId)); } } EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count, estimatedCount)); if (!TextUtils.isEmpty(data) && size > 0) { try (InputStream inputStream = openAttachmentStream(attachmentSecret, random, data)) { - outputStream.write(new AttachmentId(rowId, uniqueId), inputStream, size); + outputStream.write(new AttachmentId(rowId), inputStream, size); } catch (FileNotFoundException e) { Log.w(TAG, "Missing attachment", e); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java index 408eb7dc72..ca59cce9b6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java @@ -202,18 +202,18 @@ public class FullBackupImporter extends FullBackupBase { try { inputStream.readAttachmentTo(output.second, attachment.length); - contentValues.put(AttachmentTable.DATA, dataFile.getAbsolutePath()); + contentValues.put(AttachmentTable.DATA_FILE, dataFile.getAbsolutePath()); contentValues.put(AttachmentTable.DATA_RANDOM, output.first); } catch (BackupRecordInputStream.BadMacException e) { Log.w(TAG, "Bad MAC for attachment " + attachment.attachmentId + "! Can't restore it.", e); dataFile.delete(); - contentValues.put(AttachmentTable.DATA, (String) null); + contentValues.put(AttachmentTable.DATA_FILE, (String) null); contentValues.put(AttachmentTable.DATA_RANDOM, (String) null); } db.update(AttachmentTable.TABLE_NAME, contentValues, - AttachmentTable.ROW_ID + " = ? AND " + AttachmentTable.UNIQUE_ID + " = ?", - new String[] {String.valueOf(attachment.rowId), String.valueOf(attachment.attachmentId)}); + AttachmentTable.ID + " = ?", + new String[] {String.valueOf(attachment.rowId)}); } private static void processSticker(@NonNull Context context, @NonNull AttachmentSecret attachmentSecret, @NonNull SQLiteDatabase db, @NonNull Sticker sticker, BackupRecordInputStream inputStream) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java index a464453108..42da090d0e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java @@ -532,8 +532,8 @@ public class ThumbnailView extends FrameLayout { if (Util.equals(slide, other)) { if (slide != null && other != null) { - byte[] digestLeft = slide.asAttachment().digest; - byte[] digestRight = other.asAttachment().digest; + byte[] digestLeft = slide.asAttachment().remoteDigest; + byte[] digestRight = other.asAttachment().remoteDigest; return Arrays.equals(digestLeft, digestRight); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt index 19319fe476..3cc3927e85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt @@ -76,7 +76,7 @@ sealed class ConversationSettingsViewModel( if (!cleared) { state.copy( sharedMedia = mediaRecords, - sharedMediaIds = mediaRecords.mapNotNull { it.attachment?.attachmentId?.rowId }, + sharedMediaIds = mediaRecords.mapNotNull { it.attachment?.attachmentId?.id }, sharedMediaLoaded = true, displayInternalRecipientDetails = repository.isInternalRecipientDetailsEnabled() ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt index fd0bd5c597..7c3d241a0e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt @@ -102,42 +102,41 @@ class AttachmentTable( companion object { val TAG = Log.tag(AttachmentTable::class.java) - const val TABLE_NAME = "part" - const val ROW_ID = "_id" - const val ATTACHMENT_JSON_ALIAS = "attachment_json" - const val MMS_ID = "mid" - const val CONTENT_TYPE = "ct" - const val NAME = "name" - const val CONTENT_DISPOSITION = "cd" - const val CONTENT_LOCATION = "cl" - const val DATA = "_data" - const val TRANSFER_STATE = "pending_push" + const val TABLE_NAME = "attachment" + const val ID = "_id" + const val MESSAGE_ID = "message_id" + const val CONTENT_TYPE = "content_type" + const val REMOTE_KEY = "remote_key" + const val REMOTE_LOCATION = "remote_location" + const val REMOTE_DIGEST = "remote_digest" + const val REMOTE_INCREMENTAL_DIGEST = "remote_incremental_digest" + const val REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE = "remote_incremental_digest_chunk_size" + const val CDN_NUMBER = "cdn_number" + const val TRANSFER_STATE = "transfer_state" const val TRANSFER_FILE = "transfer_file" - const val SIZE = "data_size" + const val DATA_FILE = "data_file" + const val DATA_SIZE = "data_size" + const val DATA_RANDOM = "data_random" + const val DATA_HASH = "data_hash" const val FILE_NAME = "file_name" - const val UNIQUE_ID = "unique_id" - const val DIGEST = "digest" + const val FAST_PREFLIGHT_ID = "fast_preflight_id" const val VOICE_NOTE = "voice_note" const val BORDERLESS = "borderless" const val VIDEO_GIF = "video_gif" const val QUOTE = "quote" + const val WIDTH = "width" + const val HEIGHT = "height" + const val CAPTION = "caption" const val STICKER_PACK_ID = "sticker_pack_id" const val STICKER_PACK_KEY = "sticker_pack_key" const val STICKER_ID = "sticker_id" const val STICKER_EMOJI = "sticker_emoji" - const val FAST_PREFLIGHT_ID = "fast_preflight_id" - const val DATA_RANDOM = "data_random" - const val WIDTH = "width" - const val HEIGHT = "height" - const val CAPTION = "caption" - const val DATA_HASH = "data_hash" - const val VISUAL_HASH = "blur_hash" + const val BLUR_HASH = "blur_hash" const val TRANSFORM_PROPERTIES = "transform_properties" const val DISPLAY_ORDER = "display_order" const val UPLOAD_TIMESTAMP = "upload_timestamp" - const val CDN_NUMBER = "cdn_number" - const val MAC_DIGEST = "incremental_mac_digest" - const val INCREMENTAL_MAC_CHUNK_SIZE = "incremental_mac_chunk_size" + + const val ATTACHMENT_JSON_ALIAS = "attachment_json" private const val DIRECTORY = "parts" @@ -148,31 +147,28 @@ class AttachmentTable( const val TRANSFER_PROGRESS_PERMANENT_FAILURE = 4 const val PREUPLOAD_MESSAGE_ID: Long = -8675309 - private const val PART_ID_WHERE = "$ROW_ID = ? AND $UNIQUE_ID = ?" - private const val PART_ID_WHERE_NOT = "$ROW_ID != ? AND $UNIQUE_ID != ?" - private val PROJECTION = arrayOf( - ROW_ID, - MMS_ID, + ID, + MESSAGE_ID, CONTENT_TYPE, - NAME, - CONTENT_DISPOSITION, + REMOTE_KEY, + REMOTE_LOCATION, + REMOTE_DIGEST, + REMOTE_INCREMENTAL_DIGEST, + REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE, CDN_NUMBER, - CONTENT_LOCATION, - DATA, TRANSFER_STATE, - SIZE, + TRANSFER_FILE, + DATA_FILE, + DATA_SIZE, + DATA_RANDOM, + DATA_HASH, FILE_NAME, - UNIQUE_ID, - DIGEST, - MAC_DIGEST, - INCREMENTAL_MAC_CHUNK_SIZE, FAST_PREFLIGHT_ID, VOICE_NOTE, BORDERLESS, VIDEO_GIF, QUOTE, - DATA_RANDOM, WIDTH, HEIGHT, CAPTION, @@ -180,40 +176,34 @@ class AttachmentTable( STICKER_PACK_KEY, STICKER_ID, STICKER_EMOJI, - DATA_HASH, - VISUAL_HASH, + BLUR_HASH, TRANSFORM_PROPERTIES, - TRANSFER_FILE, DISPLAY_ORDER, UPLOAD_TIMESTAMP ) const val CREATE_TABLE = """ CREATE TABLE $TABLE_NAME ( - $ROW_ID INTEGER PRIMARY KEY, - $MMS_ID INTEGER, - seq INTEGER DEFAULT 0, + $ID INTEGER PRIMARY KEY AUTOINCREMENT, + $MESSAGE_ID INTEGER, $CONTENT_TYPE TEXT, - $NAME TEXT, - chset INTEGER, - $CONTENT_DISPOSITION TEXT, - fn TEXT, - cid TEXT, - $CONTENT_LOCATION TEXT, - ctt_s INTEGER, - ctt_t TEXT, - encrypted INTEGER, + $REMOTE_KEY TEXT, + $REMOTE_LOCATION TEXT, + $REMOTE_DIGEST BLOB, + $REMOTE_INCREMENTAL_DIGEST BLOB, + $REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE INTEGER DEFAULT 0, + $CDN_NUMBER INTEGER DEFAULT 0, $TRANSFER_STATE INTEGER, - $DATA TEXT, - $SIZE INTEGER, + $TRANSFER_FILE TEXT DEFAULT NULL, + $DATA_FILE TEXT, + $DATA_SIZE INTEGER, + $DATA_RANDOM BLOB, + $DATA_HASH TEXT DEFAULT NULL, $FILE_NAME TEXT, - $UNIQUE_ID INTEGER NOT NULL, - $DIGEST BLOB, $FAST_PREFLIGHT_ID TEXT, $VOICE_NOTE INTEGER DEFAULT 0, $BORDERLESS INTEGER DEFAULT 0, $VIDEO_GIF INTEGER DEFAULT 0, - $DATA_RANDOM BLOB, $QUOTE INTEGER DEFAULT 0, $WIDTH INTEGER DEFAULT 0, $HEIGHT INTEGER DEFAULT 0, @@ -222,25 +212,20 @@ class AttachmentTable( $STICKER_PACK_KEY DEFAULT NULL, $STICKER_ID INTEGER DEFAULT -1, $STICKER_EMOJI STRING DEFAULT NULL, - $DATA_HASH TEXT DEFAULT NULL, - $VISUAL_HASH TEXT DEFAULT NULL, + $BLUR_HASH TEXT DEFAULT NULL, $TRANSFORM_PROPERTIES TEXT DEFAULT NULL, - $TRANSFER_FILE TEXT DEFAULT NULL, $DISPLAY_ORDER INTEGER DEFAULT 0, - $UPLOAD_TIMESTAMP INTEGER DEFAULT 0, - $CDN_NUMBER INTEGER DEFAULT 0, - $MAC_DIGEST BLOB, - $INCREMENTAL_MAC_CHUNK_SIZE INTEGER DEFAULT 0 + $UPLOAD_TIMESTAMP INTEGER DEFAULT 0 ) """ @JvmField val CREATE_INDEXS = arrayOf( - "CREATE INDEX IF NOT EXISTS part_mms_id_index ON $TABLE_NAME ($MMS_ID);", - "CREATE INDEX IF NOT EXISTS pending_push_index ON $TABLE_NAME ($TRANSFER_STATE);", - "CREATE INDEX IF NOT EXISTS part_sticker_pack_id_index ON $TABLE_NAME ($STICKER_PACK_ID);", - "CREATE INDEX IF NOT EXISTS part_data_hash_index ON $TABLE_NAME ($DATA_HASH);", - "CREATE INDEX IF NOT EXISTS part_data_index ON $TABLE_NAME ($DATA);" + "CREATE INDEX IF NOT EXISTS attachment_message_id_index ON $TABLE_NAME ($MESSAGE_ID);", + "CREATE INDEX IF NOT EXISTS attachment_transfer_state_index ON $TABLE_NAME ($TRANSFER_STATE);", + "CREATE INDEX IF NOT EXISTS attachment_sticker_pack_id_index ON $TABLE_NAME ($STICKER_PACK_ID);", + "CREATE INDEX IF NOT EXISTS attachment_data_hash_index ON $TABLE_NAME ($DATA_HASH);", + "CREATE INDEX IF NOT EXISTS attachment_data_index ON $TABLE_NAME ($DATA_FILE);" ) @JvmStatic @@ -255,7 +240,7 @@ class AttachmentTable( @Throws(IOException::class) fun getAttachmentStream(attachmentId: AttachmentId, offset: Long): InputStream { return try { - getDataStream(attachmentId, DATA, offset) + getDataStream(attachmentId, DATA_FILE, offset) } catch (e: FileNotFoundException) { throw IOException("No stream for: $attachmentId", e) } ?: throw IOException("No stream for: $attachmentId") @@ -265,7 +250,7 @@ class AttachmentTable( return readableDatabase .select(*PROJECTION) .from(TABLE_NAME) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() .readToList { it.readAttachments() } .flatten() @@ -276,8 +261,8 @@ class AttachmentTable( return readableDatabase .select(*PROJECTION) .from(TABLE_NAME) - .where("$MMS_ID = ?", mmsId) - .orderBy("$UNIQUE_ID ASC, $ROW_ID ASC") + .where("$MESSAGE_ID = ?", mmsId) + .orderBy("$ID ASC") .run() .readToList { it.readAttachments() } .flatten() @@ -288,13 +273,13 @@ class AttachmentTable( return emptyMap() } - val query = buildSingleCollectionQuery(MMS_ID, mmsIds) + val query = buildSingleCollectionQuery(MESSAGE_ID, mmsIds) return readableDatabase .select(*PROJECTION) .from(TABLE_NAME) .where(query.where, query.whereArgs) - .orderBy("$UNIQUE_ID ASC, $ROW_ID ASC") + .orderBy("$ID ASC") .run() .groupBy { cursor -> val attachment = cursor.readAttachment() @@ -305,7 +290,7 @@ class AttachmentTable( fun hasAttachment(id: AttachmentId): Boolean { return readableDatabase .exists(TABLE_NAME) - .where(PART_ID_WHERE, id.toStrings()) + .where("$ID = ?", id.id) .run() } @@ -323,27 +308,24 @@ class AttachmentTable( Log.d(TAG, "[deleteAttachmentsForMessage] mmsId: $mmsId") return writableDatabase.withinTransaction { db -> - db.select(DATA, CONTENT_TYPE, ROW_ID, UNIQUE_ID) + db.select(DATA_FILE, CONTENT_TYPE, ID) .from(TABLE_NAME) - .where("$MMS_ID = ?", mmsId) + .where("$MESSAGE_ID = ?", mmsId) .run() .forEach { cursor -> - val attachmentId = AttachmentId( - cursor.requireLong(ROW_ID), - cursor.requireLong(UNIQUE_ID) - ) + val attachmentId = AttachmentId(cursor.requireLong(ID)) ApplicationDependencies.getJobManager().cancelAllInQueue(AttachmentDownloadJob.constructQueueString(attachmentId)) deleteAttachmentOnDisk( - data = cursor.requireString(DATA), + data = cursor.requireString(DATA_FILE), contentType = cursor.requireString(CONTENT_TYPE), attachmentId = attachmentId ) } val deleteCount = db.delete(TABLE_NAME) - .where("$MMS_ID = ?", mmsId) + .where("$MESSAGE_ID = ?", mmsId) .run() notifyAttachmentListeners() @@ -363,18 +345,13 @@ class AttachmentTable( var count = 0 writableDatabase - .select(ROW_ID, UNIQUE_ID) + .select(ID) .from(TABLE_NAME) - .where("$MMS_ID = ?", PREUPLOAD_MESSAGE_ID) + .where("$MESSAGE_ID = ?", PREUPLOAD_MESSAGE_ID) .run() .forEach { cursor -> - val id = AttachmentId( - cursor.requireLong(ROW_ID), - cursor.requireLong(UNIQUE_ID) - ) - + val id = AttachmentId(cursor.requireLong(ID)) deleteAttachment(id) - count++ } @@ -385,30 +362,30 @@ class AttachmentTable( Log.d(TAG, "[deleteAttachmentFilesForViewOnceMessage] mmsId: $mmsId") writableDatabase.withinTransaction { db -> - db.select(DATA, CONTENT_TYPE, ROW_ID, UNIQUE_ID) + db.select(DATA_FILE, CONTENT_TYPE, ID) .from(TABLE_NAME) - .where("$MMS_ID = ?", mmsId) + .where("$MESSAGE_ID = ?", mmsId) .run() .forEach { cursor -> deleteAttachmentOnDisk( - data = cursor.requireString(DATA), + data = cursor.requireString(DATA_FILE), contentType = cursor.requireString(CONTENT_TYPE), - attachmentId = AttachmentId(cursor.requireLong(ROW_ID), cursor.requireLong(UNIQUE_ID)) + attachmentId = AttachmentId(cursor.requireLong(ID)) ) } db.update(TABLE_NAME) .values( - DATA to null, + DATA_FILE to null, DATA_RANDOM to null, DATA_HASH to null, FILE_NAME to null, CAPTION to null, - SIZE to 0, + DATA_SIZE to 0, WIDTH to 0, HEIGHT to 0, TRANSFER_STATE to TRANSFER_PROGRESS_DONE, - VISUAL_HASH to null, + BLUR_HASH to null, CONTENT_TYPE to MediaUtil.VIEW_ONCE ) .run() @@ -426,9 +403,9 @@ class AttachmentTable( Log.d(TAG, "[deleteAttachment] attachmentId: $id") writableDatabase.withinTransaction { db -> - db.select(DATA, CONTENT_TYPE) + db.select(DATA_FILE, CONTENT_TYPE) .from(TABLE_NAME) - .where(PART_ID_WHERE, id.toStrings()) + .where("$ID = ?", id.id) .run() .use { cursor -> if (!cursor.moveToFirst()) { @@ -436,7 +413,7 @@ class AttachmentTable( return@withinTransaction } - val data = cursor.requireString(DATA) + val data = cursor.requireString(DATA_FILE) val contentType = cursor.requireString(CONTENT_TYPE) deleteAttachmentOnDisk( @@ -446,7 +423,7 @@ class AttachmentTable( ) db.delete(TABLE_NAME) - .where(PART_ID_WHERE, id.toStrings()) + .where("$ID = ?", id.id) .run() deleteAttachmentOnDisk(data, contentType, id) @@ -458,7 +435,7 @@ class AttachmentTable( fun trimAllAbandonedAttachments() { val deleteCount = writableDatabase .delete(TABLE_NAME) - .where("$MMS_ID != $PREUPLOAD_MESSAGE_ID AND $MMS_ID NOT IN (SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME})") + .where("$MESSAGE_ID != $PREUPLOAD_MESSAGE_ID AND $MESSAGE_ID NOT IN (SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME})") .run() if (deleteCount > 0) { @@ -475,10 +452,10 @@ class AttachmentTable( .toSet() val filesInDb: Set = readableDatabase - .select(DATA) + .select(DATA_FILE) .from(TABLE_NAME) .run() - .readToList { it.requireString(DATA) } + .readToList { it.requireString(DATA_FILE) } .filterNotNull() .toSet() + stickers.allStickerFiles @@ -510,7 +487,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(TRANSFER_STATE to transferState) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() val threadId = messages.getThreadIdForMessage(messageId) @@ -522,7 +499,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(TRANSFER_STATE to TRANSFER_PROGRESS_FAILED) - .where("$PART_ID_WHERE AND $TRANSFER_STATE < $TRANSFER_PROGRESS_PERMANENT_FAILURE", attachmentId.toStrings()) + .where("$ID = ? AND $TRANSFER_STATE < $TRANSFER_PROGRESS_PERMANENT_FAILURE", attachmentId.id) .run() notifyConversationListeners(messages.getThreadIdForMessage(mmsId)) @@ -533,7 +510,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(TRANSFER_STATE to TRANSFER_PROGRESS_PERMANENT_FAILURE) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() notifyConversationListeners(messages.getThreadIdForMessage(mmsId)) @@ -542,7 +519,7 @@ class AttachmentTable( @Throws(MmsException::class) fun insertAttachmentsForPlaceholder(mmsId: Long, attachmentId: AttachmentId, inputStream: InputStream) { val placeholder = getAttachment(attachmentId) - val oldInfo = getAttachmentDataFileInfo(attachmentId, DATA) + val oldInfo = getAttachmentDataFileInfo(attachmentId, DATA_FILE) var dataInfo = storeAttachmentStream(inputStream) val transferFile = getTransferFile(databaseHelper.signalReadableDatabase, attachmentId) @@ -554,14 +531,14 @@ class AttachmentTable( } val values = ContentValues() - values.put(DATA, dataInfo.file.absolutePath) - values.put(SIZE, dataInfo.length) + values.put(DATA_FILE, dataInfo.file.absolutePath) + values.put(DATA_SIZE, dataInfo.length) values.put(DATA_RANDOM, dataInfo.random) values.put(DATA_HASH, dataInfo.hash) val visualHashString = placeholder.getVisualHashStringOrNull() if (visualHashString != null) { - values.put(VISUAL_HASH, visualHashString) + values.put(BLUR_HASH, visualHashString) } values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE) @@ -570,7 +547,7 @@ class AttachmentTable( val updateCount = db.update(TABLE_NAME) .values(values) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() updateCount > 0 @@ -606,32 +583,31 @@ class AttachmentTable( @Throws(MmsException::class) fun copyAttachmentData(sourceId: AttachmentId, destinationId: AttachmentId) { val sourceAttachment = getAttachment(sourceId) ?: throw MmsException("Cannot find attachment for source!") - val sourceDataInfo = getAttachmentDataFileInfo(sourceId, DATA) ?: throw MmsException("No attachment data found for source!") + val sourceDataInfo = getAttachmentDataFileInfo(sourceId, DATA_FILE) ?: throw MmsException("No attachment data found for source!") writableDatabase .update(TABLE_NAME) .values( - DATA to sourceDataInfo.file.absolutePath, + DATA_FILE to sourceDataInfo.file.absolutePath, DATA_HASH to sourceDataInfo.hash, - SIZE to sourceDataInfo.length, + DATA_SIZE to sourceDataInfo.length, DATA_RANDOM to sourceDataInfo.random, TRANSFER_STATE to sourceAttachment.transferState, CDN_NUMBER to sourceAttachment.cdnNumber, - CONTENT_LOCATION to sourceAttachment.location, - DIGEST to sourceAttachment.digest, - MAC_DIGEST to sourceAttachment.incrementalDigest, - INCREMENTAL_MAC_CHUNK_SIZE to sourceAttachment.incrementalMacChunkSize, - CONTENT_DISPOSITION to sourceAttachment.key, - NAME to sourceAttachment.relay, - SIZE to sourceAttachment.size, + REMOTE_LOCATION to sourceAttachment.remoteLocation, + REMOTE_DIGEST to sourceAttachment.remoteDigest, + REMOTE_INCREMENTAL_DIGEST to sourceAttachment.incrementalDigest, + REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE to sourceAttachment.incrementalMacChunkSize, + REMOTE_KEY to sourceAttachment.remoteKey, + DATA_SIZE to sourceAttachment.size, FAST_PREFLIGHT_ID to sourceAttachment.fastPreflightId, WIDTH to sourceAttachment.width, HEIGHT to sourceAttachment.height, CONTENT_TYPE to sourceAttachment.contentType, - VISUAL_HASH to sourceAttachment.getVisualHashStringOrNull(), + BLUR_HASH to sourceAttachment.getVisualHashStringOrNull(), TRANSFORM_PROPERTIES to sourceAttachment.transformProperties?.serialize() ) - .where(PART_ID_WHERE, destinationId.toStrings()) + .where("$ID = ?", destinationId.id) .run() } @@ -639,7 +615,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(CAPTION to caption) - .where(PART_ID_WHERE, id.toStrings()) + .where("$ID = ?", id.id) .run() } @@ -648,26 +624,25 @@ class AttachmentTable( for ((key, value) in orderMap) { db.update(TABLE_NAME) .values(DISPLAY_ORDER to value) - .where(PART_ID_WHERE, key.toStrings()) + .where("$ID = ?", key.id) .run() } } } fun updateAttachmentAfterUpload(id: AttachmentId, attachment: Attachment, uploadTimestamp: Long) { - val dataInfo = getAttachmentDataFileInfo(id, DATA) + val dataInfo = getAttachmentDataFileInfo(id, DATA_FILE) val values = contentValuesOf( TRANSFER_STATE to TRANSFER_PROGRESS_DONE, CDN_NUMBER to attachment.cdnNumber, - CONTENT_LOCATION to attachment.location, - DIGEST to attachment.digest, - MAC_DIGEST to attachment.incrementalDigest, - INCREMENTAL_MAC_CHUNK_SIZE to attachment.incrementalMacChunkSize, - CONTENT_DISPOSITION to attachment.key, - NAME to attachment.relay, - SIZE to attachment.size, + REMOTE_LOCATION to attachment.remoteLocation, + REMOTE_DIGEST to attachment.remoteDigest, + REMOTE_INCREMENTAL_DIGEST to attachment.incrementalDigest, + REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE to attachment.incrementalMacChunkSize, + REMOTE_KEY to attachment.remoteKey, + DATA_SIZE to attachment.size, FAST_PREFLIGHT_ID to attachment.fastPreflightId, - VISUAL_HASH to attachment.getVisualHashStringOrNull(), + BLUR_HASH to attachment.getVisualHashStringOrNull(), UPLOAD_TIMESTAMP to uploadTimestamp ) @@ -677,7 +652,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(values) - .where(PART_ID_WHERE, id.toStrings()) + .where("$ID = ?", id.id) .run() } } @@ -696,7 +671,7 @@ class AttachmentTable( fun updateMessageId(attachmentIds: Collection, mmsId: Long, isStory: Boolean) { writableDatabase.withinTransaction { db -> val values = ContentValues(2).apply { - put(MMS_ID, mmsId) + put(MESSAGE_ID, mmsId) if (!isStory) { putNull(CAPTION) } @@ -709,7 +684,7 @@ class AttachmentTable( updatedCount += db .update(TABLE_NAME) .values(values) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() } @@ -756,7 +731,7 @@ class AttachmentTable( onlyModifyThisAttachment: Boolean ) { val attachmentId = databaseAttachment.attachmentId - val oldDataInfo = getAttachmentDataFileInfo(attachmentId, DATA) ?: throw MmsException("No attachment data found!") + val oldDataInfo = getAttachmentDataFileInfo(attachmentId, DATA_FILE) ?: throw MmsException("No attachment data found!") var destination = oldDataInfo.file val isSingleUseOfData = onlyModifyThisAttachment || oldDataInfo.hash == null @@ -771,11 +746,11 @@ class AttachmentTable( dataInfo = deduplicateAttachment(dataInfo, attachmentId, databaseAttachment.transformProperties) val contentValues = contentValuesOf( - SIZE to dataInfo.length, + DATA_SIZE to dataInfo.length, CONTENT_TYPE to mediaStream.mimeType, WIDTH to mediaStream.width, HEIGHT to mediaStream.height, - DATA to dataInfo.file.absolutePath, + DATA_FILE to dataInfo.file.absolutePath, DATA_RANDOM to dataInfo.random, DATA_HASH to dataInfo.hash ) @@ -793,14 +768,14 @@ class AttachmentTable( fun duplicateAttachmentsForMessage(destinationMessageId: Long, sourceMessageId: Long, excludedIds: Collection) { writableDatabase.withinTransaction { db -> - db.execSQL("CREATE TEMPORARY TABLE tmp_part AS SELECT * FROM $TABLE_NAME WHERE $MMS_ID = ?", buildArgs(sourceMessageId)) + db.execSQL("CREATE TEMPORARY TABLE tmp_part AS SELECT * FROM $TABLE_NAME WHERE $MESSAGE_ID = ?", buildArgs(sourceMessageId)) - val queries = buildCollectionQuery(ROW_ID, excludedIds) + val queries = buildCollectionQuery(ID, excludedIds) for (query in queries) { db.delete("tmp_part", query.where, query.whereArgs) } - db.execSQL("UPDATE tmp_part SET $ROW_ID = NULL, $MMS_ID = ?", buildArgs(destinationMessageId)) + db.execSQL("UPDATE tmp_part SET $ID = NULL, $MESSAGE_ID = ?", buildArgs(destinationMessageId)) db.execSQL("INSERT INTO $TABLE_NAME SELECT * FROM tmp_part") db.execSQL("DROP TABLE tmp_part") } @@ -818,7 +793,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(TRANSFER_FILE to transferFile.absolutePath) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() return transferFile @@ -827,9 +802,9 @@ class AttachmentTable( @VisibleForTesting fun getAttachmentDataFileInfo(attachmentId: AttachmentId, dataType: String): DataInfo? { return readableDatabase - .select(dataType, SIZE, DATA_RANDOM, DATA_HASH, TRANSFORM_PROPERTIES) + .select(dataType, DATA_SIZE, DATA_RANDOM, DATA_HASH, TRANSFORM_PROPERTIES) .from(TABLE_NAME) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() .readToSingleObject { cursor -> if (cursor.isNull(dataType)) { @@ -837,7 +812,7 @@ class AttachmentTable( } else { DataInfo( file = File(cursor.getString(cursor.getColumnIndexOrThrow(dataType))), - length = cursor.requireLong(SIZE), + length = cursor.requireLong(DATA_SIZE), random = cursor.requireNonNullBlob(DATA_RANDOM), hash = cursor.requireString(DATA_HASH), transformProperties = TransformProperties.parse(cursor.requireString(TRANSFORM_PROPERTIES)) @@ -872,14 +847,14 @@ class AttachmentTable( Log.i(TAG, "updating part audio wave form for $attachmentId") writableDatabase .update(TABLE_NAME) - .values(VISUAL_HASH to audioWaveForm?.let { AudioHash(it).hash }) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .values(BLUR_HASH to audioWaveForm?.let { AudioHash(it).hash }) + .where("$ID = ?", attachmentId.id) .run() } @RequiresApi(23) fun mediaDataSourceFor(attachmentId: AttachmentId, allowReadingFromTempFile: Boolean): MediaDataSource? { - val dataInfo = getAttachmentDataFileInfo(attachmentId, DATA) + val dataInfo = getAttachmentDataFileInfo(attachmentId, DATA_FILE) if (dataInfo != null) { return EncryptedMediaDataSource.createFor(attachmentSecret, dataInfo.file, dataInfo.random, dataInfo.length) } @@ -903,7 +878,7 @@ class AttachmentTable( return readableDatabase .select(TRANSFORM_PROPERTIES) .from(TABLE_NAME) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .run() .readToSingleObject { TransformProperties.parse(it.requireString(TRANSFORM_PROPERTIES)) @@ -914,7 +889,7 @@ class AttachmentTable( writableDatabase .update(TABLE_NAME) .values(TRANSFER_STATE to TRANSFER_PROGRESS_DONE) - .where(PART_ID_WHERE, (attachment as DatabaseAttachment).attachmentId.toStrings()) + .where("$ID = ?", (attachment as DatabaseAttachment).attachmentId.id) .run() val threadId = messages.getThreadIdForMessage(messageId) @@ -934,22 +909,21 @@ class AttachmentTable( for (i in 0 until array.length()) { val jsonObject = SaneJSONObject(array.getJSONObject(i)) - if (!jsonObject.isNull(ROW_ID)) { + if (!jsonObject.isNull(ID)) { val contentType = jsonObject.getString(CONTENT_TYPE) result += DatabaseAttachment( - attachmentId = AttachmentId(jsonObject.getLong(ROW_ID), jsonObject.getLong(UNIQUE_ID)), - mmsId = jsonObject.getLong(MMS_ID), - hasData = !TextUtils.isEmpty(jsonObject.getString(DATA)), + attachmentId = AttachmentId(jsonObject.getLong(ID)), + mmsId = jsonObject.getLong(MESSAGE_ID), + hasData = !TextUtils.isEmpty(jsonObject.getString(DATA_FILE)), hasThumbnail = MediaUtil.isImageType(contentType) || MediaUtil.isVideoType(contentType), contentType = contentType, transferProgress = jsonObject.getInt(TRANSFER_STATE), - size = jsonObject.getLong(SIZE), + size = jsonObject.getLong(DATA_SIZE), fileName = jsonObject.getString(FILE_NAME), cdnNumber = jsonObject.getInt(CDN_NUMBER), - location = jsonObject.getString(CONTENT_LOCATION), - key = jsonObject.getString(CONTENT_DISPOSITION), - relay = jsonObject.getString(NAME), + location = jsonObject.getString(REMOTE_LOCATION), + key = jsonObject.getString(REMOTE_KEY), digest = null, incrementalDigest = null, incrementalMacChunkSize = 0, @@ -971,8 +945,8 @@ class AttachmentTable( } else { null }, - blurHash = if (MediaUtil.isAudioType(contentType)) null else BlurHash.parseOrNull(jsonObject.getString(VISUAL_HASH)), - audioHash = if (MediaUtil.isAudioType(contentType)) AudioHash.parseOrNull(jsonObject.getString(VISUAL_HASH)) else null, + blurHash = if (MediaUtil.isAudioType(contentType)) null else BlurHash.parseOrNull(jsonObject.getString(BLUR_HASH)), + audioHash = if (MediaUtil.isAudioType(contentType)) AudioHash.parseOrNull(jsonObject.getString(BLUR_HASH)) else null, transformProperties = TransformProperties.parse(jsonObject.getString(TRANSFORM_PROPERTIES)), displayOrder = jsonObject.getInt(DISPLAY_ORDER), uploadTimestamp = jsonObject.getLong(UPLOAD_TIMESTAMP) @@ -1043,11 +1017,11 @@ class AttachmentTable( deletedCount += writableDatabase .update(TABLE_NAME) .values( - DATA to null, + DATA_FILE to null, DATA_RANDOM to null, DATA_HASH to null ) - .where(PART_ID_WHERE, weakReference.toStrings()) + .where("$ID = ?", weakReference.id) .run() } @@ -1079,13 +1053,13 @@ class AttachmentTable( val quoteRows: MutableList = mutableListOf() readableDatabase - .select(ROW_ID, UNIQUE_ID, QUOTE) + .select(ID, QUOTE) .from(TABLE_NAME) - .where("$DATA = ? AND $UNIQUE_ID != ? AND $ROW_ID != ?", data, attachmentId.uniqueId, attachmentId.rowId) + .where("$DATA_FILE = ? AND $ID != ?", data, attachmentId.id) .run() .forEach { cursor -> if (cursor.requireBoolean(QUOTE)) { - quoteRows += AttachmentId(cursor.requireLong(ROW_ID), cursor.requireLong(UNIQUE_ID)) + quoteRows += AttachmentId(cursor.requireLong(ID)) } else { return DataUsageResult.IN_USE } @@ -1104,7 +1078,7 @@ class AttachmentTable( } else { readableDatabase .exists(TABLE_NAME) - .where("$DATA = ? AND $DATA_HASH != ?", dataInfo.file.absolutePath, dataInfo.hash) + .where("$DATA_FILE = ? AND $DATA_HASH != ?", dataInfo.file.absolutePath, dataInfo.hash) .run() } } @@ -1120,7 +1094,7 @@ class AttachmentTable( db.update(TABLE_NAME) .values( - DATA to newData.file.absolutePath, + DATA_FILE to newData.file.absolutePath, DATA_RANDOM to newData.random, DATA_HASH to newData.hash ) @@ -1129,7 +1103,7 @@ class AttachmentTable( } private fun updateAttachmentTransformProperties(attachmentId: AttachmentId, transformProperties: TransformProperties) { - val dataInfo = getAttachmentDataFileInfo(attachmentId, DATA) + val dataInfo = getAttachmentDataFileInfo(attachmentId, DATA_FILE) if (dataInfo == null) { Log.w(TAG, "[updateAttachmentTransformProperties] No data info found!") return @@ -1149,7 +1123,7 @@ class AttachmentTable( return db .update(TABLE_NAME) .values(contentValues) - .where("($ROW_ID = ? AND $UNIQUE_ID = ?) OR ($DATA_HASH NOT NULL AND $DATA_HASH = ?)", attachmentId.rowId.toString(), attachmentId.uniqueId.toString(), dataHash.toString()) + .where("$ID = ? OR ($DATA_HASH NOT NULL AND $DATA_HASH = ?)", attachmentId.id, dataHash.toString()) .run() } @@ -1161,7 +1135,7 @@ class AttachmentTable( return readableDatabase .select("1") .from(TABLE_NAME) - .where("$DATA = ?", file.absolutePath) + .where("$DATA_FILE = ?", file.absolutePath) .limit(2) .run() .use { cursor -> @@ -1297,14 +1271,14 @@ class AttachmentTable( val selectorArgs: Pair> = buildSharedFileSelectorArgs(hash, excludedAttachmentId) return database - .select(DATA, DATA_RANDOM, SIZE, TRANSFORM_PROPERTIES) + .select(DATA_FILE, DATA_RANDOM, DATA_SIZE, TRANSFORM_PROPERTIES) .from(TABLE_NAME) .where(selectorArgs.first, selectorArgs.second) .run() .readToList { cursor -> DataInfo( - file = File(cursor.requireNonNullString(DATA)), - length = cursor.requireLong(SIZE), + file = File(cursor.requireNonNullString(DATA_FILE)), + length = cursor.requireLong(DATA_SIZE), random = cursor.requireNonNullBlob(DATA_RANDOM), hash = hash, transformProperties = TransformProperties.parse(cursor.requireString(TRANSFORM_PROPERTIES)) @@ -1316,9 +1290,8 @@ class AttachmentTable( return if (attachmentId == null) { "$DATA_HASH = ?" to arrayOf(newHash) } else { - "$PART_ID_WHERE_NOT AND $DATA_HASH = ?" to arrayOf( - attachmentId.rowId.toString(), - attachmentId.uniqueId.toString(), + "$ID != ? AND $DATA_HASH = ?" to arrayOf( + attachmentId.id.toString(), newHash ) } @@ -1333,7 +1306,6 @@ class AttachmentTable( val attachmentId: AttachmentId = writableDatabase.withinTransaction { db -> try { var dataInfo: DataInfo? = null - val uniqueId = System.currentTimeMillis() if (attachment.uri != null) { val storeDataInfo = storeAttachmentStream(PartAuthority.getAttachmentStream(context, attachment.uri!!)) @@ -1351,7 +1323,7 @@ class AttachmentTable( for (possibleTemplate in possibleTemplates) { useTemplateUpload = possibleTemplate.uploadTimestamp > attachment.uploadTimestamp && possibleTemplate.transferState == TRANSFER_PROGRESS_DONE && - possibleTemplate.transformProperties?.shouldSkipTransform() == true && possibleTemplate.digest != null && + possibleTemplate.transformProperties?.shouldSkipTransform() == true && possibleTemplate.remoteDigest != null && attachment.transformProperties?.videoEdited == false && possibleTemplate.transformProperties?.sentMediaQuality == attachment.transformProperties?.sentMediaQuality if (useTemplateUpload) { @@ -1363,19 +1335,17 @@ class AttachmentTable( } val contentValues = ContentValues() - contentValues.put(MMS_ID, mmsId) + contentValues.put(MESSAGE_ID, mmsId) contentValues.put(CONTENT_TYPE, template.contentType) contentValues.put(TRANSFER_STATE, attachment.transferState) - contentValues.put(UNIQUE_ID, uniqueId) contentValues.put(CDN_NUMBER, if (useTemplateUpload) template.cdnNumber else attachment.cdnNumber) - contentValues.put(CONTENT_LOCATION, if (useTemplateUpload) template.location else attachment.location) - contentValues.put(DIGEST, if (useTemplateUpload) template.digest else attachment.digest) - contentValues.put(MAC_DIGEST, if (useTemplateUpload) template.incrementalDigest else attachment.incrementalDigest) - contentValues.put(INCREMENTAL_MAC_CHUNK_SIZE, if (useTemplateUpload) template.incrementalMacChunkSize else attachment.incrementalMacChunkSize) - contentValues.put(CONTENT_DISPOSITION, if (useTemplateUpload) template.key else attachment.key) - contentValues.put(NAME, if (useTemplateUpload) template.relay else attachment.relay) + contentValues.put(REMOTE_LOCATION, if (useTemplateUpload) template.remoteLocation else attachment.remoteLocation) + contentValues.put(REMOTE_DIGEST, if (useTemplateUpload) template.remoteDigest else attachment.remoteDigest) + contentValues.put(REMOTE_INCREMENTAL_DIGEST, if (useTemplateUpload) template.incrementalDigest else attachment.incrementalDigest) + contentValues.put(REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE, if (useTemplateUpload) template.incrementalMacChunkSize else attachment.incrementalMacChunkSize) + contentValues.put(REMOTE_KEY, if (useTemplateUpload) template.remoteKey else attachment.remoteKey) contentValues.put(FILE_NAME, StorageUtil.getCleanFileName(attachment.fileName)) - contentValues.put(SIZE, template.size) + contentValues.put(DATA_SIZE, template.size) contentValues.put(FAST_PREFLIGHT_ID, attachment.fastPreflightId) contentValues.put(VOICE_NOTE, if (attachment.voiceNote) 1 else 0) contentValues.put(BORDERLESS, if (attachment.borderless) 1 else 0) @@ -1387,10 +1357,10 @@ class AttachmentTable( contentValues.put(UPLOAD_TIMESTAMP, if (useTemplateUpload) template.uploadTimestamp else attachment.uploadTimestamp) if (attachment.transformProperties?.videoEdited == true) { - contentValues.putNull(VISUAL_HASH) + contentValues.putNull(BLUR_HASH) contentValues.put(TRANSFORM_PROPERTIES, attachment.transformProperties?.serialize()) } else { - contentValues.put(VISUAL_HASH, template.getVisualHashStringOrNull()) + contentValues.put(BLUR_HASH, template.getVisualHashStringOrNull()) contentValues.put(TRANSFORM_PROPERTIES, (if (useTemplateUpload) template else attachment).transformProperties?.serialize()) } @@ -1402,8 +1372,8 @@ class AttachmentTable( } if (dataInfo != null) { - contentValues.put(DATA, dataInfo.file.absolutePath) - contentValues.put(SIZE, dataInfo.length) + contentValues.put(DATA_FILE, dataInfo.file.absolutePath) + contentValues.put(DATA_SIZE, dataInfo.length) contentValues.put(DATA_RANDOM, dataInfo.random) if (attachment.transformProperties?.videoEdited == true) { @@ -1416,7 +1386,7 @@ class AttachmentTable( notifyPacks = attachment.isSticker && !hasStickerAttachments() val rowId = db.insert(TABLE_NAME, null, contentValues) - AttachmentId(rowId, uniqueId) + AttachmentId(rowId) } catch (e: IOException) { throw MmsException(e) } @@ -1447,7 +1417,7 @@ class AttachmentTable( return db .select(TRANSFER_FILE) .from(TABLE_NAME) - .where(PART_ID_WHERE, attachmentId.toStrings()) + .where("$ID = ?", attachmentId.id) .limit(1) .run() .readToSingleObject { cursor -> @@ -1459,21 +1429,20 @@ class AttachmentTable( val contentType = cursor.requireString(CONTENT_TYPE) return DatabaseAttachment( - attachmentId = AttachmentId(cursor.requireLong(ROW_ID), cursor.requireLong(UNIQUE_ID)), - mmsId = cursor.requireLong(MMS_ID), - hasData = !cursor.isNull(DATA), + attachmentId = AttachmentId(cursor.requireLong(ID)), + mmsId = cursor.requireLong(MESSAGE_ID), + hasData = !cursor.isNull(DATA_FILE), hasThumbnail = MediaUtil.isImageType(contentType) || MediaUtil.isVideoType(contentType), contentType = contentType, transferProgress = cursor.requireInt(TRANSFER_STATE), - size = cursor.requireLong(SIZE), + size = cursor.requireLong(DATA_SIZE), fileName = cursor.requireString(FILE_NAME), cdnNumber = cursor.requireInt(CDN_NUMBER), - location = cursor.requireString(CONTENT_LOCATION), - key = cursor.requireString(CONTENT_DISPOSITION), - relay = cursor.requireString(NAME), - digest = cursor.requireBlob(DIGEST), - incrementalDigest = cursor.requireBlob(MAC_DIGEST), - incrementalMacChunkSize = cursor.requireInt(INCREMENTAL_MAC_CHUNK_SIZE), + location = cursor.requireString(REMOTE_LOCATION), + key = cursor.requireString(REMOTE_KEY), + digest = cursor.requireBlob(REMOTE_DIGEST), + incrementalDigest = cursor.requireBlob(REMOTE_INCREMENTAL_DIGEST), + incrementalMacChunkSize = cursor.requireInt(REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE), fastPreflightId = cursor.requireString(FAST_PREFLIGHT_ID), voiceNote = cursor.requireBoolean(VOICE_NOTE), borderless = cursor.requireBoolean(BORDERLESS), @@ -1483,8 +1452,8 @@ class AttachmentTable( quote = cursor.requireBoolean(QUOTE), caption = cursor.requireString(CAPTION), stickerLocator = cursor.readStickerLocator(), - blurHash = if (MediaUtil.isAudioType(contentType)) null else BlurHash.parseOrNull(cursor.requireString(VISUAL_HASH)), - audioHash = if (MediaUtil.isAudioType(contentType)) AudioHash.parseOrNull(cursor.requireString(VISUAL_HASH)) else null, + blurHash = if (MediaUtil.isAudioType(contentType)) null else BlurHash.parseOrNull(cursor.requireString(BLUR_HASH)), + audioHash = if (MediaUtil.isAudioType(contentType)) AudioHash.parseOrNull(cursor.requireString(BLUR_HASH)) else null, transformProperties = TransformProperties.parse(cursor.requireString(TRANSFORM_PROPERTIES)), displayOrder = cursor.requireInt(DISPLAY_ORDER), uploadTimestamp = cursor.requireLong(UPLOAD_TIMESTAMP) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt index 63ad86da12..cc137bcbea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt @@ -20,18 +20,17 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD private const val THREAD_RECIPIENT_ID = "THREAD_RECIPIENT_ID" private val BASE_MEDIA_QUERY = """ SELECT - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ROW_ID} AS ${AttachmentTable.ROW_ID}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ID} AS ${AttachmentTable.ID}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CONTENT_TYPE}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.UNIQUE_ID}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.TRANSFER_STATE}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.SIZE}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA_SIZE}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.FILE_NAME}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA_FILE}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CDN_NUMBER}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CONTENT_LOCATION}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CONTENT_DISPOSITION}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DIGEST}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_LOCATION}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_KEY}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_DIGEST}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.FAST_PREFLIGHT_ID}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.VOICE_NOTE}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.BORDERLESS}, @@ -43,14 +42,13 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_PACK_KEY}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_ID}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_EMOJI}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.VISUAL_HASH}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.BLUR_HASH}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.TRANSFORM_PROPERTIES}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CAPTION}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.NAME}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.UPLOAD_TIMESTAMP}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MAC_DIGEST}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.INCREMENTAL_MAC_CHUNK_SIZE}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_INCREMENTAL_DIGEST}, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE}, ${MessageTable.TABLE_NAME}.${MessageTable.TYPE}, ${MessageTable.TABLE_NAME}.${MessageTable.DATE_SENT}, ${MessageTable.TABLE_NAME}.${MessageTable.DATE_RECEIVED}, @@ -60,10 +58,10 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} as $THREAD_RECIPIENT_ID FROM ${AttachmentTable.TABLE_NAME} - LEFT JOIN ${MessageTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID} + LEFT JOIN ${MessageTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID} LEFT JOIN ${ThreadTable.TABLE_NAME} ON ${ThreadTable.TABLE_NAME}.${ThreadTable.ID} = ${MessageTable.TABLE_NAME}.${MessageTable.THREAD_ID} WHERE - ${AttachmentTable.MMS_ID} IN ( + ${AttachmentTable.MESSAGE_ID} IN ( SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.THREAD_ID} __EQUALITY__ ? @@ -86,20 +84,20 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD private val UNIQUE_MEDIA_QUERY = """ SELECT - MAX(${AttachmentTable.SIZE}) as ${AttachmentTable.SIZE}, + MAX(${AttachmentTable.DATA_SIZE}) as ${AttachmentTable.DATA_SIZE}, ${AttachmentTable.CONTENT_TYPE} FROM ${AttachmentTable.TABLE_NAME} WHERE ${AttachmentTable.STICKER_PACK_ID} IS NULL AND ${AttachmentTable.TRANSFER_STATE} = ${AttachmentTable.TRANSFER_PROGRESS_DONE} - GROUP BY ${AttachmentTable.DATA} + GROUP BY ${AttachmentTable.DATA_FILE} """ private val GALLERY_MEDIA_QUERY = String.format( BASE_MEDIA_QUERY, """ - ${AttachmentTable.DATA} IS NOT NULL AND + ${AttachmentTable.DATA_FILE} IS NOT NULL AND ${AttachmentTable.CONTENT_TYPE} NOT LIKE 'image/svg%' AND (${AttachmentTable.CONTENT_TYPE} LIKE 'image/%' OR ${AttachmentTable.CONTENT_TYPE} LIKE 'video/%') """ @@ -108,7 +106,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD private val GALLERY_MEDIA_QUERY_INCLUDING_TEMP_VIDEOS = String.format( BASE_MEDIA_QUERY, """ - (${AttachmentTable.DATA} IS NOT NULL OR (${AttachmentTable.CONTENT_TYPE} LIKE 'video/%' AND ${AttachmentTable.MAC_DIGEST} IS NOT NULL)) AND + (${AttachmentTable.DATA_FILE} IS NOT NULL OR (${AttachmentTable.CONTENT_TYPE} LIKE 'video/%' AND ${AttachmentTable.REMOTE_INCREMENTAL_DIGEST} IS NOT NULL)) AND ${AttachmentTable.CONTENT_TYPE} NOT LIKE 'image/svg%' AND (${AttachmentTable.CONTENT_TYPE} LIKE 'image/%' OR ${AttachmentTable.CONTENT_TYPE} LIKE 'video/%') """ @@ -117,17 +115,17 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD private val AUDIO_MEDIA_QUERY = String.format( BASE_MEDIA_QUERY, """ - ${AttachmentTable.DATA} IS NOT NULL AND + ${AttachmentTable.DATA_FILE} IS NOT NULL AND ${AttachmentTable.CONTENT_TYPE} LIKE 'audio/%' """ ) - private val ALL_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, "${AttachmentTable.DATA} IS NOT NULL AND ${AttachmentTable.CONTENT_TYPE} NOT LIKE 'text/x-signal-plain'") + private val ALL_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, "${AttachmentTable.DATA_FILE} IS NOT NULL AND ${AttachmentTable.CONTENT_TYPE} NOT LIKE 'text/x-signal-plain'") private val DOCUMENT_MEDIA_QUERY = String.format( BASE_MEDIA_QUERY, """ - ${AttachmentTable.DATA} IS NOT NULL AND + ${AttachmentTable.DATA_FILE} IS NOT NULL AND ( ${AttachmentTable.CONTENT_TYPE} LIKE 'image/svg%' OR ( @@ -185,7 +183,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD readableDatabase.rawQuery(UNIQUE_MEDIA_QUERY, null).use { cursor -> while (cursor.moveToNext()) { - val size: Int = cursor.requireInt(AttachmentTable.SIZE) + val size: Int = cursor.requireInt(AttachmentTable.DATA_SIZE) val type: String = cursor.requireNonNullString(AttachmentTable.CONTENT_TYPE) when (MediaUtil.getSlideTypeFromContentType(type)) { @@ -253,21 +251,21 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD enum class Sorting(order: String) { Newest( """ - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} DESC, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID} DESC, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER} DESC, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ROW_ID} DESC + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ID} DESC """ ), Oldest( """ - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} ASC, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID} ASC, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER} DESC, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ROW_ID} ASC + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ID} ASC """ ), Largest( """ - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.SIZE} DESC, + ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA_SIZE} DESC, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER} DESC """ ); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogTables.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogTables.kt index 16e3d7096f..b0e7817e62 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogTables.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageSendLogTables.kt @@ -92,13 +92,13 @@ class MessageSendLogTables constructor(context: Context?, databaseHelper: Signal """ CREATE TRIGGER msl_message_delete AFTER DELETE ON ${MessageTable.TABLE_NAME} BEGIN - DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MslMessageTable.PAYLOAD_ID} FROM ${MslMessageTable.TABLE_NAME} WHERE ${MslMessageTable.MESSAGE_ID} = old.${MessageTable.ID}); + DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MslMessageTable.PAYLOAD_ID} FROM ${MslMessageTable.TABLE_NAME} WHERE ${MslMessageTable.MESSAGE_ID} = old.${MessageTable.ID}); END """, """ CREATE TRIGGER msl_attachment_delete AFTER DELETE ON ${AttachmentTable.TABLE_NAME} BEGIN - DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MslMessageTable.PAYLOAD_ID} FROM ${MslMessageTable.TABLE_NAME} WHERE ${MslMessageTable.MESSAGE_ID} = old.${AttachmentTable.MMS_ID}); + DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MslMessageTable.PAYLOAD_ID} FROM ${MslMessageTable.TABLE_NAME} WHERE ${MslMessageTable.TABLE_NAME}.${MslMessageTable.MESSAGE_ID} = old.${AttachmentTable.MESSAGE_ID}); END """ ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index 9b633e9cdb..8751fb33d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -351,15 +351,14 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat """ json_group_array( json_object( - '${AttachmentTable.ROW_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ROW_ID}, - '${AttachmentTable.UNIQUE_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.UNIQUE_ID}, - '${AttachmentTable.MMS_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID}, - '${AttachmentTable.SIZE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.SIZE}, + '${AttachmentTable.ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.ID}, + '${AttachmentTable.MESSAGE_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID}, + '${AttachmentTable.DATA_SIZE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA_SIZE}, '${AttachmentTable.FILE_NAME}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.FILE_NAME}, - '${AttachmentTable.DATA}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA}, + '${AttachmentTable.DATA_FILE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA_FILE}, '${AttachmentTable.CONTENT_TYPE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CONTENT_TYPE}, '${AttachmentTable.CDN_NUMBER}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CDN_NUMBER}, - '${AttachmentTable.CONTENT_LOCATION}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CONTENT_LOCATION}, + '${AttachmentTable.REMOTE_LOCATION}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_LOCATION}, '${AttachmentTable.FAST_PREFLIGHT_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.FAST_PREFLIGHT_ID}, '${AttachmentTable.VOICE_NOTE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.VOICE_NOTE}, '${AttachmentTable.BORDERLESS}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.BORDERLESS}, @@ -367,15 +366,14 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat '${AttachmentTable.WIDTH}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.WIDTH}, '${AttachmentTable.HEIGHT}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.HEIGHT}, '${AttachmentTable.QUOTE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.QUOTE}, - '${AttachmentTable.CONTENT_DISPOSITION}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CONTENT_DISPOSITION}, - '${AttachmentTable.NAME}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.NAME}, + '${AttachmentTable.REMOTE_KEY}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_KEY}, '${AttachmentTable.TRANSFER_STATE}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.TRANSFER_STATE}, '${AttachmentTable.CAPTION}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CAPTION}, '${AttachmentTable.STICKER_PACK_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_PACK_ID}, '${AttachmentTable.STICKER_PACK_KEY}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_PACK_KEY}, '${AttachmentTable.STICKER_ID}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_ID}, '${AttachmentTable.STICKER_EMOJI}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.STICKER_EMOJI}, - '${AttachmentTable.VISUAL_HASH}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.VISUAL_HASH}, + '${AttachmentTable.BLUR_HASH}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.BLUR_HASH}, '${AttachmentTable.TRANSFORM_PROPERTIES}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.TRANSFORM_PROPERTIES}, '${AttachmentTable.DISPLAY_ORDER}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER}, '${AttachmentTable.UPLOAD_TIMESTAMP}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.UPLOAD_TIMESTAMP} @@ -1783,7 +1781,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat SELECT ${Util.join(projection, ",")} FROM - $TABLE_NAME LEFT OUTER JOIN ${AttachmentTable.TABLE_NAME} ON ($TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID}) + $TABLE_NAME LEFT OUTER JOIN ${AttachmentTable.TABLE_NAME} ON ($TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID}) WHERE $where GROUP BY @@ -2253,12 +2251,12 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat .run() readableDatabase - .select(AttachmentTable.ROW_ID, AttachmentTable.UNIQUE_ID) + .select(AttachmentTable.ID) .from(AttachmentTable.TABLE_NAME) - .where("${AttachmentTable.MMS_ID} NOT IN (SELECT $ID FROM $TABLE_NAME)") + .where("${AttachmentTable.MESSAGE_ID} NOT IN (SELECT $ID FROM $TABLE_NAME)") .run() .forEach { cursor -> - attachments.deleteAttachment(AttachmentId(cursor.requireLong(AttachmentTable.ROW_ID), cursor.requireLong(AttachmentTable.UNIQUE_ID))) + attachments.deleteAttachment(AttachmentId(cursor.requireLong(AttachmentTable.ID))) } mentions.deleteAbandonedMentions() @@ -2555,7 +2553,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat } if (retrieved.attachments.isEmpty() && editedMessage?.id != null && attachments.getAttachmentsForMessage(editedMessage.id).isNotEmpty()) { - val linkPreviewAttachmentIds = editedMessage.linkPreviews.mapNotNull { it.attachmentId?.rowId }.toSet() + val linkPreviewAttachmentIds = editedMessage.linkPreviews.mapNotNull { it.attachmentId?.id }.toSet() attachments.duplicateAttachmentsForMessage(messageId, editedMessage.id, linkPreviewAttachmentIds) } @@ -2928,8 +2926,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat .where("$ID_WHERE OR $LATEST_REVISION_ID = ?", message.messageToEdit, message.messageToEdit) .run() - val textAttachments = (editedMessage as? MmsMessageRecord)?.slideDeck?.asAttachments()?.filter { it.contentType == MediaUtil.LONG_TEXT }?.mapNotNull { (it as? DatabaseAttachment)?.attachmentId?.rowId } ?: emptyList() - val linkPreviewAttachments = (editedMessage as? MmsMessageRecord)?.linkPreviews?.mapNotNull { it.attachmentId?.rowId } ?: emptyList() + val textAttachments = (editedMessage as? MmsMessageRecord)?.slideDeck?.asAttachments()?.filter { it.contentType == MediaUtil.LONG_TEXT }?.mapNotNull { (it as? DatabaseAttachment)?.attachmentId?.id } ?: emptyList() + val linkPreviewAttachments = (editedMessage as? MmsMessageRecord)?.linkPreviews?.mapNotNull { it.attachmentId?.id } ?: emptyList() val excludeIds = HashSet() excludeIds += textAttachments excludeIds += linkPreviewAttachments @@ -3305,9 +3303,9 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat val fileSize: Long = readableDatabase.rawQuery( """ SELECT - SUM(${AttachmentTable.TABLE_NAME}.${AttachmentTable.SIZE}) AS s + SUM(${AttachmentTable.TABLE_NAME}.${AttachmentTable.DATA_SIZE}) AS s FROM - $TABLE_NAME INNER JOIN ${AttachmentTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} + $TABLE_NAME INNER JOIN ${AttachmentTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID} WHERE ${getInsecureMessageClause()} AND $EXPORTED < ${MessageExportStatus.EXPORTED.serialize()} """, @@ -3415,10 +3413,10 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat $VIEW_ONCE, $DATE_RECEIVED FROM - $TABLE_NAME INNER JOIN ${AttachmentTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} + $TABLE_NAME INNER JOIN ${AttachmentTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MESSAGE_ID} WHERE $VIEW_ONCE > 0 AND - (${AttachmentTable.DATA} NOT NULL OR ${AttachmentTable.TRANSFER_STATE} != ?) + (${AttachmentTable.DATA_FILE} NOT NULL OR ${AttachmentTable.TRANSFER_STATE} != ?) """ val args = buildArgs(AttachmentTable.TRANSFER_PROGRESS_DONE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt index f732038a79..292af9cd1d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -72,6 +72,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V211_ReceiptColumnR import org.thoughtcrime.securesms.database.helpers.migration.V212_RemoveDistributionListUniqueConstraint import org.thoughtcrime.securesms.database.helpers.migration.V213_FixUsernameInE164Column import org.thoughtcrime.securesms.database.helpers.migration.V214_PhoneNumberSharingColumn +import org.thoughtcrime.securesms.database.helpers.migration.V215_RemoveAttachmentUniqueId /** * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. @@ -146,10 +147,11 @@ object SignalDatabaseMigrations { 211 to V211_ReceiptColumnRenames, 212 to V212_RemoveDistributionListUniqueConstraint, 213 to V213_FixUsernameInE164Column, - 214 to V214_PhoneNumberSharingColumn + 214 to V214_PhoneNumberSharingColumn, + 215 to V215_RemoveAttachmentUniqueId ) - const val DATABASE_VERSION = 214 + const val DATABASE_VERSION = 215 @JvmStatic fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V215_RemoveAttachmentUniqueId.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V215_RemoveAttachmentUniqueId.kt new file mode 100644 index 0000000000..298d39f8a7 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V215_RemoveAttachmentUniqueId.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.database.helpers.migration + +import android.app.Application +import net.zetetic.database.sqlcipher.SQLiteDatabase +import org.signal.core.util.Stopwatch +import org.signal.core.util.logging.Log + +object V215_RemoveAttachmentUniqueId : SignalDatabaseMigration { + + private val TAG = Log.tag(V215_RemoveAttachmentUniqueId::class.java) + + override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + val stopwatch = Stopwatch("migration", decimalPlaces = 2) + + db.execSQL( + """ + CREATE TABLE attachment ( + _id INTEGER PRIMARY KEY AUTOINCREMENT, + message_id INTEGER, + content_type TEXT, + remote_key TEXT, + remote_location TEXT, + remote_digest BLOB, + remote_incremental_digest BLOB, + remote_incremental_digest_chunk_size INTEGER DEFAULT 0, + cdn_number INTEGER DEFAULT 0, + transfer_state INTEGER, + transfer_file TEXT DEFAULT NULL, + data_file TEXT, + data_size INTEGER, + data_random BLOB, + data_hash TEXT DEFAULT NULL, + file_name TEXT, + fast_preflight_id TEXT, + voice_note INTEGER DEFAULT 0, + borderless INTEGER DEFAULT 0, + video_gif INTEGER DEFAULT 0, + quote INTEGER DEFAULT 0, + width INTEGER DEFAULT 0, + height INTEGER DEFAULT 0, + caption TEXT DEFAULT NULL, + sticker_pack_id TEXT DEFAULT NULL, + sticker_pack_key DEFAULT NULL, + sticker_id INTEGER DEFAULT -1, + sticker_emoji STRING DEFAULT NULL, + blur_hash TEXT DEFAULT NULL, + transform_properties TEXT DEFAULT NULL, + display_order INTEGER DEFAULT 0, + upload_timestamp INTEGER DEFAULT 0 + ) + """ + ) + + db.execSQL( + """ + INSERT INTO attachment + SELECT + _id, + mid, + ct, + cd, + cl, + digest, + incremental_mac_digest, + incremental_mac_chunk_size, + cdn_number, + pending_push, + transfer_file, + _data, + data_size, + data_random, + data_hash, + file_name, + fast_preflight_id, + voice_note, + borderless, + video_gif, + quote, + width, + height, + caption, + sticker_pack_id, + sticker_pack_key, + sticker_id, + sticker_emoji, + blur_hash, + transform_properties, + display_order, + upload_timestamp + FROM part + """ + ) + stopwatch.split("copy-data") + + db.execSQL("DROP TABLE part") + stopwatch.split("drop-old") + + db.execSQL("CREATE INDEX IF NOT EXISTS attachment_message_id_index ON attachment (message_id)") + db.execSQL("CREATE INDEX IF NOT EXISTS attachment_transfer_state_index ON attachment (transfer_state)") + db.execSQL("CREATE INDEX IF NOT EXISTS attachment_sticker_pack_id_index ON attachment (sticker_pack_id)") + db.execSQL("CREATE INDEX IF NOT EXISTS attachment_data_hash_index ON attachment (data_hash)") + db.execSQL("CREATE INDEX IF NOT EXISTS attachment_data_index ON attachment (data_file)") + stopwatch.split("create-indexes") + + db.execSQL( + """ + CREATE TRIGGER msl_attachment_delete AFTER DELETE ON attachment + BEGIN + DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE msl_message.message_id = old.message_id); + END + """ + ) + + stopwatch.stop(TAG) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java index a551bb1201..26a64611de 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/loaders/PagingMediaLoader.java @@ -48,7 +48,7 @@ public final class PagingMediaLoader extends AsyncLoader> Cursor cursor = SignalDatabase.media().getGalleryMediaForThread(threadId, sorting); while (cursor.moveToNext()) { - AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.ROW_ID)), cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.UNIQUE_ID))); + AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentTable.ID))); Uri attachmentUri = PartAuthority.getAttachmentDataUri(attachmentId); if (attachmentUri.equals(uri)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java index bf8fa8f5e2..fe238d627b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java @@ -59,9 +59,8 @@ public final class AttachmentCompressionJob extends BaseJob { @SuppressWarnings("unused") private static final String TAG = Log.tag(AttachmentCompressionJob.class); - private static final String KEY_ROW_ID = "row_id"; - private static final String KEY_UNIQUE_ID = "unique_id"; - private static final String KEY_MMS = "mms"; + private static final String KEY_ATTACHMENT_ID = "row_id"; + private static final String KEY_MMS = "mms"; private static final String KEY_MMS_SUBSCRIPTION_ID = "mms_subscription_id"; private final AttachmentId attachmentId; @@ -107,8 +106,7 @@ public final class AttachmentCompressionJob extends BaseJob { @Override public @Nullable byte [] serialize() { - return new JsonJobData.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId()) - .putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId()) + return new JsonJobData.Builder().putLong(KEY_ATTACHMENT_ID, attachmentId.id) .putBoolean(KEY_MMS, mms) .putInt(KEY_MMS_SUBSCRIPTION_ID, mmsSubscriptionId) .serialize(); @@ -391,7 +389,7 @@ public final class AttachmentCompressionJob extends BaseJob { } JsonJobData data = JsonJobData.deserialize(serializedData); - final AttachmentId parsed = new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)); + final AttachmentId parsed = new AttachmentId(data.getLong(KEY_ATTACHMENT_ID)); return attachmentId.equals(parsed); } @@ -401,7 +399,7 @@ public final class AttachmentCompressionJob extends BaseJob { JsonJobData data = JsonJobData.deserialize(serializedData); return new AttachmentCompressionJob(parameters, - new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), + new AttachmentId(data.getLong(KEY_ATTACHMENT_ID)), data.getBoolean(KEY_MMS), data.getInt(KEY_MMS_SUBSCRIPTION_ID)); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java index d6821b5e62..56d3049ba4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java @@ -64,14 +64,12 @@ public final class AttachmentDownloadJob extends BaseJob { private static final String TAG = Log.tag(AttachmentDownloadJob.class); - private static final String KEY_MESSAGE_ID = "message_id"; - private static final String KEY_ROW_ID = "part_row_id"; - private static final String KEY_UNIQUE_ID = "part_unique_id"; - private static final String KEY_MANUAL = "part_manual"; + private static final String KEY_MESSAGE_ID = "message_id"; + private static final String KEY_ATTACHMENT_ID = "part_row_id"; + private static final String KEY_MANUAL = "part_manual"; - private final long messageId; - private final long partRowId; - private final long partUniqueId; + private final long messageId; + private final long attachmentId; private final boolean manual; public AttachmentDownloadJob(long messageId, AttachmentId attachmentId, boolean manual) { @@ -90,16 +88,14 @@ public final class AttachmentDownloadJob extends BaseJob { super(parameters); this.messageId = messageId; - this.partRowId = attachmentId.getRowId(); - this.partUniqueId = attachmentId.getUniqueId(); + this.attachmentId = attachmentId.id; this.manual = manual; } @Override public @Nullable byte[] serialize() { return new JsonJobData.Builder().putLong(KEY_MESSAGE_ID, messageId) - .putLong(KEY_ROW_ID, partRowId) - .putLong(KEY_UNIQUE_ID, partUniqueId) + .putLong(KEY_ATTACHMENT_ID, attachmentId) .putBoolean(KEY_MANUAL, manual) .serialize(); } @@ -110,18 +106,18 @@ public final class AttachmentDownloadJob extends BaseJob { } public static String constructQueueString(AttachmentId attachmentId) { - return "AttachmentDownloadJob" + attachmentId.getRowId() + "-" + attachmentId.getUniqueId(); + return "AttachmentDownloadJob-" + attachmentId.id; } @Override public void onAdded() { - Log.i(TAG, "onAdded() messageId: " + messageId + " partRowId: " + partRowId + " partUniqueId: " + partUniqueId + " manual: " + manual); + Log.i(TAG, "onAdded() messageId: " + messageId + " attachmentId: " + attachmentId + " manual: " + manual); final AttachmentTable database = SignalDatabase.attachments(); - final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId); + final AttachmentId attachmentId = new AttachmentId(this.attachmentId); final DatabaseAttachment attachment = database.getAttachment(attachmentId); - final boolean pending = attachment != null && attachment.transferState != AttachmentTable.TRANSFER_PROGRESS_DONE - && attachment.transferState != 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'"); @@ -139,10 +135,10 @@ public final class AttachmentDownloadJob extends BaseJob { } public void doWork() throws IOException, RetryLaterException { - Log.i(TAG, "onRun() messageId: " + messageId + " partRowId: " + partRowId + " partUniqueId: " + partUniqueId + " manual: " + manual); + Log.i(TAG, "onRun() messageId: " + messageId + " attachmentId: " + attachmentId + " manual: " + manual); final AttachmentTable database = SignalDatabase.attachments(); - final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId); + final AttachmentId attachmentId = new AttachmentId(this.attachmentId); final DatabaseAttachment attachment = database.getAttachment(attachmentId); if (attachment == null) { @@ -178,9 +174,9 @@ public final class AttachmentDownloadJob extends BaseJob { @Override public void onFailure() { - Log.w(TAG, JobLogger.format(this, "onFailure() messageId: " + messageId + " partRowId: " + partRowId + " partUniqueId: " + partUniqueId + " manual: " + manual)); + Log.w(TAG, JobLogger.format(this, "onFailure() messageId: " + messageId + " attachmentId: " + attachmentId + " manual: " + manual)); - final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId); + final AttachmentId attachmentId = new AttachmentId(this.attachmentId); markFailed(messageId, attachmentId); } @@ -244,20 +240,20 @@ public final class AttachmentDownloadJob extends BaseJob { } private SignalServiceAttachmentPointer createAttachmentPointer(Attachment attachment) throws InvalidPartException { - if (TextUtils.isEmpty(attachment.location)) { + if (TextUtils.isEmpty(attachment.remoteLocation)) { throw new InvalidPartException("empty content id"); } - if (TextUtils.isEmpty(attachment.key)) { + if (TextUtils.isEmpty(attachment.remoteKey)) { throw new InvalidPartException("empty encrypted key"); } try { - final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.location); - final byte[] key = Base64.decode(attachment.key); + final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.remoteLocation); + final byte[] key = Base64.decode(attachment.remoteKey); - if (attachment.digest != null) { - Log.i(TAG, "Downloading attachment with digest: " + Hex.toString(attachment.digest)); + if (attachment.remoteDigest != null) { + Log.i(TAG, "Downloading attachment with digest: " + Hex.toString(attachment.remoteDigest)); } else { Log.i(TAG, "Downloading attachment with no digest..."); } @@ -266,7 +262,7 @@ public final class AttachmentDownloadJob extends BaseJob { Optional.of(Util.toIntExact(attachment.size)), Optional.empty(), 0, 0, - Optional.ofNullable(attachment.digest), + Optional.ofNullable(attachment.remoteDigest), Optional.ofNullable(attachment.getIncrementalDigest()), attachment.incrementalMacChunkSize, Optional.ofNullable(attachment.fileName), @@ -330,7 +326,7 @@ public final class AttachmentDownloadJob extends BaseJob { } JsonJobData data = JsonJobData.deserialize(serializedData); - final AttachmentId parsed = new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)); + final AttachmentId parsed = new AttachmentId(data.getLong(KEY_ATTACHMENT_ID)); return attachmentId.equals(parsed); } @@ -347,7 +343,7 @@ public final class AttachmentDownloadJob extends BaseJob { return new AttachmentDownloadJob(parameters, data.getLong(KEY_MESSAGE_ID), - new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), + new AttachmentId(data.getLong(KEY_ATTACHMENT_ID)), data.getBoolean(KEY_MANUAL)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java index 6e22100931..1c3b206857 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentMarkUploadedJob.java @@ -24,9 +24,8 @@ public final class AttachmentMarkUploadedJob extends BaseJob { @SuppressWarnings("unused") private static final String TAG = Log.tag(AttachmentMarkUploadedJob.class); - private static final String KEY_ROW_ID = "row_id"; - private static final String KEY_UNIQUE_ID = "unique_id"; - private static final String KEY_MESSAGE_ID = "message_id"; + private static final String KEY_ATTACHMENT_ID = "row_id"; + private static final String KEY_MESSAGE_ID = "message_id"; private final AttachmentId attachmentId; private final long messageId; @@ -48,8 +47,7 @@ public final class AttachmentMarkUploadedJob extends BaseJob { @Override public @Nullable byte[] serialize() { - return new JsonJobData.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId()) - .putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId()) + return new JsonJobData.Builder().putLong(KEY_ATTACHMENT_ID, attachmentId.id) .putLong(KEY_MESSAGE_ID, messageId) .serialize(); } @@ -93,7 +91,7 @@ public final class AttachmentMarkUploadedJob extends BaseJob { return new AttachmentMarkUploadedJob(parameters, data.getLong(KEY_MESSAGE_ID), - new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID))); + new AttachmentId(data.getLong(KEY_ATTACHMENT_ID))); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt index 11246d88dc..c2d5ad5dff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt @@ -82,7 +82,7 @@ class AttachmentUploadJob private constructor( } val serializedData = jobSpec.serializedData ?: return false val data = AttachmentUploadJobData.ADAPTER.decode(serializedData) - val parsed = AttachmentId(data.attachmentRowId, data.attachmentUniqueId) + val parsed = AttachmentId(data.attachmentId) return attachmentId == parsed } } @@ -99,8 +99,7 @@ class AttachmentUploadJob private constructor( override fun serialize(): ByteArray { return AttachmentUploadJobData( - attachmentRowId = attachmentId.rowId, - attachmentUniqueId = attachmentId.uniqueId, + attachmentId = attachmentId.id, uploadSpec = uploadSpec ).encode() } @@ -138,7 +137,7 @@ class AttachmentUploadJob private constructor( val databaseAttachment = SignalDatabase.attachments.getAttachment(attachmentId) ?: throw InvalidAttachmentException("Cannot find the specified attachment.") val timeSinceUpload = System.currentTimeMillis() - databaseAttachment.uploadTimestamp - if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.location)) { + if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.remoteLocation)) { Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded $timeSinceUpload ms (${timeSinceUpload.milliseconds.inRoundedDays()} days) ago. Skipping.") return } else if (databaseAttachment.uploadTimestamp > 0) { @@ -297,7 +296,7 @@ class AttachmentUploadJob private constructor( val data = AttachmentUploadJobData.ADAPTER.decode(serializedData!!) return AttachmentUploadJob( parameters = parameters, - attachmentId = AttachmentId(data.attachmentRowId, data.attachmentUniqueId), + attachmentId = AttachmentId(data.attachmentId), data.uploadSpec ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt index 41a1e3b5ca..ae0b3cea19 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt @@ -22,8 +22,7 @@ class GenerateAudioWaveFormJob private constructor(private val attachmentId: Att companion object { private val TAG = Log.tag(GenerateAudioWaveFormJob::class.java) - private const val KEY_PART_ROW_ID = "part_row_id" - private const val KEY_PAR_UNIQUE_ID = "part_unique_id" + private const val KEY_ATTACHMENT_ID = "part_row_id" const val KEY = "GenerateAudioWaveFormJob" @@ -48,8 +47,7 @@ class GenerateAudioWaveFormJob private constructor(private val attachmentId: Att override fun serialize(): ByteArray? { return JsonJobData.Builder() - .putLong(KEY_PART_ROW_ID, attachmentId.rowId) - .putLong(KEY_PAR_UNIQUE_ID, attachmentId.uniqueId) + .putLong(KEY_ATTACHMENT_ID, attachmentId.id) .serialize() } @@ -89,7 +87,7 @@ class GenerateAudioWaveFormJob private constructor(private val attachmentId: Att class Factory : Job.Factory { override fun create(parameters: Parameters, serializedData: ByteArray?): GenerateAudioWaveFormJob { val data = JsonJobData.deserialize(serializedData) - return GenerateAudioWaveFormJob(AttachmentId(data.getLong(KEY_PART_ROW_ID), data.getLong(KEY_PAR_UNIQUE_ID)), parameters) + return GenerateAudioWaveFormJob(AttachmentId(data.getLong(KEY_ATTACHMENT_ID)), parameters) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java index 3e12bb822e..721f5e6a92 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java @@ -60,9 +60,8 @@ public final class LegacyAttachmentUploadJob extends BaseJob { private static final long UPLOAD_REUSE_THRESHOLD = TimeUnit.DAYS.toMillis(3); - private static final String KEY_ROW_ID = "row_id"; - private static final String KEY_UNIQUE_ID = "unique_id"; - private static final String KEY_FORCE_V2 = "force_v2"; + private static final String KEY_ROW_ID = "row_id"; + private static final String KEY_FORCE_V2 = "force_v2"; /** * Foreground notification shows while uploading attachments above this. @@ -81,8 +80,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob { @Override public @Nullable byte[] serialize() { - return new JsonJobData.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId()) - .putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId()) + return new JsonJobData.Builder().putLong(KEY_ROW_ID, attachmentId.id) .putBoolean(KEY_FORCE_V2, forceV2) .serialize(); } @@ -127,7 +125,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob { } long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.uploadTimestamp; - if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.location)) { + if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.remoteLocation)) { Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping."); return; } else if (databaseAttachment.uploadTimestamp > 0) { @@ -276,7 +274,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob { public @NonNull LegacyAttachmentUploadJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) { JsonJobData data = JsonJobData.deserialize(serializedData); - return new LegacyAttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), data.getBooleanOrDefault(KEY_FORCE_V2, false)); + return new LegacyAttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID)), data.getBooleanOrDefault(KEY_FORCE_V2, false)); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java index a1fde86a7d..f13cfa2390 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -262,19 +262,19 @@ public abstract class PushSendJob extends SendJob { } protected @Nullable SignalServiceAttachment getAttachmentPointerFor(Attachment attachment) { - if (TextUtils.isEmpty(attachment.location)) { + if (TextUtils.isEmpty(attachment.remoteLocation)) { Log.w(TAG, "empty content id"); return null; } - if (TextUtils.isEmpty(attachment.key)) { + if (TextUtils.isEmpty(attachment.remoteKey)) { Log.w(TAG, "empty encrypted key"); return null; } try { - final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.location); - final byte[] key = Base64.decode(attachment.key); + final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.remoteLocation); + final byte[] key = Base64.decode(attachment.remoteKey); int width = attachment.width; int height = attachment.height; @@ -296,7 +296,7 @@ public abstract class PushSendJob extends SendJob { Optional.empty(), width, height, - Optional.ofNullable(attachment.digest), + Optional.ofNullable(attachment.remoteDigest), Optional.ofNullable(attachment.getIncrementalDigest()), attachment.incrementalMacChunkSize, Optional.ofNullable(attachment.fileName), diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewRepository.kt index 496deaccf9..feb9741bdd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewRepository.kt @@ -47,9 +47,7 @@ class MediaPreviewRepository { val mediaRecords = mutableListOf() var startingRow = -1 while (cursor.moveToNext()) { - if (startingAttachmentId.rowId == cursor.requireLong(AttachmentTable.ROW_ID) && - startingAttachmentId.uniqueId == cursor.requireLong(AttachmentTable.UNIQUE_ID) - ) { + if (startingAttachmentId.id == cursor.requireLong(AttachmentTable.ID)) { startingRow = cursor.position break } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java index 96a8c8fbf4..74b399786e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java @@ -54,7 +54,7 @@ public class PartAuthority { static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - uriMatcher.addURI(AUTHORITY, "part/*/#", PART_ROW); + uriMatcher.addURI(AUTHORITY, "part/#", PART_ROW); uriMatcher.addURI(AUTHORITY, "sticker/#", STICKER_ROW); uriMatcher.addURI(AUTHORITY, "wallpaper/*", WALLPAPER_ROW); uriMatcher.addURI(AUTHORITY, "emoji/*", EMOJI_ROW); @@ -174,8 +174,7 @@ public class PartAuthority { } public static Uri getAttachmentDataUri(AttachmentId attachmentId) { - Uri uri = Uri.withAppendedPath(PART_CONTENT_URI, String.valueOf(attachmentId.getUniqueId())); - return ContentUris.withAppendedId(uri, attachmentId.getRowId()); + return ContentUris.withAppendedId(PART_CONTENT_URI, attachmentId.id); } public static Uri getAttachmentThumbnailUri(AttachmentId attachmentId) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/PartUriParser.java b/app/src/main/java/org/thoughtcrime/securesms/mms/PartUriParser.java index ca22393265..a750b0892a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PartUriParser.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PartUriParser.java @@ -14,7 +14,7 @@ public class PartUriParser { } public AttachmentId getPartId() { - return new AttachmentId(getId(), getUniqueId()); + return new AttachmentId(getId()); } private long getId() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java index e8f8ccc464..58d98693c8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java @@ -78,8 +78,7 @@ public final class PartProvider extends BaseContentProvider { } public static Uri getContentUri(AttachmentId attachmentId) { - Uri uri = Uri.withAppendedPath(CONTENT_URI, String.valueOf(attachmentId.getUniqueId())); - return ContentUris.withAppendedId(uri, attachmentId.getRowId()); + return ContentUris.withAppendedId(CONTENT_URI, attachmentId.id); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java index 47e03bc6b4..c5eb0bc67f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java @@ -723,7 +723,7 @@ public class MessageSender { @Override public @NonNull String toString() { - return "{ID: " + attachmentId.getRowId() + ", URI: " + media.getUri() + ", Jobs: " + jobIds.stream().map(j -> "JOB::" + j).collect(Collectors.toList()) + "}"; + return "{ID: " + attachmentId.id + ", URI: " + media.getUri() + ", Jobs: " + jobIds.stream().map(j -> "JOB::" + j).collect(Collectors.toList()) + "}"; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java index 7d50d14aa2..5ba14edc59 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java @@ -58,14 +58,14 @@ class PartDataSource implements DataSource { final boolean hasIncrementalDigest = attachment.getIncrementalDigest() != null; final boolean inProgress = attachment.isInProgress(); - final String attachmentKey = attachment.key; + final String attachmentKey = attachment.remoteKey; 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.attachmentId); try { - this.inputStream = AttachmentCipherInputStream.createForAttachment(transferFile, attachment.size, decode, attachment.digest, attachment.getIncrementalDigest(), attachment.incrementalMacChunkSize); + this.inputStream = AttachmentCipherInputStream.createForAttachment(transferFile, attachment.size, decode, attachment.remoteDigest, attachment.getIncrementalDigest(), attachment.incrementalMacChunkSize); long skipped = 0; while (skipped < dataSpec.position) { diff --git a/app/src/main/protowire/JobData.proto b/app/src/main/protowire/JobData.proto index 6503ce3c12..c048c958d6 100644 --- a/app/src/main/protowire/JobData.proto +++ b/app/src/main/protowire/JobData.proto @@ -33,7 +33,7 @@ message CallLinkUpdateSendJobData { } message AttachmentUploadJobData { - uint64 attachmentRowId = 1; - uint64 attachmentUniqueId = 2; + uint64 attachmentId = 1; + reserved /*attachmentUniqueId*/ 2; optional ResumableUpload uploadSpec = 3; } \ No newline at end of file diff --git a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt index 0528f11d8a..6cc5d63d4e 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt @@ -214,7 +214,7 @@ class UploadDependencyGraphTest { val uploadData = AttachmentUploadJobData.ADAPTER.decode(steps[1][0].serialize()!!) val copyData = JsonJobData.deserialize(steps[2][0].serialize()) - val uploadAttachmentId = AttachmentId(uploadData.attachmentRowId, uploadData.attachmentUniqueId) + val uploadAttachmentId = AttachmentId(uploadData.attachmentId) val copySourceAttachmentId = JsonUtils.fromJson(copyData.getString("source_id"), AttachmentId::class.java) assertEquals(uploadAttachmentId, copySourceAttachmentId) @@ -228,7 +228,7 @@ class UploadDependencyGraphTest { private fun getAttachmentForPreUpload(id: Long, attachment: Attachment): DatabaseAttachment { return DatabaseAttachment( - attachmentId = AttachmentId(id, id), + attachmentId = AttachmentId(id), mmsId = AttachmentTable.PREUPLOAD_MESSAGE_ID, hasData = false, hasThumbnail = false, @@ -237,10 +237,9 @@ class UploadDependencyGraphTest { size = attachment.size, fileName = attachment.fileName, cdnNumber = attachment.cdnNumber, - location = attachment.location, - key = attachment.key, - relay = attachment.relay, - digest = attachment.digest, + location = attachment.remoteLocation, + key = attachment.remoteKey, + digest = attachment.remoteDigest, incrementalDigest = attachment.incrementalDigest, incrementalMacChunkSize = attachment.incrementalMacChunkSize, fastPreflightId = attachment.fastPreflightId, diff --git a/app/src/test/java/org/thoughtcrime/securesms/stories/StoriesTest.kt b/app/src/test/java/org/thoughtcrime/securesms/stories/StoriesTest.kt index b2118cef61..b5599ab43d 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/stories/StoriesTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/stories/StoriesTest.kt @@ -84,7 +84,7 @@ class StoriesTest { val messageRecord = FakeMessageRecords.buildMediaMmsMessageRecord( linkPreviews = listOf( FakeMessageRecords.buildLinkPreview( - attachmentId = AttachmentId(1, 2) + attachmentId = AttachmentId(1) ) ) ) diff --git a/app/src/test/java/org/thoughtcrime/securesms/stories/dialogs/StoryContextMenuTest.kt b/app/src/test/java/org/thoughtcrime/securesms/stories/dialogs/StoryContextMenuTest.kt index d74edc94d7..7da235b9b7 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/stories/dialogs/StoryContextMenuTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/stories/dialogs/StoryContextMenuTest.kt @@ -42,7 +42,7 @@ class StoryContextMenuTest { @Test fun `Given a story with an attachment, when I share, then I expect the correct stream, type, and flag`() { // GIVEN - val attachmentId = AttachmentId(1, 2) + val attachmentId = AttachmentId(1) val storyRecord = FakeMessageRecords.buildMediaMmsMessageRecord( storyType = StoryType.STORY_WITH_REPLIES, slideDeck = SlideDeck().apply { diff --git a/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt b/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt index 5134ffbebc..a0fac5dcb3 100644 --- a/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt +++ b/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt @@ -27,7 +27,7 @@ import org.thoughtcrime.securesms.util.MediaUtil object FakeMessageRecords { fun buildDatabaseAttachment( - attachmentId: AttachmentId = AttachmentId(1, 1), + attachmentId: AttachmentId = AttachmentId(1), mmsId: Long = 1, hasData: Boolean = true, hasThumbnail: Boolean = true, @@ -69,7 +69,6 @@ object FakeMessageRecords { cdnNumber, location, key, - relay, digest, incrementalDigest, incrementalMacChunkSize,