Signal-Android/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
Moxie Marlinspike 737810475e Remove the Canonical Address Database
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
2017-07-31 12:02:29 -07:00

121 lines
5.2 KiB
Java

package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.util.Log;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
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.IOException;
import javax.inject.Inject;
import static org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory;
public class PushTextSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = PushTextSendJob.class.getSimpleName();
@Inject transient SignalMessageSenderFactory messageSenderFactory;
private final long messageId;
public PushTextSendJob(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 NoSuchMessageException, RetryLaterException {
ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager();
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
SmsMessageRecord record = database.getMessage(masterSecret, messageId);
try {
Log.w(TAG, "Sending message: " + messageId);
deliver(record);
database.markAsSent(messageId, true);
if (record.getExpiresIn() > 0) {
database.markExpireStarted(messageId);
expirationManager.scheduleDeletion(record.getId(), record.isMms(), record.getExpiresIn());
}
} catch (InsecureFallbackApprovalException e) {
Log.w(TAG, e);
database.markAsPendingInsecureSmsFallback(record.getId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context));
} catch (UntrustedIdentityException e) {
Log.w(TAG, e);
database.addMismatchedIdentity(record.getId(), Address.fromSerialized(e.getE164Number()), e.getIdentityKey());
database.markAsSentFailed(record.getId());
database.markAsPush(record.getId());
}
}
@Override
public boolean onShouldRetryThrowable(Exception exception) {
if (exception instanceof RetryLaterException) return true;
return false;
}
@Override
public void onCanceled() {
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
Recipients recipients = DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);
if (threadId != -1 && recipients != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
}
}
private void deliver(SmsMessageRecord message)
throws UntrustedIdentityException, InsecureFallbackApprovalException, RetryLaterException
{
try {
SignalServiceAddress address = getPushAddress(message.getIndividualRecipient().getAddress());
SignalServiceMessageSender messageSender = messageSenderFactory.create();
SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder()
.withTimestamp(message.getDateSent())
.withBody(message.getBody().getBody())
.withExpiration((int)(message.getExpiresIn() / 1000))
.asEndSessionMessage(message.isEndSession())
.build();
messageSender.sendMessage(address, textSecureMessage);
} catch (UnregisteredUserException e) {
Log.w(TAG, e);
throw new InsecureFallbackApprovalException(e);
} catch (IOException e) {
Log.w(TAG, e);
throw new RetryLaterException(e);
}
}
}