From 67ef831681fdd46a2ce2833f6dd4a2c6e1af2d18 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Tue, 28 Nov 2023 09:36:32 -0500 Subject: [PATCH] Only generate incremental mac for faststart videos. --- .../securesms/database/AttachmentTable.java | 34 ++++++++++++---- .../jobs/AttachmentCompressionJob.java | 8 ++-- .../securesms/jobs/AttachmentUploadJob.kt | 1 + .../jobs/LegacyAttachmentUploadJob.java | 1 + .../securesms/jobs/PushSendJob.java | 1 + .../mediasend/VideoTrimTransform.java | 2 +- .../thoughtcrime/securesms/stories/Stories.kt | 2 +- ...chmentDatabaseTransformPropertiesTest.java | 4 +- .../sms/UploadDependencyGraphTest.kt | 4 +- .../api/SignalServiceMessageSender.java | 3 +- .../api/messages/SignalServiceAttachment.java | 9 ++++- .../SignalServiceAttachmentStream.java | 40 +++++++++++-------- .../DeviceContactsInputStream.java | 2 +- .../internal/push/PushAttachmentData.java | 8 +++- .../internal/push/PushServiceSocket.java | 21 +++++----- .../push/http/DigestingRequestBody.kt | 3 +- .../push/http/DigestingRequestBodyTest.java | 2 +- 17 files changed, 96 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java index e8cc05c4ec..a4263139a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java @@ -942,10 +942,16 @@ public class AttachmentTable extends DatabaseTable { } } - public void markAttachmentAsTransformed(@NonNull AttachmentId attachmentId) { + public void markAttachmentAsTransformed(@NonNull AttachmentId attachmentId, boolean withFaststart) { getWritableDatabase().beginTransaction(); try { - updateAttachmentTransformProperties(attachmentId, getTransformProperties(attachmentId).withSkipTransform()); + TransformProperties transformProperties = getTransformProperties(attachmentId).withSkipTransform(); + + if (withFaststart) { + transformProperties = transformProperties.withMp4Faststart(); + } + + updateAttachmentTransformProperties(attachmentId, transformProperties); getWritableDatabase().setTransactionSuccessful(); } catch (Exception e) { Log.w(TAG, "Could not mark attachment as transformed.", e); @@ -1645,19 +1651,22 @@ public class AttachmentTable extends DatabaseTable { @JsonProperty private final long videoTrimStartTimeUs; @JsonProperty private final long videoTrimEndTimeUs; @JsonProperty private final int sentMediaQuality; + @JsonProperty private final boolean mp4Faststart; @JsonCreator public TransformProperties(@JsonProperty("skipTransform") boolean skipTransform, @JsonProperty("videoTrim") boolean videoTrim, @JsonProperty("videoTrimStartTimeUs") long videoTrimStartTimeUs, @JsonProperty("videoTrimEndTimeUs") long videoTrimEndTimeUs, - @JsonProperty("sentMediaQuality") int sentMediaQuality) + @JsonProperty("sentMediaQuality") int sentMediaQuality, + @JsonProperty("mp4Faststart") boolean mp4Faststart) { this.skipTransform = skipTransform; this.videoTrim = videoTrim; this.videoTrimStartTimeUs = videoTrimStartTimeUs; this.videoTrimEndTimeUs = videoTrimEndTimeUs; this.sentMediaQuality = sentMediaQuality; + this.mp4Faststart = mp4Faststart; } protected TransformProperties(Parcel in) { @@ -1666,6 +1675,7 @@ public class AttachmentTable extends DatabaseTable { videoTrimStartTimeUs = in.readLong(); videoTrimEndTimeUs = in.readLong(); sentMediaQuality = in.readInt(); + mp4Faststart = in.readByte() != 0; } @Override @@ -1675,6 +1685,7 @@ public class AttachmentTable extends DatabaseTable { dest.writeLong(videoTrimStartTimeUs); dest.writeLong(videoTrimEndTimeUs); dest.writeInt(sentMediaQuality); + dest.writeByte((byte) (mp4Faststart ? 1 : 0)); } @Override @@ -1695,20 +1706,20 @@ public class AttachmentTable extends DatabaseTable { }; public static @NonNull TransformProperties empty() { - return new TransformProperties(false, false, 0, 0, DEFAULT_MEDIA_QUALITY); + return new TransformProperties(false, false, 0, 0, DEFAULT_MEDIA_QUALITY, false); } public static @NonNull TransformProperties forSkipTransform() { - return new TransformProperties(true, false, 0, 0, DEFAULT_MEDIA_QUALITY); + return new TransformProperties(true, false, 0, 0, DEFAULT_MEDIA_QUALITY, false); } public static @NonNull TransformProperties forVideoTrim(long videoTrimStartTimeUs, long videoTrimEndTimeUs) { - return new TransformProperties(false, true, videoTrimStartTimeUs, videoTrimEndTimeUs, DEFAULT_MEDIA_QUALITY); + return new TransformProperties(false, true, videoTrimStartTimeUs, videoTrimEndTimeUs, DEFAULT_MEDIA_QUALITY, false); } public static @NonNull TransformProperties forSentMediaQuality(@NonNull Optional currentProperties, @NonNull SentMediaQuality sentMediaQuality) { TransformProperties existing = currentProperties.orElse(empty()); - return new TransformProperties(existing.skipTransform, existing.videoTrim, existing.videoTrimStartTimeUs, existing.videoTrimEndTimeUs, sentMediaQuality.getCode()); + return new TransformProperties(existing.skipTransform, existing.videoTrim, existing.videoTrimStartTimeUs, existing.videoTrimEndTimeUs, sentMediaQuality.getCode(), existing.mp4Faststart); } public boolean shouldSkipTransform() { @@ -1723,6 +1734,10 @@ public class AttachmentTable extends DatabaseTable { return videoTrim; } + public boolean isMp4Faststart() { + return mp4Faststart; + } + public long getVideoTrimStartTimeUs() { return videoTrimStartTimeUs; } @@ -1736,9 +1751,12 @@ public class AttachmentTable extends DatabaseTable { } @NonNull TransformProperties withSkipTransform() { - return new TransformProperties(true, false, 0, 0, sentMediaQuality); + return new TransformProperties(true, false, 0, 0, sentMediaQuality, false); } + @NonNull TransformProperties withMp4Faststart() { + return new TransformProperties(skipTransform, videoTrim, videoTrimStartTimeUs, videoTrimEndTimeUs, sentMediaQuality, true); + } public @NonNull String serialize() { return JsonUtil.toJson(this); } 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 6faa30de6b..e62253df85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java @@ -174,10 +174,10 @@ public final class AttachmentCompressionJob extends BaseJob { try (MediaStream converted = compressImage(context, attachment, constraints)) { attachmentDatabase.updateAttachmentData(attachment, converted, false); } - attachmentDatabase.markAttachmentAsTransformed(attachmentId); + attachmentDatabase.markAttachmentAsTransformed(attachmentId, false); } else if (constraints.isSatisfied(context, attachment)) { Log.i(TAG, "Not compressing."); - attachmentDatabase.markAttachmentAsTransformed(attachmentId); + attachmentDatabase.markAttachmentAsTransformed(attachmentId, false); } else { throw new UndeliverableMessageException("Size constraints could not be met!"); } @@ -253,7 +253,7 @@ public final class AttachmentCompressionJob extends BaseJob { } } - attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId()); + attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId(), false); return Objects.requireNonNull(attachmentDatabase.getAttachment(attachment.getAttachmentId())); } else { @@ -276,7 +276,7 @@ public final class AttachmentCompressionJob extends BaseJob { attachmentDatabase.updateAttachmentData(attachment, mediaStream, true); } - attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId()); + attachmentDatabase.markAttachmentAsTransformed(attachment.getAttachmentId(), true); return Objects.requireNonNull(attachmentDatabase.getAttachment(attachment.getAttachmentId())); } else { 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 ab22d2dd80..fd619bd96c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt @@ -177,6 +177,7 @@ class AttachmentUploadJob private constructor( .withVoiceNote(attachment.isVoiceNote) .withBorderless(attachment.isBorderless) .withGif(attachment.isVideoGif) + .withFaststart(attachment.transformProperties.isMp4Faststart) .withWidth(attachment.width) .withHeight(attachment.height) .withUploadTimestamp(System.currentTimeMillis()) 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 2c1271c06f..027ef5896c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java @@ -193,6 +193,7 @@ public final class LegacyAttachmentUploadJob extends BaseJob { .withVoiceNote(attachment.isVoiceNote()) .withBorderless(attachment.isBorderless()) .withGif(attachment.isVideoGif()) + .withFaststart(attachment.getTransformProperties().isMp4Faststart()) .withWidth(attachment.getWidth()) .withHeight(attachment.getHeight()) .withUploadTimestamp(System.currentTimeMillis()) 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 f2801becd0..899665857e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -207,6 +207,7 @@ public abstract class PushSendJob extends SendJob { .withVoiceNote(attachment.isVoiceNote()) .withBorderless(attachment.isBorderless()) .withGif(attachment.isVideoGif()) + .withFaststart(attachment.getTransformProperties().isMp4Faststart()) .withWidth(attachment.getWidth()) .withHeight(attachment.getHeight()) .withCaption(attachment.getCaption()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.java index a2f44f62d2..4bb9cc1307 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoTrimTransform.java @@ -33,6 +33,6 @@ public final class VideoTrimTransform implements MediaTransform { media.isVideoGif(), media.getBucketId(), media.getCaption(), - Optional.of(new AttachmentTable.TransformProperties(false, data.durationEdited, data.startTimeUs, data.endTimeUs, SentMediaQuality.STANDARD.getCode()))); + Optional.of(new AttachmentTable.TransformProperties(false, data.durationEdited, data.startTimeUs, data.endTimeUs, SentMediaQuality.STANDARD.getCode(), false))); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt index cd6559cd68..ecbe926892 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/Stories.kt @@ -339,7 +339,7 @@ object Stories { error("Illegal clip: $startTimeUs > $endTimeUs for clip $clipIndex") } - AttachmentTable.TransformProperties(false, true, startTimeUs, endTimeUs, SentMediaQuality.STANDARD.code) + AttachmentTable.TransformProperties(false, true, startTimeUs, endTimeUs, SentMediaQuality.STANDARD.code, false) }.map { transformMedia(media, it) } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/AttachmentDatabaseTransformPropertiesTest.java b/app/src/test/java/org/thoughtcrime/securesms/database/AttachmentDatabaseTransformPropertiesTest.java index 8b80363b7c..7a32bcd172 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/AttachmentDatabaseTransformPropertiesTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/database/AttachmentDatabaseTransformPropertiesTest.java @@ -11,13 +11,13 @@ public class AttachmentDatabaseTransformPropertiesTest { public void transformProperties_verifyStructure() { AttachmentTable.TransformProperties properties = AttachmentTable.TransformProperties.empty(); assertEquals("Added transform property, need to confirm default behavior for pre-existing payloads in database", - "{\"skipTransform\":false,\"videoTrim\":false,\"videoTrimStartTimeUs\":0,\"videoTrimEndTimeUs\":0,\"sentMediaQuality\":0,\"videoEdited\":false}", + "{\"skipTransform\":false,\"videoTrim\":false,\"videoTrimStartTimeUs\":0,\"videoTrimEndTimeUs\":0,\"sentMediaQuality\":0,\"mp4Faststart\":false,\"videoEdited\":false}", properties.serialize()); } @Test public void transformProperties_verifyMissingSentMediaQualityDefaultBehavior() { - String json = "{\"skipTransform\":false,\"videoTrim\":false,\"videoTrimStartTimeUs\":0,\"videoTrimEndTimeUs\":0,\"videoEdited\":false}"; + String json = "{\"skipTransform\":false,\"videoTrim\":false,\"videoTrimStartTimeUs\":0,\"videoTrimEndTimeUs\":0,\"videoEdited\":false,\"mp4Faststart\":false}"; AttachmentTable.TransformProperties properties = AttachmentTable.TransformProperties.parse(json); 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 9b499e7187..48e85886b3 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt @@ -85,7 +85,7 @@ class UploadDependencyGraphTest { UriAttachmentBuilder.build( id = 10, contentType = MediaUtil.IMAGE_JPEG, - transformProperties = AttachmentTable.TransformProperties(false, true, increment, increment + 1, SentMediaQuality.STANDARD.code) + transformProperties = AttachmentTable.TransformProperties(false, true, increment, increment + 1, SentMediaQuality.STANDARD.code, false) ) } @@ -127,7 +127,7 @@ class UploadDependencyGraphTest { UriAttachmentBuilder.build( id = 10, contentType = MediaUtil.IMAGE_JPEG, - transformProperties = if (it != 1) AttachmentTable.TransformProperties(false, true, 1, 2, SentMediaQuality.STANDARD.code) else null + transformProperties = if (it != 1) AttachmentTable.TransformProperties(false, true, 1, 2, SentMediaQuality.STANDARD.code, false) else null ) } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index 11197781a5..e046b86b22 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -792,6 +792,7 @@ public class SignalServiceMessageSender { PushAttachmentData attachmentData = new PushAttachmentData(attachment.getContentType(), dataStream, ciphertextLength, + attachment.isFaststart(), new AttachmentCipherOutputStreamFactory(attachmentKey, attachmentIV), attachment.getListener(), attachment.getCancelationSignal(), @@ -877,7 +878,7 @@ public class SignalServiceMessageSender { attachment.getHeight(), Optional.of(digest.getDigest()), Optional.ofNullable(digest.getIncrementalDigest()), - digest.getIncrementalMacChunkSize(), + digest.getIncrementalDigest() != null ? digest.getIncrementalMacChunkSize() : 0, attachment.getFileName(), attachment.getVoiceNote(), attachment.isBorderless(), diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachment.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachment.java index fa695dca26..01b1445e57 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachment.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachment.java @@ -41,7 +41,7 @@ public abstract class SignalServiceAttachment { } public static SignalServiceAttachmentStream emptyStream(String contentType) { - return new SignalServiceAttachmentStream(new ByteArrayInputStream(new byte[0]), contentType, 0, Optional.empty(), false, false, false, null, null); + return new SignalServiceAttachmentStream(new ByteArrayInputStream(new byte[0]), contentType, 0, Optional.empty(), false, false, false, false, null, null); } public static class Builder { @@ -55,6 +55,7 @@ public abstract class SignalServiceAttachment { private boolean voiceNote; private boolean borderless; private boolean gif; + private boolean faststart; private int width; private int height; private String caption; @@ -109,6 +110,11 @@ public abstract class SignalServiceAttachment { return this; } + public Builder withFaststart(boolean faststart) { + this.faststart = faststart; + return this; + } + public Builder withWidth(int width) { this.width = width; return this; @@ -151,6 +157,7 @@ public abstract class SignalServiceAttachment { voiceNote, borderless, gif, + faststart, Optional.empty(), width, height, diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java index c35f9a8775..2459f4b9f1 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceAttachmentStream.java @@ -29,6 +29,7 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple private final boolean voiceNote; private final boolean borderless; private final boolean gif; + private final boolean faststart; private final int width; private final int height; private final long uploadTimestamp; @@ -43,10 +44,11 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple boolean voiceNote, boolean borderless, boolean gif, + boolean faststart, ProgressListener listener, CancelationSignal cancelationSignal) { - this(inputStream, contentType, length, fileName, voiceNote, borderless, gif, Optional.empty(), 0, 0, System.currentTimeMillis(), Optional.empty(), Optional.empty(), listener, cancelationSignal, Optional.empty()); + this(inputStream, contentType, length, fileName, voiceNote, borderless, gif, faststart, Optional.empty(), 0, 0, System.currentTimeMillis(), Optional.empty(), Optional.empty(), listener, cancelationSignal, Optional.empty()); } public SignalServiceAttachmentStream(InputStream inputStream, @@ -56,6 +58,7 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple boolean voiceNote, boolean borderless, boolean gif, + boolean faststart, Optional preview, int width, int height, @@ -67,21 +70,22 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple Optional resumableUploadSpec) { super(contentType); - this.inputStream = inputStream; - this.length = length; - this.fileName = fileName; - this.listener = listener; - this.voiceNote = voiceNote; - this.borderless = borderless; - this.gif = gif; - this.preview = preview; - this.width = width; - this.height = height; - this.uploadTimestamp = uploadTimestamp; - this.caption = caption; - this.blurHash = blurHash; - this.cancelationSignal = cancelationSignal; - this.resumableUploadSpec = resumableUploadSpec; + this.inputStream = inputStream; + this.length = length; + this.fileName = fileName; + this.listener = listener; + this.voiceNote = voiceNote; + this.borderless = borderless; + this.gif = gif; + this.preview = preview; + this.faststart = faststart; + this.width = width; + this.height = height; + this.uploadTimestamp = uploadTimestamp; + this.caption = caption; + this.blurHash = blurHash; + this.cancelationSignal = cancelationSignal; + this.resumableUploadSpec = resumableUploadSpec; } @Override @@ -130,6 +134,10 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple return gif; } + public boolean isFaststart() { + return faststart; + } + public int getWidth() { return width; } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java index 4a57b1daf6..4cec5a0099 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java @@ -61,7 +61,7 @@ public class DeviceContactsInputStream extends ChunkedInputStream { InputStream avatarStream = new LimitedInputStream(in, avatarLength); String avatarContentType = details.avatar.contentType; - avatar = Optional.of(new SignalServiceAttachmentStream(avatarStream, avatarContentType, avatarLength, Optional.empty(), false, false, false, null, null)); + avatar = Optional.of(new SignalServiceAttachmentStream(avatarStream, avatarContentType, avatarLength, Optional.empty(), false, false, false, false, null, null)); } if (details.verified != null) { diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushAttachmentData.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushAttachmentData.java index 536af853e3..384528effd 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushAttachmentData.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushAttachmentData.java @@ -18,19 +18,21 @@ public class PushAttachmentData { private final String contentType; private final InputStream data; private final long dataSize; + private final boolean incremental; private final OutputStreamFactory outputStreamFactory; private final ProgressListener listener; private final CancelationSignal cancelationSignal; private final ResumableUploadSpec resumableUploadSpec; public PushAttachmentData(String contentType, InputStream data, long dataSize, - OutputStreamFactory outputStreamFactory, + boolean incremental, OutputStreamFactory outputStreamFactory, ProgressListener listener, CancelationSignal cancelationSignal, ResumableUploadSpec resumableUploadSpec) { this.contentType = contentType; this.data = data; this.dataSize = dataSize; + this.incremental = incremental; this.outputStreamFactory = outputStreamFactory; this.resumableUploadSpec = resumableUploadSpec; this.listener = listener; @@ -49,6 +51,10 @@ public class PushAttachmentData { return dataSize; } + public boolean getIncremental() { + return incremental; + } + public OutputStreamFactory getOutputStreamFactory() { return outputStreamFactory; } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index da322ea25f..c2541cd3ee 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -946,7 +946,7 @@ public class PushServiceSocket { formAttributes.getPolicy(), formAttributes.getAlgorithm(), formAttributes.getCredential(), formAttributes.getDate(), formAttributes.getSignature(), profileAvatar.getData(), - profileAvatar.getContentType(), profileAvatar.getDataLength(), + profileAvatar.getContentType(), profileAvatar.getDataLength(), false, profileAvatar.getOutputStreamFactory(), null, null); return Optional.of(formAttributes.getKey()); @@ -1393,7 +1393,7 @@ public class PushServiceSocket { uploadAttributes.credential, uploadAttributes.date, uploadAttributes.signature, new ByteArrayInputStream(avatarCipherText), - "application/octet-stream", avatarCipherText.length, + "application/octet-stream", avatarCipherText.length, false, new NoCipherOutputStreamFactory(), null, null); } @@ -1407,8 +1407,8 @@ public class PushServiceSocket { uploadAttributes.getCredential(), uploadAttributes.getDate(), uploadAttributes.getSignature(), attachment.getData(), "application/octet-stream", attachment.getDataSize(), - attachment.getOutputStreamFactory(), attachment.getListener(), - attachment.getCancelationSignal()); + attachment.getIncremental(), attachment.getOutputStreamFactory(), + attachment.getListener(), attachment.getCancelationSignal()); return new Pair<>(id, digest); } @@ -1434,6 +1434,7 @@ public class PushServiceSocket { attachment.getData(), "application/octet-stream", attachment.getDataSize(), + attachment.getIncremental(), attachment.getOutputStreamFactory(), attachment.getListener(), attachment.getCancelationSignal()); @@ -1442,6 +1443,7 @@ public class PushServiceSocket { attachment.getData(), "application/offset+octet-stream", attachment.getDataSize(), + attachment.getIncremental(), attachment.getOutputStreamFactory(), attachment.getListener(), attachment.getCancelationSignal(), @@ -1529,7 +1531,7 @@ public class PushServiceSocket { private AttachmentDigest uploadToCdn0(String path, String acl, String key, String policy, String algorithm, String credential, String date, String signature, - InputStream data, String contentType, long length, + InputStream data, String contentType, long length, boolean incremental, OutputStreamFactory outputStreamFactory, ProgressListener progressListener, CancelationSignal cancelationSignal) throws PushNetworkException, NonSuccessfulResponseCodeException @@ -1541,7 +1543,7 @@ public class PushServiceSocket { .readTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS) .build(); - DigestingRequestBody file = new DigestingRequestBody(data, outputStreamFactory, contentType, length, progressListener, cancelationSignal, 0); + DigestingRequestBody file = new DigestingRequestBody(data, outputStreamFactory, contentType, length, incremental, progressListener, cancelationSignal, 0); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) @@ -1639,7 +1641,7 @@ public class PushServiceSocket { } } - private AttachmentDigest uploadToCdn2(String resumableUrl, InputStream data, String contentType, long length, OutputStreamFactory outputStreamFactory, ProgressListener progressListener, CancelationSignal cancelationSignal) throws IOException { + private AttachmentDigest uploadToCdn2(String resumableUrl, InputStream data, String contentType, long length, boolean incremental, OutputStreamFactory outputStreamFactory, ProgressListener progressListener, CancelationSignal cancelationSignal) throws IOException { ConnectionHolder connectionHolder = getRandom(cdnClientsMap.get(2), random); OkHttpClient okHttpClient = connectionHolder.getClient() .newBuilder() @@ -1648,7 +1650,7 @@ public class PushServiceSocket { .build(); ResumeInfo resumeInfo = getResumeInfoCdn2(resumableUrl, length); - DigestingRequestBody file = new DigestingRequestBody(data, outputStreamFactory, contentType, length, progressListener, cancelationSignal, resumeInfo.contentStart); + DigestingRequestBody file = new DigestingRequestBody(data, outputStreamFactory, contentType, length, incremental, progressListener, cancelationSignal, resumeInfo.contentStart); if (resumeInfo.contentStart == length) { Log.w(TAG, "Resume start point == content length"); @@ -1690,6 +1692,7 @@ public class PushServiceSocket { InputStream data, String contentType, long length, + boolean incremental, OutputStreamFactory outputStreamFactory, ProgressListener progressListener, CancelationSignal cancelationSignal, @@ -1704,7 +1707,7 @@ public class PushServiceSocket { .build(); ResumeInfo resumeInfo = getResumeInfoCdn3(resumableUrl, headers); - DigestingRequestBody file = new DigestingRequestBody(data, outputStreamFactory, contentType, length, progressListener, cancelationSignal, resumeInfo.contentStart); + DigestingRequestBody file = new DigestingRequestBody(data, outputStreamFactory, contentType, length, incremental, progressListener, cancelationSignal, resumeInfo.contentStart); if (resumeInfo.contentStart == length) { Log.w(TAG, "Resume start point == content length"); diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt index a032b3cc7c..6a76822e59 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt @@ -22,6 +22,7 @@ class DigestingRequestBody( private val outputStreamFactory: OutputStreamFactory, private val contentType: String, private val contentLength: Long, + private val incremental: Boolean, private val progressListener: SignalServiceAttachment.ProgressListener?, private val cancelationSignal: CancelationSignal?, private val contentStart: Long @@ -41,7 +42,7 @@ class DigestingRequestBody( override fun writeTo(sink: BufferedSink) { val digestStream = ByteArrayOutputStream() val inner = SkippingOutputStream(contentStart, sink.outputStream()) - val isIncremental = outputStreamFactory is AttachmentCipherOutputStreamFactory + val isIncremental = incremental && outputStreamFactory is AttachmentCipherOutputStreamFactory val sizeChoice: ChunkSizeChoice = ChunkSizeChoice.inferChunkSize(contentLength.toInt()) val outputStream: DigestingOutputStream = if (isIncremental) { (outputStreamFactory as AttachmentCipherOutputStreamFactory).createIncrementalFor(inner, contentLength, sizeChoice, digestStream) diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBodyTest.java b/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBodyTest.java index 805aafdf27..658a4b1071 100644 --- a/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBodyTest.java +++ b/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBodyTest.java @@ -83,7 +83,7 @@ public class DigestingRequestBodyTest { } private DigestingRequestBody getBody(long contentStart) { - return new DigestingRequestBody(new ByteArrayInputStream(input), outputStreamFactory, "application/octet", CONTENT_LENGTH, new SignalServiceAttachment.ProgressListener() { + return new DigestingRequestBody(new ByteArrayInputStream(input), outputStreamFactory, "application/octet", CONTENT_LENGTH, false, new SignalServiceAttachment.ProgressListener() { @Override public void onAttachmentProgress(long total, long progress) { // no-op