diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index 458ea90049..3d29772c85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -307,7 +307,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { } } - private Optional getSystemAvatar(@Nullable Uri uri) { + private Optional getSystemAvatar(@Nullable Uri uri) throws IOException { if (uri == null) { return Optional.empty(); } @@ -329,6 +329,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { .withStream(fd.createInputStream()) .withContentType("image/*") .withLength(fd.getLength()) + .withResumableUploadSpec(AppDependencies.getSignalServiceMessageSender().getResumableUploadSpec()) .build()); } catch (IOException e) { // Ignored @@ -355,6 +356,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { .withStream(new ByteArrayInputStream(data)) .withContentType("image/*") .withLength(data.length) + .withResumableUploadSpec(AppDependencies.getSignalServiceMessageSender().getResumableUploadSpec()) .build()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java index 16b7c21ab8..df964d4281 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java @@ -93,6 +93,7 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob { .withStream(new ByteArrayInputStream(baos.toByteArray())) .withContentType("application/octet-stream") .withLength(baos.toByteArray().length) + .withResumableUploadSpec(messageSender.getResumableUploadSpec()) .build(); SignalServiceSyncMessage syncMessage = SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, 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 9a94086a42..b5c8e5ad8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -197,7 +197,9 @@ public abstract class PushSendJob extends SendJob { return Optional.of(ProfileKeyUtil.getSelfProfileKey().serialize()); } - protected SignalServiceAttachment getAttachmentFor(Attachment attachment) { + protected SignalServiceAttachment getAttachmentFor(Contact.Avatar avatar) { + Attachment attachment = avatar.getAttachment(); + try { if (attachment.getUri() == null || attachment.size == 0) throw new IOException("Assertion failed, outgoing attachment has no data!"); InputStream is = PartAuthority.getAttachmentStream(context, attachment.getUri()); @@ -214,6 +216,7 @@ public abstract class PushSendJob extends SendJob { .withHeight(attachment.height) .withCaption(attachment.caption) .withUuid(attachment.uuid) + .withResumableUploadSpec(AppDependencies.getSignalServiceMessageSender().getResumableUploadSpec()) .withListener(new SignalServiceAttachment.ProgressListener() { @Override public void onAttachmentProgress(long total, long progress) { @@ -454,7 +457,7 @@ public abstract class PushSendJob extends SendJob { if (contact.getAvatar() != null && contact.getAvatar().getAttachment() != null) { SignalServiceAttachment attachment = getAttachmentPointerFor(contact.getAvatar().getAttachment()); if (attachment == null) { - attachment = getAttachmentFor(contact.getAvatar().getAttachment()); + attachment = getAttachmentFor(contact.getAvatar()); } avatar = SharedContact.Avatar.newBuilder().withAttachment(attachment) .withProfileFlag(contact.getAvatar().isProfile()) 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 4fa97f85cb..fffcfe831e 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 @@ -816,53 +816,11 @@ public class SignalServiceMessageSender { attachment.getCancelationSignal(), attachment.getResumableUploadSpec().orElse(null)); - if (attachment.getResumableUploadSpec().isPresent()) { - return uploadAttachmentV4(attachment, attachmentKey, attachmentData); - } else { - Log.w(TAG, "Using legacy attachment upload endpoint."); - return uploadAttachmentV2(attachment, attachmentKey, attachmentData); - } - } - - private SignalServiceAttachmentPointer uploadAttachmentV2(SignalServiceAttachmentStream attachment, byte[] attachmentKey, PushAttachmentData attachmentData) - throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException - { - AttachmentV2UploadAttributes v2UploadAttributes = null; - - Log.d(TAG, "Using pipe to retrieve attachment upload attributes..."); - try { - v2UploadAttributes = new AttachmentService.AttachmentAttributesResponseProcessor<>(attachmentService.getAttachmentV2UploadAttributes().blockingGet()).getResultOrThrow(); - } catch (WebSocketUnavailableException e) { - Log.w(TAG, "[uploadAttachmentV2] Pipe unavailable, falling back... (" + e.getClass().getSimpleName() + ": " + e.getMessage() + ")"); - } catch (IOException e) { - Log.w(TAG, "Failed to retrieve attachment upload attributes using pipe. Falling back..."); + if (attachment.getResumableUploadSpec().isEmpty()) { + throw new IllegalStateException("Attachment must have a resumable upload spec."); } - if (v2UploadAttributes == null) { - Log.d(TAG, "Not using pipe to retrieve attachment upload attributes..."); - v2UploadAttributes = socket.getAttachmentV2UploadAttributes(); - } - - Pair attachmentIdAndDigest = socket.uploadAttachment(attachmentData, v2UploadAttributes); - - return new SignalServiceAttachmentPointer(0, - new SignalServiceAttachmentRemoteId.V2(attachmentIdAndDigest.first()), - attachment.getContentType(), - attachmentKey, - Optional.of(Util.toIntExact(attachment.getLength())), - attachment.getPreview(), - attachment.getWidth(), attachment.getHeight(), - Optional.of(attachmentIdAndDigest.second().getDigest()), - Optional.of(attachmentIdAndDigest.second().getIncrementalDigest()), - attachmentIdAndDigest.second().getIncrementalMacChunkSize(), - attachment.getFileName(), - attachment.getVoiceNote(), - attachment.isBorderless(), - attachment.isGif(), - attachment.getCaption(), - attachment.getBlurHash(), - attachment.getUploadTimestamp(), - attachment.getUuid()); + return uploadAttachmentV4(attachment, attachmentKey, attachmentData); } public ResumableUploadSpec getResumableUploadSpec() throws IOException { 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 30b0e248ef..384e9c3a44 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 @@ -63,7 +63,11 @@ public class DeviceContactsInputStream extends ChunkedInputStream { InputStream avatarStream = new LimitedInputStream(in, avatarLength); String avatarContentType = details.avatar.contentType; - avatar = Optional.of(SignalServiceAttachment.newStreamBuilder().withStream(avatarStream).withContentType(avatarContentType).withLength(avatarLength).build()); + avatar = Optional.of(SignalServiceAttachment.newStreamBuilder() + .withStream(avatarStream) + .withContentType(avatarContentType) + .withLength(avatarLength) + .build()); } if (details.verified != null) { diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/AttachmentService.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/AttachmentService.kt index b9299ed42a..23d09a394a 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/AttachmentService.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/AttachmentService.kt @@ -5,7 +5,6 @@ import org.whispersystems.signalservice.api.SignalWebSocket import org.whispersystems.signalservice.internal.ServiceResponse import org.whispersystems.signalservice.internal.ServiceResponseProcessor import org.whispersystems.signalservice.internal.push.AttachmentUploadForm -import org.whispersystems.signalservice.internal.push.AttachmentV2UploadAttributes import org.whispersystems.signalservice.internal.websocket.DefaultResponseMapper import org.whispersystems.signalservice.internal.websocket.WebSocketRequestMessage import org.whispersystems.signalservice.internal.websocket.WebsocketResponse @@ -17,18 +16,6 @@ import java.security.SecureRandom * Note: To be expanded to have REST fallback and other attachment related operations. */ class AttachmentService(private val signalWebSocket: SignalWebSocket) { - fun getAttachmentV2UploadAttributes(): Single> { - val requestMessage = WebSocketRequestMessage( - id = SecureRandom().nextLong(), - verb = "GET", - path = "/v2/attachments/form/upload" - ) - - return signalWebSocket.request(requestMessage) - .map { response: WebsocketResponse? -> DefaultResponseMapper.getDefault(AttachmentV2UploadAttributes::class.java).map(response) } - .onErrorReturn { throwable: Throwable? -> ServiceResponse.forUnknownError(throwable) } - } - fun getAttachmentV4UploadAttributes(): Single> { val requestMessage = WebSocketRequestMessage( id = SecureRandom().nextLong(), 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 9eae04814f..13ca5d7b0f 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 @@ -255,7 +255,6 @@ public class PushServiceSocket { private static final String GROUP_MESSAGE_PATH = "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s&story=%s"; private static final String SENDER_ACK_MESSAGE_PATH = "/v1/messages/%s/%d"; private static final String UUID_ACK_MESSAGE_PATH = "/v1/messages/uuid/%s"; - private static final String ATTACHMENT_V2_PATH = "/v2/attachments/form/upload"; private static final String ATTACHMENT_V4_PATH = "/v4/attachments/form/upload"; private static final String PAYMENTS_AUTH_PATH = "/v1/payments/auth"; @@ -1544,18 +1543,6 @@ public class PushServiceSocket { } } - public AttachmentV2UploadAttributes getAttachmentV2UploadAttributes() - throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException - { - String response = makeServiceRequest(ATTACHMENT_V2_PATH, "GET", null); - try { - return JsonUtil.fromJson(response, AttachmentV2UploadAttributes.class); - } catch (IOException e) { - Log.w(TAG, e); - throw new MalformedResponseException("Unable to parse entity", e); - } - } - public AttachmentUploadForm getAttachmentV4UploadAttributes() throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException {