This was a holdover from Signal's origins as a pure SMS app. It causes problems, depends on undefined device specific behavior, and should no longer be necessary now that we have all the information we need to E164 all numbers. // FREEBIE
136 lines
6.1 KiB
Java
136 lines
6.1 KiB
Java
package org.thoughtcrime.securesms.jobs;
|
|
|
|
import android.content.Context;
|
|
import android.util.Log;
|
|
|
|
import org.thoughtcrime.securesms.ApplicationContext;
|
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|
import org.thoughtcrime.securesms.database.Address;
|
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|
import org.thoughtcrime.securesms.database.MmsDatabase;
|
|
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
|
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
|
import org.thoughtcrime.securesms.mms.MmsException;
|
|
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
|
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
|
import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
|
|
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
|
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
|
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
|
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
|
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import static org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory;
|
|
|
|
public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
private static final String TAG = PushMediaSendJob.class.getSimpleName();
|
|
|
|
@Inject transient SignalMessageSenderFactory messageSenderFactory;
|
|
|
|
private final long messageId;
|
|
|
|
public PushMediaSendJob(Context context, long messageId, Address destination) {
|
|
super(context, constructParameters(context, destination));
|
|
this.messageId = messageId;
|
|
}
|
|
|
|
@Override
|
|
public void onAdded() {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onPushSend(MasterSecret masterSecret)
|
|
throws RetryLaterException, MmsException, NoSuchMessageException,
|
|
UndeliverableMessageException
|
|
{
|
|
ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager();
|
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
|
OutgoingMediaMessage message = database.getOutgoingMessage(masterSecret, messageId);
|
|
|
|
try {
|
|
deliver(masterSecret, message);
|
|
database.markAsSent(messageId, true);
|
|
markAttachmentsUploaded(messageId, message.getAttachments());
|
|
|
|
if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) {
|
|
database.markExpireStarted(messageId);
|
|
expirationManager.scheduleDeletion(messageId, true, message.getExpiresIn());
|
|
}
|
|
|
|
} catch (InsecureFallbackApprovalException ifae) {
|
|
Log.w(TAG, ifae);
|
|
database.markAsPendingInsecureSmsFallback(messageId);
|
|
notifyMediaMessageDeliveryFailed(context, messageId);
|
|
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context));
|
|
} catch (UntrustedIdentityException uie) {
|
|
Log.w(TAG, uie);
|
|
database.addMismatchedIdentity(messageId, Address.fromSerialized(uie.getE164Number()), uie.getIdentityKey());
|
|
database.markAsSentFailed(messageId);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onShouldRetryThrowable(Exception exception) {
|
|
if (exception instanceof RequirementNotMetException) return true;
|
|
if (exception instanceof RetryLaterException) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onCanceled() {
|
|
DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId);
|
|
notifyMediaMessageDeliveryFailed(context, messageId);
|
|
}
|
|
|
|
private void deliver(MasterSecret masterSecret, OutgoingMediaMessage message)
|
|
throws RetryLaterException, InsecureFallbackApprovalException, UntrustedIdentityException,
|
|
UndeliverableMessageException
|
|
{
|
|
if (message.getRecipients() == null || message.getRecipients().getPrimaryRecipient() == null) {
|
|
throw new UndeliverableMessageException("No destination address.");
|
|
}
|
|
|
|
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
|
|
|
try {
|
|
SignalServiceAddress address = getPushAddress(message.getRecipients().getPrimaryRecipient().getAddress());
|
|
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
|
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
|
|
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
|
|
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()
|
|
.withBody(message.getBody())
|
|
.withAttachments(attachmentStreams)
|
|
.withTimestamp(message.getSentTimeMillis())
|
|
.withExpiration((int)(message.getExpiresIn() / 1000))
|
|
.asExpirationUpdate(message.isExpirationUpdate())
|
|
.build();
|
|
|
|
messageSender.sendMessage(address, mediaMessage);
|
|
} catch (UnregisteredUserException e) {
|
|
Log.w(TAG, e);
|
|
throw new InsecureFallbackApprovalException(e);
|
|
} catch (FileNotFoundException e) {
|
|
Log.w(TAG, e);
|
|
throw new UndeliverableMessageException(e);
|
|
} catch (IOException e) {
|
|
Log.w(TAG, e);
|
|
throw new RetryLaterException(e);
|
|
}
|
|
}
|
|
}
|