diff --git a/src/org/thoughtcrime/securesms/attachments/Attachment.java b/src/org/thoughtcrime/securesms/attachments/Attachment.java index 6f1f41bade..cfde38ba91 100644 --- a/src/org/thoughtcrime/securesms/attachments/Attachment.java +++ b/src/org/thoughtcrime/securesms/attachments/Attachment.java @@ -6,6 +6,7 @@ import androidx.annotation.Nullable; import org.thoughtcrime.securesms.blurhash.BlurHash; import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.database.AttachmentDatabase.TransformProperties; import org.thoughtcrime.securesms.stickers.StickerLocator; public abstract class Attachment { @@ -48,28 +49,32 @@ public abstract class Attachment { @Nullable private final BlurHash blurHash; + @NonNull + private final TransformProperties transformProperties; + public Attachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName, @Nullable String location, @Nullable String key, @Nullable String relay, @Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote, int width, int height, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator, - @Nullable BlurHash blurHash) + @Nullable BlurHash blurHash, @Nullable TransformProperties transformProperties) { - this.contentType = contentType; - this.transferState = transferState; - this.size = size; - this.fileName = fileName; - this.location = location; - this.key = key; - this.relay = relay; - this.digest = digest; - this.fastPreflightId = fastPreflightId; - this.voiceNote = voiceNote; - this.width = width; - this.height = height; - this.quote = quote; - this.stickerLocator = stickerLocator; - this.caption = caption; - this.blurHash = blurHash; + this.contentType = contentType; + this.transferState = transferState; + this.size = size; + this.fileName = fileName; + this.location = location; + this.key = key; + this.relay = relay; + this.digest = digest; + this.fastPreflightId = fastPreflightId; + this.voiceNote = voiceNote; + this.width = width; + this.height = height; + this.quote = quote; + this.stickerLocator = stickerLocator; + this.caption = caption; + this.blurHash = blurHash; + this.transformProperties = transformProperties != null ? transformProperties : TransformProperties.empty(); } @Nullable @@ -157,4 +162,8 @@ public abstract class Attachment { public @Nullable String getCaption() { return caption; } + + public @NonNull TransformProperties getTransformProperties() { + return transformProperties; + } } diff --git a/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java b/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java index cd82a28933..c2b03bc055 100644 --- a/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java @@ -6,6 +6,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.thoughtcrime.securesms.blurhash.BlurHash; +import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.database.AttachmentDatabase.TransformProperties; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.stickers.StickerLocator; @@ -22,9 +24,10 @@ public class DatabaseAttachment extends Attachment { String fileName, String location, String key, String relay, byte[] digest, String fastPreflightId, boolean voiceNote, int width, int height, boolean quote, @Nullable String caption, - @Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash) + @Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash, + @Nullable TransformProperties transformProperties) { - super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, blurHash); + super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, blurHash, transformProperties); this.attachmentId = attachmentId; this.hasData = hasData; this.hasThumbnail = hasThumbnail; diff --git a/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java b/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java index bd16517bf0..a066b8e6d6 100644 --- a/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java @@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.database.MmsDatabase; public class MmsNotificationAttachment extends Attachment { public MmsNotificationAttachment(int status, long size) { - super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false, null, null, null); + super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false, null, null, null, null); } @Nullable diff --git a/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java b/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java index 38eff818cb..b0eb0cf33c 100644 --- a/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java @@ -24,7 +24,7 @@ public class PointerAttachment extends Attachment { int width, int height, @Nullable String caption, @Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash) { - super(contentType, transferState, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, false, caption, stickerLocator, blurHash); + super(contentType, transferState, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, false, caption, stickerLocator, blurHash, null); } @Nullable diff --git a/src/org/thoughtcrime/securesms/attachments/TombstoneAttachment.java b/src/org/thoughtcrime/securesms/attachments/TombstoneAttachment.java index e7f13377cc..7791d2ebdd 100644 --- a/src/org/thoughtcrime/securesms/attachments/TombstoneAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/TombstoneAttachment.java @@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase; public class TombstoneAttachment extends Attachment { public TombstoneAttachment(@NonNull String contentType, boolean quote) { - super(contentType, AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0, null, null, null, null, null, null, false, 0, 0, quote, null, null, null); + super(contentType, AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0, null, null, null, null, null, null, false, 0, 0, quote, null, null, null, null); } @Override diff --git a/src/org/thoughtcrime/securesms/attachments/UriAttachment.java b/src/org/thoughtcrime/securesms/attachments/UriAttachment.java index bdf14e405f..86aa5b8180 100644 --- a/src/org/thoughtcrime/securesms/attachments/UriAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/UriAttachment.java @@ -5,6 +5,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.thoughtcrime.securesms.blurhash.BlurHash; +import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.database.AttachmentDatabase.TransformProperties; import org.thoughtcrime.securesms.stickers.StickerLocator; public class UriAttachment extends Attachment { @@ -14,18 +16,18 @@ public class UriAttachment extends Attachment { public UriAttachment(@NonNull Uri uri, @NonNull String contentType, int transferState, long size, @Nullable String fileName, boolean voiceNote, boolean quote, @Nullable String caption, - @Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash) + @Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash, @Nullable TransformProperties transformProperties) { - this(uri, uri, contentType, transferState, size, 0, 0, fileName, null, voiceNote, quote, caption, stickerLocator, blurHash); + this(uri, uri, contentType, transferState, size, 0, 0, fileName, null, voiceNote, quote, caption, stickerLocator, blurHash, transformProperties); } public UriAttachment(@NonNull Uri dataUri, @Nullable Uri thumbnailUri, @NonNull String contentType, int transferState, long size, int width, int height, @Nullable String fileName, @Nullable String fastPreflightId, boolean voiceNote, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator, - @Nullable BlurHash blurHash) + @Nullable BlurHash blurHash, @Nullable TransformProperties transformProperties) { - super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, blurHash); + super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, blurHash, transformProperties); this.dataUri = dataUri; this.thumbnailUri = thumbnailUri; } diff --git a/src/org/thoughtcrime/securesms/contactshare/Contact.java b/src/org/thoughtcrime/securesms/contactshare/Contact.java index d33922db42..aef1fdf4c8 100644 --- a/src/org/thoughtcrime/securesms/contactshare/Contact.java +++ b/src/org/thoughtcrime/securesms/contactshare/Contact.java @@ -643,7 +643,7 @@ public class Contact implements Parcelable { private static Attachment attachmentFromUri(@Nullable Uri uri) { if (uri == null) return null; - return new UriAttachment(uri, MediaUtil.IMAGE_JPEG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0, null, false, false, null, null, null); + return new UriAttachment(uri, MediaUtil.IMAGE_JPEG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0, null, false, false, null, null, null, null); } @Override diff --git a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 1d04749083..794a141482 100644 --- a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -33,6 +33,7 @@ import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; import com.bumptech.glide.Glide; +import com.fasterxml.jackson.annotation.JsonProperty; import net.sqlcipher.DatabaseUtils; import net.sqlcipher.database.SQLiteDatabase; @@ -64,6 +65,7 @@ import org.thoughtcrime.securesms.util.StorageUtil; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.video.EncryptedMediaDataSource; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.internal.util.JsonUtil; import java.io.File; import java.io.FileNotFoundException; @@ -115,6 +117,7 @@ public class AttachmentDatabase extends Database { static final String CAPTION = "caption"; private static final String DATA_HASH = "data_hash"; static final String BLUR_HASH = "blur_hash"; + static final String TRANSFORM_PROPERTIES = "transform_properties"; public static final String DIRECTORY = "parts"; @@ -133,7 +136,7 @@ public class AttachmentDatabase extends Database { UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE, QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT, CAPTION, STICKER_PACK_ID, STICKER_PACK_KEY, STICKER_ID, - DATA_HASH, BLUR_HASH}; + DATA_HASH, BLUR_HASH, TRANSFORM_PROPERTIES}; public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " + MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " + @@ -148,7 +151,8 @@ public class AttachmentDatabase extends Database { 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, " + - DATA_HASH + " TEXT DEFAULT NULL, " + BLUR_HASH + " TEXT DEFAULT NULL);"; + DATA_HASH + " TEXT DEFAULT NULL, " + BLUR_HASH + " TEXT DEFAULT NULL, " + + TRANSFORM_PROPERTIES + " TEXT DEFAULT NULL);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");", @@ -586,14 +590,37 @@ public class AttachmentDatabase extends Database { contentValues.put(DATA_RANDOM, dataInfo.random); contentValues.put(DATA_HASH, dataInfo.hash); + int updateCount = updateAttachmentAndMatchingHashes(database, databaseAttachment.getAttachmentId(), dataInfo.hash, contentValues); + Log.i(TAG, "[updateAttachmentData] Updated " + updateCount + " rows."); + } + + public void markAttachmentAsTransformed(@NonNull AttachmentId attachmentId) { + DataInfo dataInfo = getAttachmentDataFileInfo(attachmentId, DATA); + + if (dataInfo == null) { + Log.w(TAG, "[markAttachmentAsTransformed] No data info found!"); + return; + } + + ContentValues contentValues = new ContentValues(); + contentValues.put(TRANSFORM_PROPERTIES, TransformProperties.forSkipTransform().serialize()); + + int updateCount = updateAttachmentAndMatchingHashes(databaseHelper.getWritableDatabase(), attachmentId, dataInfo.hash, contentValues); + Log.i(TAG, "[markAttachmentAsTransformed] Updated " + updateCount + " rows."); + } + + private static int updateAttachmentAndMatchingHashes(@NonNull SQLiteDatabase database, + @NonNull AttachmentId attachmentId, + @Nullable String dataHash, + @NonNull ContentValues contentValues) + { String selection = "(" + ROW_ID + " = ? AND " + UNIQUE_ID + " = ?) OR " + "(" + DATA_HASH + " NOT NULL AND " + DATA_HASH + " = ?)"; - String[] args = new String[]{String.valueOf(databaseAttachment.getAttachmentId().getRowId()), - String.valueOf(databaseAttachment.getAttachmentId().getUniqueId()), - oldDataInfo.hash}; + String[] args = new String[]{String.valueOf(attachmentId.getRowId()), + String.valueOf(attachmentId.getUniqueId()), + String.valueOf(dataHash)}; - int updateCount = database.update(TABLE_NAME, contentValues, selection, args); - Log.i(TAG, "[updateAttachmentData] Updated " + updateCount + " rows."); + return database.update(TABLE_NAME, contentValues, selection, args); } private static void updateAttachmentDataHash(@NonNull SQLiteDatabase database, @@ -723,14 +750,14 @@ public class AttachmentDatabase extends Database { null, null, null); if (cursor != null && cursor.moveToFirst()) { - if (cursor.isNull(0)) { + if (cursor.isNull(cursor.getColumnIndexOrThrow(dataType))) { return null; } - return new DataInfo(new File(cursor.getString(0)), - cursor.getLong(1), - cursor.getBlob(2), - cursor.getString(3)); + return new DataInfo(new File(cursor.getString(cursor.getColumnIndexOrThrow(dataType))), + cursor.getLong(cursor.getColumnIndexOrThrow(SIZE)), + cursor.getBlob(cursor.getColumnIndexOrThrow(randomColumn)), + cursor.getString(cursor.getColumnIndexOrThrow(DATA_HASH))); } else { return null; } @@ -886,7 +913,8 @@ public class AttachmentDatabase extends Database { object.getString(STICKER_PACK_KEY), object.getInt(STICKER_ID)) : null, - BlurHash.parseOrNull(object.getString(BLUR_HASH)))); + BlurHash.parseOrNull(object.getString(BLUR_HASH)), + TransformProperties.parse(object.getString(TRANSFORM_PROPERTIES)))); } } @@ -916,7 +944,8 @@ public class AttachmentDatabase extends Database { cursor.getString(cursor.getColumnIndexOrThrow(STICKER_PACK_KEY)), cursor.getInt(cursor.getColumnIndexOrThrow(STICKER_ID))) : null, - BlurHash.parseOrNull(cursor.getString(cursor.getColumnIndex(BLUR_HASH))))); + BlurHash.parseOrNull(cursor.getString(cursor.getColumnIndexOrThrow(BLUR_HASH))), + TransformProperties.parse(cursor.getString(cursor.getColumnIndexOrThrow(TRANSFORM_PROPERTIES))))); } } catch (JSONException e) { throw new AssertionError(e); @@ -938,9 +967,20 @@ public class AttachmentDatabase extends Database { Log.d(TAG, "Wrote part to file: " + dataInfo.file.getAbsolutePath()); } + Attachment template = attachment; + + if (dataInfo != null && dataInfo.hash != null) { + Attachment possibleTemplate = findTemplateAttachment(dataInfo.hash); + + if (possibleTemplate != null) { + Log.i(TAG, "Found a duplicate attachment upon insertion. Using it as a template."); + template = possibleTemplate; + } + } + ContentValues contentValues = new ContentValues(); contentValues.put(MMS_ID, mmsId); - contentValues.put(CONTENT_TYPE, attachment.getContentType()); + contentValues.put(CONTENT_TYPE, template.getContentType()); contentValues.put(TRANSFER_STATE, attachment.getTransferState()); contentValues.put(UNIQUE_ID, uniqueId); contentValues.put(CONTENT_LOCATION, attachment.getLocation()); @@ -948,14 +988,15 @@ public class AttachmentDatabase extends Database { contentValues.put(CONTENT_DISPOSITION, attachment.getKey()); contentValues.put(NAME, attachment.getRelay()); contentValues.put(FILE_NAME, StorageUtil.getCleanFileName(attachment.getFileName())); - contentValues.put(SIZE, attachment.getSize()); + contentValues.put(SIZE, template.getSize()); contentValues.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId()); contentValues.put(VOICE_NOTE, attachment.isVoiceNote() ? 1 : 0); - contentValues.put(WIDTH, attachment.getWidth()); - contentValues.put(HEIGHT, attachment.getHeight()); + contentValues.put(WIDTH, template.getWidth()); + contentValues.put(HEIGHT, template.getHeight()); contentValues.put(QUOTE, quote); contentValues.put(CAPTION, attachment.getCaption()); contentValues.put(BLUR_HASH, getBlurHashStringOrNull(attachment.getBlurHash())); + contentValues.put(TRANSFORM_PROPERTIES, template.getTransformProperties().serialize()); if (attachment.isSticker()) { contentValues.put(STICKER_PACK_ID, attachment.getSticker().getPackId()); @@ -1013,6 +1054,19 @@ public class AttachmentDatabase extends Database { return attachmentId; } + private @Nullable DatabaseAttachment findTemplateAttachment(@NonNull String dataHash) { + String selection = DATA_HASH + " = ?"; + String[] args = new String[] { dataHash }; + + try (Cursor cursor = databaseHelper.getWritableDatabase().query(TABLE_NAME, null, selection, args, null, null, null)) { + if (cursor != null && cursor.moveToFirst()) { + return getAttachment(cursor).get(0); + } + } + + return null; + } + @SuppressWarnings("WeakerAccess") @VisibleForTesting protected void updateAttachmentThumbnail(AttachmentId attachmentId, InputStream in, float aspectRatio) @@ -1121,10 +1175,47 @@ public class AttachmentDatabase extends Database { private final String hash; private DataInfo(File file, long length, byte[] random, String hash) { - this.file = file; + this.file = file; this.length = length; this.random = random; - this.hash = hash; + this.hash = hash; + } + } + public static final class TransformProperties { + + @JsonProperty private final boolean skipTransform; + + public TransformProperties(@JsonProperty("skipTransform") boolean skipTransform) { + this.skipTransform = skipTransform; + } + + public static @NonNull TransformProperties empty() { + return new TransformProperties(false); + } + + public static @NonNull TransformProperties forSkipTransform() { + return new TransformProperties(true); + } + + public boolean shouldSkipTransform() { + return skipTransform; + } + + @NonNull String serialize() { + return JsonUtil.toJson(this); + } + + static @NonNull TransformProperties parse(@Nullable String serialized) { + if (serialized == null) { + return empty(); + } + + try { + return JsonUtil.fromJson(serialized, TransformProperties.class); + } catch (IOException e) { + Log.w(TAG, "Failed to parse TransformProperties!", e); + return empty(); + } } } } diff --git a/src/org/thoughtcrime/securesms/database/MediaDatabase.java b/src/org/thoughtcrime/securesms/database/MediaDatabase.java index 090da9329b..ac2f447e71 100644 --- a/src/org/thoughtcrime/securesms/database/MediaDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MediaDatabase.java @@ -38,6 +38,7 @@ public class MediaDatabase extends Database { + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_PACK_KEY + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_ID + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + ", " + + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFORM_PROPERTIES + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CAPTION + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", " diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 4464556219..2e20582efb 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -175,7 +175,8 @@ public class MmsDatabase extends MessagingDatabase { "'" + AttachmentDatabase.STICKER_PACK_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_PACK_ID+ ", " + "'" + AttachmentDatabase.STICKER_PACK_KEY + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_PACK_KEY + ", " + "'" + AttachmentDatabase.STICKER_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_ID + ", " + - "'" + AttachmentDatabase.BLUR_HASH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + + "'" + AttachmentDatabase.BLUR_HASH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + ", " + + "'" + AttachmentDatabase.TRANSFORM_PROPERTIES + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFORM_PROPERTIES + ")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS, }; @@ -797,7 +798,8 @@ public class MmsDatabase extends MessagingDatabase { databaseAttachment.isQuote(), databaseAttachment.getCaption(), databaseAttachment.getSticker(), - databaseAttachment.getBlurHash())); + databaseAttachment.getBlurHash(), + databaseAttachment.getTransformProperties())); } return insertMediaMessage(request.getBody(), diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 56908887ae..dc4582421b 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -256,7 +256,8 @@ public class MmsSmsDatabase extends Database { "'" + AttachmentDatabase.STICKER_PACK_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_PACK_ID + ", " + "'" + AttachmentDatabase.STICKER_PACK_KEY + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_PACK_KEY + ", " + "'" + AttachmentDatabase.STICKER_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_ID + ", " + - "'" + AttachmentDatabase.BLUR_HASH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + + "'" + AttachmentDatabase.BLUR_HASH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + ", " + + "'" + AttachmentDatabase.TRANSFORM_PROPERTIES + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFORM_PROPERTIES + ")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS, SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID, SmsDatabase.TYPE, SmsDatabase.RECIPIENT_ID, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE, diff --git a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 867db0d96f..3c4fe6176c 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -86,8 +86,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int NOTIFICATION_RECIPIENT_IDS = 29; private static final int BLUR_HASH = 30; private static final int MMS_RECIPIENT_CLEANUP_2 = 31; + private static final int ATTACHMENT_TRANSFORM_PROPERTIES = 32; - private static final int DATABASE_VERSION = 31; + private static final int DATABASE_VERSION = 32; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -597,6 +598,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { Log.i(TAG, "MMS recipient cleanup 2 updated " + count + " rows."); } + if (oldVersion < ATTACHMENT_TRANSFORM_PROPERTIES) { + db.execSQL("ALTER TABLE part ADD COLUMN transform_properties TEXT DEFAULT NULL"); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/src/org/thoughtcrime/securesms/groups/V1GroupManager.java b/src/org/thoughtcrime/securesms/groups/V1GroupManager.java index 8462476b36..45d6f1c272 100644 --- a/src/org/thoughtcrime/securesms/groups/V1GroupManager.java +++ b/src/org/thoughtcrime/securesms/groups/V1GroupManager.java @@ -112,7 +112,7 @@ final class V1GroupManager { if (avatar != null) { Uri avatarUri = BlobProvider.getInstance().forData(avatar).createForSingleUseInMemory(); - avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false, null, null, null); + avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false, null, null, null, null); } OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, System.currentTimeMillis(), 0, false, null, Collections.emptyList(), Collections.emptyList()); diff --git a/src/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java b/src/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java index d5392daf3a..826e12d146 100644 --- a/src/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java +++ b/src/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java @@ -115,6 +115,11 @@ public final class AttachmentCompressionJob extends BaseJob { throw new UndeliverableMessageException("Cannot find the specified attachment."); } + if (databaseAttachment.getTransformProperties().shouldSkipTransform()) { + Log.i(TAG, "Skipping at the direction of the TransformProperties."); + return; + } + MediaConstraints mediaConstraints = mms ? MediaConstraints.getMmsMediaConstraints(mmsSubscriptionId) : MediaConstraints.getPushMediaConstraints(); @@ -141,10 +146,12 @@ public final class AttachmentCompressionJob extends BaseJob { if (MediaUtil.isJpeg(attachment)) { MediaStream stripped = getResizedMedia(context, attachment, constraints); attachmentDatabase.updateAttachmentData(attachment, stripped); + attachmentDatabase.markAttachmentAsTransformed(attachmentId); } } else if (constraints.canResize(attachment)) { MediaStream resized = getResizedMedia(context, attachment, constraints); attachmentDatabase.updateAttachmentData(attachment, resized); + attachmentDatabase.markAttachmentAsTransformed(attachmentId); } else { throw new UndeliverableMessageException("Size constraints could not be met!"); } @@ -184,6 +191,7 @@ public final class AttachmentCompressionJob extends BaseJob { }); attachmentDatabase.updateAttachmentData(attachment, mediaStream); + attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId()); } } } diff --git a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java index 5ed05c0004..7741556fed 100644 --- a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java @@ -230,7 +230,7 @@ public class MmsDownloadJob extends BaseJob { attachments.add(new UriAttachment(uri, Util.toIsoString(part.getContentType()), AttachmentDatabase.TRANSFER_PROGRESS_DONE, - part.getData().length, name, false, false, null, null, null)); + part.getData().length, name, false, false, null, null, null, null)); } } } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 32b5ea8f46..c2cb8c669f 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -1252,6 +1252,7 @@ public class PushDecryptJob extends BaseJob { false, null, stickerLocator, + null, null)); } else { return Optional.of(PointerAttachment.forPointer(Optional.of(sticker.get().getAttachment()), stickerLocator).get()); diff --git a/src/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/src/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index d0d783f73a..26c3f7dd40 100644 --- a/src/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/src/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -176,6 +176,7 @@ public class LinkPreviewRepository { false, null, null, + null, null)); callback.onComplete(thumbnail); @@ -249,6 +250,7 @@ public class LinkPreviewRepository { false, null, null, + null, null)); callback.onComplete(Optional.of(new LinkPreview(packUrl, title, thumbnail))); diff --git a/src/org/thoughtcrime/securesms/mms/AudioSlide.java b/src/org/thoughtcrime/securesms/mms/AudioSlide.java index ba2531d6fd..7f36a20e21 100644 --- a/src/org/thoughtcrime/securesms/mms/AudioSlide.java +++ b/src/org/thoughtcrime/securesms/mms/AudioSlide.java @@ -39,7 +39,7 @@ public class AudioSlide extends Slide { } public AudioSlide(Context context, Uri uri, long dataSize, String contentType, boolean voiceNote) { - super(context, new UriAttachment(uri, null, contentType, AttachmentDatabase.TRANSFER_PROGRESS_STARTED, dataSize, 0, 0, null, null, voiceNote, false, null, null, null)); + super(context, new UriAttachment(uri, null, contentType, AttachmentDatabase.TRANSFER_PROGRESS_STARTED, dataSize, 0, 0, null, null, voiceNote, false, null, null, null, null)); } public AudioSlide(Context context, Attachment attachment) { diff --git a/src/org/thoughtcrime/securesms/mms/Slide.java b/src/org/thoughtcrime/securesms/mms/Slide.java index 7346f670f2..cca1ffae10 100644 --- a/src/org/thoughtcrime/securesms/mms/Slide.java +++ b/src/org/thoughtcrime/securesms/mms/Slide.java @@ -168,7 +168,8 @@ public abstract class Slide { quote, caption, stickerLocator, - blurHash); + blurHash, + null); } @Override