"name":"org.whispersystems.signalservice.internal.keybackup.protos.RestoreResponse",
"fields":[{"name":"bitField0_"}, {"name":"data_"}, {"name":"status_"}, {"name":"token_"}, {"name":"tries_"}]
},
+{
+ "name":"org.whispersystems.signalservice.internal.push.AttachmentUploadForm",
+ "allDeclaredFields":true,
+ "queryAllDeclaredMethods":true,
+ "queryAllDeclaredConstructors":true,
+ "methods":[{"name":"<init>","parameterTypes":["int","java.lang.String","java.util.Map","java.lang.String"] }, {"name":"<init>","parameterTypes":["int","java.lang.String","java.util.Map","java.lang.String","int","kotlin.jvm.internal.DefaultConstructorMarker"] }]
+},
{
"name":"org.whispersystems.signalservice.internal.push.AttachmentV2UploadAttributes",
"allDeclaredFields":true,
}
public List<SignalServiceAttachment> uploadAttachments(final List<String> attachments) throws AttachmentInvalidException, IOException {
- var attachmentStreams = AttachmentUtils.createAttachmentStreams(attachments);
+ var attachmentStreams = createAttachmentStreams(attachments);
// Upload attachments here, so we only upload once even for multiple recipients
var attachmentPointers = new ArrayList<SignalServiceAttachment>(attachmentStreams.size());
return attachmentPointers;
}
+ private List<SignalServiceAttachmentStream> createAttachmentStreams(List<String> attachments) throws AttachmentInvalidException, IOException {
+ if (attachments == null) {
+ return null;
+ }
+ final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(attachments.size());
+ for (var attachment : attachments) {
+ final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto();
+ signalServiceAttachments.add(AttachmentUtils.createAttachmentStream(attachment, uploadSpec));
+ }
+ return signalServiceAttachments;
+ }
+
public SignalServiceAttachmentPointer uploadAttachment(String attachment) throws IOException, AttachmentInvalidException {
- var attachmentStream = AttachmentUtils.createAttachmentStream(attachment);
+ final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto();
+ var attachmentStream = AttachmentUtils.createAttachmentStream(attachment, uploadSpec);
return uploadAttachment(attachmentStream);
}
return Optional.empty();
}
- return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty()));
+ final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto();
+ return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty(), uploadSpec));
}
public GroupInfoV2 getOrMigrateGroup(
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.internal.push.SyncMessage;
+import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
if (groupsFile.exists() && groupsFile.length() > 0) {
try (var groupsFileStream = new FileInputStream(groupsFile)) {
+ final var uploadSpec = context.getDependencies()
+ .getMessageSender()
+ .getResumableUploadSpec()
+ .toProto();
var attachmentStream = SignalServiceAttachment.newStreamBuilder()
.withStream(groupsFileStream)
.withContentType(MimeUtils.OCTET_STREAM)
.withLength(groupsFile.length())
+ .withResumableUploadSpec(ResumableUploadSpec.from(uploadSpec))
.build();
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream));
if (contactsFile.exists() && contactsFile.length() > 0) {
try (var contactsFileStream = new FileInputStream(contactsFile)) {
+ final var uploadSpec = context.getDependencies()
+ .getMessageSender()
+ .getResumableUploadSpec()
+ .toProto();
var attachmentStream = SignalServiceAttachment.newStreamBuilder()
.withStream(contactsFileStream)
.withContentType(MimeUtils.OCTET_STREAM)
.withLength(contactsFile.length())
+ .withResumableUploadSpec(ResumableUploadSpec.from(uploadSpec))
.build();
context.getSendHelper()
return Optional.empty();
}
- return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty()));
+ final var uploadSpec = context.getDependencies().getMessageSender().getResumableUploadSpec().toProto();
+ return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty(), uploadSpec));
}
private void downloadContactAvatar(SignalServiceAttachment avatar, RecipientAddress address) {
final var additionalAttachments = new ArrayList<SignalServiceAttachment>();
if (message.messageText().length() > 2000) {
final var messageBytes = message.messageText().getBytes(StandardCharsets.UTF_8);
- final var textAttachment = AttachmentUtils.createAttachmentStream(new StreamDetails(new ByteArrayInputStream(
- messageBytes), MimeUtils.LONG_TEXT, messageBytes.length), Optional.empty());
+ final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto();
+ final var streamDetails = new StreamDetails(new ByteArrayInputStream(messageBytes),
+ MimeUtils.LONG_TEXT,
+ messageBytes.length);
+ final var textAttachment = AttachmentUtils.createAttachmentStream(streamDetails,
+ Optional.empty(),
+ uploadSpec);
messageBuilder.withBody(message.messageText().substring(0, 2000));
additionalAttachments.add(context.getAttachmentHelper().uploadAttachment(textAttachment));
} else {
if (streamDetails == null) {
throw new InvalidStickerException("Missing local sticker file");
}
+ final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto();
+ final var stickerAttachment = AttachmentUtils.createAttachmentStream(streamDetails,
+ Optional.empty(),
+ uploadSpec);
messageBuilder.withSticker(new SignalServiceDataMessage.Sticker(packId.serialize(),
stickerPack.packKey(),
stickerId,
manifestSticker.emoji(),
- AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty())));
+ stickerAttachment));
}
if (!message.previews().isEmpty()) {
final var previews = new ArrayList<SignalServicePreview>(message.previews().size());
package org.asamk.signal.manager.util;
import org.asamk.signal.manager.api.AttachmentInvalidException;
+import org.signal.protos.resumableuploads.ResumableUpload;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
+import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException;
import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class AttachmentUtils {
- public static List<SignalServiceAttachmentStream> createAttachmentStreams(List<String> attachments) throws AttachmentInvalidException {
- if (attachments == null) {
- return null;
- }
- final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(attachments.size());
- for (var attachment : attachments) {
- signalServiceAttachments.add(createAttachmentStream(attachment));
- }
- return signalServiceAttachments;
- }
-
- public static SignalServiceAttachmentStream createAttachmentStream(String attachment) throws AttachmentInvalidException {
+ public static SignalServiceAttachmentStream createAttachmentStream(
+ String attachment, ResumableUpload resumableUpload
+ ) throws AttachmentInvalidException {
try {
final var streamDetails = Utils.createStreamDetails(attachment);
- return createAttachmentStream(streamDetails.first(), streamDetails.second());
+ return createAttachmentStream(streamDetails.first(), streamDetails.second(), resumableUpload);
} catch (IOException e) {
throw new AttachmentInvalidException(attachment, e);
}
}
public static SignalServiceAttachmentStream createAttachmentStream(
- StreamDetails streamDetails, Optional<String> name
- ) {
+ StreamDetails streamDetails, Optional<String> name, ResumableUpload resumableUpload
+ ) throws ResumeLocationInvalidException {
// TODO maybe add a parameter to set the voiceNote, borderless, preview, width, height and caption option
final var uploadTimestamp = System.currentTimeMillis();
- Optional<byte[]> preview = Optional.empty();
- Optional<String> caption = Optional.empty();
- Optional<String> blurHash = Optional.empty();
- final Optional<ResumableUploadSpec> resumableUploadSpec = Optional.empty();
- return new SignalServiceAttachmentStream(streamDetails.getStream(),
- streamDetails.getContentType(),
- streamDetails.getLength(),
- name,
- false,
- false,
- false,
- false,
- preview,
- 0,
- 0,
- uploadTimestamp,
- caption,
- blurHash,
- null,
- null,
- resumableUploadSpec,
- UUID.randomUUID());
+ final var resumableUploadSpec = ResumableUploadSpec.from(resumableUpload);
+ return SignalServiceAttachmentStream.newStreamBuilder()
+ .withStream(streamDetails.getStream())
+ .withContentType(streamDetails.getContentType())
+ .withLength(streamDetails.getLength())
+ .withFileName(name.orElse(null))
+ .withUploadTimestamp(uploadTimestamp)
+ .withResumableUploadSpec(resumableUploadSpec)
+ .withUuid(UUID.randomUUID())
+ .build();
}
}