From 9f8b4cf8923c4cd461a7aa024c39faf6e3f111b4 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sun, 18 Mar 2018 16:04:33 -0700 Subject: [PATCH] Populate incoming attachments with width and height from message --- .../securesms/CreateProfileActivity.java | 3 +- .../securesms/attachments/Attachment.java | 15 +++++++++- .../attachments/DatabaseAttachment.java | 5 ++-- .../MmsNotificationAttachment.java | 2 +- .../attachments/PointerAttachment.java | 9 ++++-- .../securesms/attachments/UriAttachment.java | 2 +- .../database/AttachmentDatabase.java | 19 +++++++++--- .../securesms/database/MediaDatabase.java | 2 ++ .../securesms/database/MmsDatabase.java | 6 +++- .../securesms/database/MmsSmsDatabase.java | 8 +++++ .../database/helpers/SQLCipherOpenHelper.java | 8 ++++- .../securesms/jobs/PushSendJob.java | 9 ++---- .../securesms/mms/MediaConstraints.java | 4 +-- .../securesms/mms/MediaStream.java | 14 ++++++++- .../securesms/profiles/SystemProfileUtil.java | 3 +- .../securesms/util/BitmapUtil.java | 30 +++++++++++++++++-- 16 files changed, 111 insertions(+), 28 deletions(-) diff --git a/src/org/thoughtcrime/securesms/CreateProfileActivity.java b/src/org/thoughtcrime/securesms/CreateProfileActivity.java index 16169753b5..8d7904d5ed 100644 --- a/src/org/thoughtcrime/securesms/CreateProfileActivity.java +++ b/src/org/thoughtcrime/securesms/CreateProfileActivity.java @@ -175,7 +175,8 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje @Override protected byte[] doInBackground(Void... params) { try { - return BitmapUtil.createScaledBytes(CreateProfileActivity.this, Crop.getOutput(data), new ProfileMediaConstraints()); + BitmapUtil.ScaleResult result = BitmapUtil.createScaledBytes(CreateProfileActivity.this, Crop.getOutput(data), new ProfileMediaConstraints()); + return result.getBitmap(); } catch (BitmapDecodingException e) { Log.w(TAG, e); return null; diff --git a/src/org/thoughtcrime/securesms/attachments/Attachment.java b/src/org/thoughtcrime/securesms/attachments/Attachment.java index 3f0a822f36..13cbe0d6f6 100644 --- a/src/org/thoughtcrime/securesms/attachments/Attachment.java +++ b/src/org/thoughtcrime/securesms/attachments/Attachment.java @@ -32,10 +32,13 @@ public abstract class Attachment { private final String fastPreflightId; private final boolean voiceNote; + private final int width; + private final int height; 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) + @Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote, + int width, int height) { this.contentType = contentType; this.transferState = transferState; @@ -47,6 +50,8 @@ public abstract class Attachment { this.digest = digest; this.fastPreflightId = fastPreflightId; this.voiceNote = voiceNote; + this.width = width; + this.height = height; } @Nullable @@ -106,4 +111,12 @@ public abstract class Attachment { public boolean isVoiceNote() { return voiceNote; } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } } diff --git a/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java b/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java index b24904bbfc..f06347a24d 100644 --- a/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/DatabaseAttachment.java @@ -16,9 +16,10 @@ public class DatabaseAttachment extends Attachment { boolean hasData, boolean hasThumbnail, String contentType, int transferProgress, long size, String fileName, String location, String key, String relay, - byte[] digest, String fastPreflightId, boolean voiceNote) + byte[] digest, String fastPreflightId, boolean voiceNote, + int width, int height) { - super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote); + super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height); 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 46dbaaf401..0801a24d6d 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); + super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0); } @Nullable diff --git a/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java b/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java index bf5269e58b..9cf930535d 100644 --- a/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/PointerAttachment.java @@ -17,9 +17,10 @@ public class PointerAttachment extends Attachment { private PointerAttachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName, @NonNull String location, @NonNull String key, @NonNull String relay, - @Nullable byte[] digest, boolean voiceNote) + @Nullable byte[] digest, boolean voiceNote, + int width, int height) { - super(contentType, transferState, size, fileName, location, key, relay, digest, null, voiceNote); + super(contentType, transferState, size, fileName, location, key, relay, digest, null, voiceNote, width, height); } @Nullable @@ -50,7 +51,9 @@ public class PointerAttachment extends Attachment { String.valueOf(pointer.asPointer().getId()), encodedKey, pointer.asPointer().getRelay().orNull(), pointer.asPointer().getDigest().orNull(), - pointer.asPointer().getVoiceNote())); + pointer.asPointer().getVoiceNote(), + pointer.asPointer().getWidth(), + pointer.asPointer().getHeight())); } } } diff --git a/src/org/thoughtcrime/securesms/attachments/UriAttachment.java b/src/org/thoughtcrime/securesms/attachments/UriAttachment.java index 9ae5b9adab..4511563303 100644 --- a/src/org/thoughtcrime/securesms/attachments/UriAttachment.java +++ b/src/org/thoughtcrime/securesms/attachments/UriAttachment.java @@ -20,7 +20,7 @@ public class UriAttachment extends Attachment { @Nullable String fileName, @Nullable String fastPreflightId, boolean voiceNote) { - super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote); + super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, 0, 0); this.dataUri = dataUri; this.thumbnailUri = thumbnailUri; } diff --git a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 05cdf1fc3d..04f4cbab00 100644 --- a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -85,6 +85,8 @@ public class AttachmentDatabase extends Database { public static final String FAST_PREFLIGHT_ID = "fast_preflight_id"; public static final String DATA_RANDOM = "data_random"; private static final String THUMBNAIL_RANDOM = "thumbnail_random"; + static final String WIDTH = "width"; + static final String HEIGHT = "height"; public static final String DIRECTORY = "parts"; @@ -100,7 +102,7 @@ public class AttachmentDatabase extends Database { CONTENT_LOCATION, DATA, THUMBNAIL, TRANSFER_STATE, SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO, UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE, - DATA_RANDOM, THUMBNAIL_RANDOM}; + DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT}; public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " + MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " + @@ -111,7 +113,8 @@ public class AttachmentDatabase extends Database { TRANSFER_STATE + " INTEGER, "+ DATA + " TEXT, " + SIZE + " INTEGER, " + FILE_NAME + " TEXT, " + THUMBNAIL + " TEXT, " + THUMBNAIL_ASPECT_RATIO + " REAL, " + UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT, " + - VOICE_NOTE + " INTEGER DEFAULT 0, " + DATA_RANDOM + " BLOB, " + THUMBNAIL_RANDOM + " BLOB);"; + VOICE_NOTE + " INTEGER DEFAULT 0, " + DATA_RANDOM + " BLOB, " + THUMBNAIL_RANDOM + " BLOB, " + + WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");", @@ -352,6 +355,8 @@ public class AttachmentDatabase extends Database { ContentValues contentValues = new ContentValues(); contentValues.put(SIZE, dataInfo.length); contentValues.put(CONTENT_TYPE, mediaStream.getMimeType()); + contentValues.put(WIDTH, mediaStream.getWidth()); + contentValues.put(HEIGHT, mediaStream.getHeight()); contentValues.put(DATA_RANDOM, dataInfo.random); database.update(TABLE_NAME, contentValues, PART_ID_WHERE, databaseAttachment.getAttachmentId().toStrings()); @@ -369,7 +374,9 @@ public class AttachmentDatabase extends Database { databaseAttachment.getRelay(), databaseAttachment.getDigest(), databaseAttachment.getFastPreflightId(), - databaseAttachment.isVoiceNote()); + databaseAttachment.isVoiceNote(), + mediaStream.getWidth(), + mediaStream.getHeight()); } @@ -527,7 +534,9 @@ public class AttachmentDatabase extends Database { cursor.getString(cursor.getColumnIndexOrThrow(NAME)), cursor.getBlob(cursor.getColumnIndexOrThrow(DIGEST)), cursor.getString(cursor.getColumnIndexOrThrow(FAST_PREFLIGHT_ID)), - cursor.getInt(cursor.getColumnIndexOrThrow(VOICE_NOTE)) == 1); + cursor.getInt(cursor.getColumnIndexOrThrow(VOICE_NOTE)) == 1, + cursor.getInt(cursor.getColumnIndexOrThrow(WIDTH)), + cursor.getInt(cursor.getColumnIndexOrThrow(HEIGHT))); } @@ -558,6 +567,8 @@ public class AttachmentDatabase extends Database { contentValues.put(SIZE, attachment.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()); if (dataInfo != null) { contentValues.put(DATA, dataInfo.file.getAbsolutePath()); diff --git a/src/org/thoughtcrime/securesms/database/MediaDatabase.java b/src/org/thoughtcrime/securesms/database/MediaDatabase.java index e10ce75cee..6d7f136d65 100644 --- a/src/org/thoughtcrime/securesms/database/MediaDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MediaDatabase.java @@ -30,6 +30,8 @@ public class MediaDatabase extends Database { + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DIGEST + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + ", " + + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.WIDTH + ", " + + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.HEIGHT + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", " diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 577a17acd8..8f915878e4 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -135,6 +135,8 @@ public class MmsDatabase extends MessagingDatabase { AttachmentDatabase.DIGEST, AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.VOICE_NOTE, + AttachmentDatabase.WIDTH, + AttachmentDatabase.HEIGHT, AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.NAME, AttachmentDatabase.TRANSFER_STATE @@ -600,7 +602,9 @@ public class MmsDatabase extends MessagingDatabase { databaseAttachment.getRelay(), databaseAttachment.getDigest(), databaseAttachment.getFastPreflightId(), - databaseAttachment.isVoiceNote())); + databaseAttachment.isVoiceNote(), + databaseAttachment.getWidth(), + databaseAttachment.getHeight())); } return insertMediaMessage(request.getBody(), diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 476bc0893b..c1e5c4ae9a 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -72,6 +72,8 @@ public class MmsSmsDatabase extends Database { AttachmentDatabase.DIGEST, AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.VOICE_NOTE, + AttachmentDatabase.WIDTH, + AttachmentDatabase.HEIGHT, AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.NAME, AttachmentDatabase.TRANSFER_STATE}; @@ -175,6 +177,8 @@ public class MmsSmsDatabase extends Database { AttachmentDatabase.DIGEST, AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.VOICE_NOTE, + AttachmentDatabase.WIDTH, + AttachmentDatabase.HEIGHT, AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.NAME, AttachmentDatabase.TRANSFER_STATE}; @@ -207,6 +211,8 @@ public class MmsSmsDatabase extends Database { AttachmentDatabase.DIGEST, AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.VOICE_NOTE, + AttachmentDatabase.WIDTH, + AttachmentDatabase.HEIGHT, AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.NAME, AttachmentDatabase.TRANSFER_STATE}; @@ -265,6 +271,8 @@ public class MmsSmsDatabase extends Database { mmsColumnsPresent.add(AttachmentDatabase.DIGEST); mmsColumnsPresent.add(AttachmentDatabase.FAST_PREFLIGHT_ID); mmsColumnsPresent.add(AttachmentDatabase.VOICE_NOTE); + mmsColumnsPresent.add(AttachmentDatabase.WIDTH); + mmsColumnsPresent.add(AttachmentDatabase.HEIGHT); mmsColumnsPresent.add(AttachmentDatabase.CONTENT_DISPOSITION); mmsColumnsPresent.add(AttachmentDatabase.NAME); mmsColumnsPresent.add(AttachmentDatabase.TRANSFER_STATE); diff --git a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 92752a3570..b9d4303d8c 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -42,8 +42,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int MIGRATE_PREKEYS_VERSION = 3; private static final int MIGRATE_SESSIONS_VERSION = 4; private static final int NO_MORE_IMAGE_THUMBNAILS_VERSION = 5; + private static final int ATTACHMENT_DIMENSIONS = 6; - private static final int DATABASE_VERSION = 4; + private static final int DATABASE_VERSION = 6; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -161,6 +162,11 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { } } + if (oldVersion < ATTACHMENT_DIMENSIONS) { + db.execSQL("ALTER TABLE part ADD COLUMN width INTEGER DEFAULT 0"); + db.execSQL("ALTER TABLE part ADD COLUMN height INTEGER DEFAULT 0"); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java index 79d4f59055..806eadfe96 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -89,12 +89,9 @@ public abstract class PushSendJob extends SendJob { .withLength(attachment.getSize()) .withFileName(attachment.getFileName()) .withVoiceNote(attachment.isVoiceNote()) - .withListener(new ProgressListener() { - @Override - public void onAttachmentProgress(long total, long progress) { - EventBus.getDefault().postSticky(new PartProgressEvent(attachment, total, progress)); - } - }) + .withWidth(attachment.getWidth()) + .withHeight(attachment.getHeight()) + .withListener((total, progress) -> EventBus.getDefault().postSticky(new PartProgressEvent(attachment, total, progress))) .build()); } catch (IOException ioe) { Log.w(TAG, "Couldn't open attachment", ioe); diff --git a/src/org/thoughtcrime/securesms/mms/MediaConstraints.java b/src/org/thoughtcrime/securesms/mms/MediaConstraints.java index a9f46b5132..75717d96e7 100644 --- a/src/org/thoughtcrime/securesms/mms/MediaConstraints.java +++ b/src/org/thoughtcrime/securesms/mms/MediaConstraints.java @@ -75,8 +75,8 @@ public abstract class MediaConstraints { try { // XXX - This is loading everything into memory! We want the send path to be stream-like. - return new MediaStream(new ByteArrayInputStream(BitmapUtil.createScaledBytes(context, new DecryptableUri(attachment.getDataUri()), this)), - MediaUtil.IMAGE_JPEG); + BitmapUtil.ScaleResult scaleResult = BitmapUtil.createScaledBytes(context, new DecryptableUri(attachment.getDataUri()), this); + return new MediaStream(new ByteArrayInputStream(scaleResult.getBitmap()), MediaUtil.IMAGE_JPEG, scaleResult.getWidth(), scaleResult.getHeight()); } catch (BitmapDecodingException e) { throw new IOException(e); } diff --git a/src/org/thoughtcrime/securesms/mms/MediaStream.java b/src/org/thoughtcrime/securesms/mms/MediaStream.java index ba729f9aec..c736dd3a96 100644 --- a/src/org/thoughtcrime/securesms/mms/MediaStream.java +++ b/src/org/thoughtcrime/securesms/mms/MediaStream.java @@ -21,10 +21,14 @@ import java.io.InputStream; public class MediaStream { private final InputStream stream; private final String mimeType; + private final int width; + private final int height; - public MediaStream(InputStream stream, String mimeType) { + public MediaStream(InputStream stream, String mimeType, int width, int height) { this.stream = stream; this.mimeType = mimeType; + this.width = width; + this.height = height; } public InputStream getStream() { @@ -34,4 +38,12 @@ public class MediaStream { public String getMimeType() { return mimeType; } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } } diff --git a/src/org/thoughtcrime/securesms/profiles/SystemProfileUtil.java b/src/org/thoughtcrime/securesms/profiles/SystemProfileUtil.java index d8745b9a9a..781465ee75 100644 --- a/src/org/thoughtcrime/securesms/profiles/SystemProfileUtil.java +++ b/src/org/thoughtcrime/securesms/profiles/SystemProfileUtil.java @@ -39,7 +39,8 @@ public class SystemProfileUtil { if (!TextUtils.isEmpty(photoUri)) { try { - return BitmapUtil.createScaledBytes(context, Uri.parse(photoUri), mediaConstraints); + BitmapUtil.ScaleResult result = BitmapUtil.createScaledBytes(context, Uri.parse(photoUri), mediaConstraints); + return result.getBitmap(); } catch (BitmapDecodingException e) { Log.w(TAG, e); } diff --git a/src/org/thoughtcrime/securesms/util/BitmapUtil.java b/src/org/thoughtcrime/securesms/util/BitmapUtil.java index 70f8bbe6b4..dc8f391ceb 100644 --- a/src/org/thoughtcrime/securesms/util/BitmapUtil.java +++ b/src/org/thoughtcrime/securesms/util/BitmapUtil.java @@ -15,7 +15,6 @@ import android.support.annotation.WorkerThread; import android.util.Log; import android.util.Pair; -import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy; @@ -45,7 +44,7 @@ public class BitmapUtil { private static final int MIN_COMPRESSION_QUALITY_DECREASE = 5; @android.support.annotation.WorkerThread - public static byte[] createScaledBytes(Context context, T model, MediaConstraints constraints) + public static ScaleResult createScaledBytes(Context context, T model, MediaConstraints constraints) throws BitmapDecodingException { try { @@ -87,7 +86,7 @@ public class BitmapUtil { throw new BitmapDecodingException("Unable to scale image below: " + bytes.length); } Log.w(TAG, "createScaledBytes(" + model.toString() + ") -> quality " + Math.min(quality, MAX_COMPRESSION_QUALITY) + ", " + attempts + " attempt(s)"); - return bytes; + return new ScaleResult(bytes, scaledBitmap.getWidth(), scaledBitmap.getHeight()); } finally { if (scaledBitmap != null) scaledBitmap.recycle(); } @@ -305,4 +304,29 @@ public class BitmapUtil { return Math.min(maximumTextureSize, MAX_ALLOWED_TEXTURE_SIZE); } + + public static class ScaleResult { + private final byte[] bitmap; + private final int width; + private final int height; + + public ScaleResult(byte[] bitmap, int width, int height) { + this.bitmap = bitmap; + this.width = width; + this.height = height; + } + + + public byte[] getBitmap() { + return bitmap; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + } }