From c5ab13aadff63da0fb100eb4b4160bd1a999006a Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Mon, 22 Feb 2021 16:29:48 +1100 Subject: [PATCH] clean up deprecated message connection --- .../conversation/ConversationItem.java | 77 +---- .../database/helpers/SQLCipherOpenHelper.java | 8 +- .../securesms/jobs/JobManagerFactories.java | 6 - .../securesms/jobs/MmsDownloadJob.java | 268 -------------- .../securesms/jobs/MmsReceiveJob.java | 126 ------- .../securesms/jobs/MmsSendJob.java | 326 ------------------ .../securesms/jobs/SmsReceiveJob.java | 171 --------- .../securesms/jobs/SmsSendJob.java | 249 ------------- .../securesms/jobs/SmsSentJob.java | 128 ------- .../securesms/mms/CompatMmsConnection.java | 100 ------ .../mms/IncomingLegacyMmsConnection.java | 156 --------- .../mms/OutgoingLegacyMmsConnection.java | 162 --------- .../securesms/service/MmsListener.java | 67 ---- .../service/SmsDeliveryListener.java | 69 ---- .../securesms/service/SmsListener.java | 113 ------ .../securesms/sms/MessageSender.java | 46 --- .../org/thoughtcrime/securesms/util/Util.java | 3 +- 17 files changed, 14 insertions(+), 2061 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/CompatMmsConnection.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/SmsDeliveryListener.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 7786b52f94..10295aa2d0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -49,7 +49,6 @@ import android.widget.Toast; import androidx.annotation.DimenRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import com.annimon.stream.Stream; @@ -71,17 +70,12 @@ import org.thoughtcrime.securesms.components.StickerView; import org.thoughtcrime.securesms.components.emoji.EmojiTextView; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsSmsDatabase; -import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.Quote; import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob; -import org.thoughtcrime.securesms.jobs.MmsDownloadJob; -import org.thoughtcrime.securesms.jobs.MmsSendJob; -import org.thoughtcrime.securesms.jobs.SmsSendJob; import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil; import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.loki.utilities.MentionUtilities; @@ -1114,21 +1108,13 @@ public class ConversationItem extends LinearLayout @Override public void onClick(View v, final List slides) { Log.i(TAG, "onClick() for attachment download"); - if (messageRecord.isMmsNotification()) { - Log.i(TAG, "Scheduling MMS attachment download"); - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MmsDownloadJob(messageRecord.getId(), - messageRecord.getThreadId(), false)); - } else { - Log.i(TAG, "Scheduling push attachment downloads for " + slides.size() + " items"); + Log.i(TAG, "Scheduling push attachment downloads for " + slides.size() + " items"); - for (Slide slide : slides) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new AttachmentDownloadJob(messageRecord.getId(), - ((DatabaseAttachment)slide.asAttachment()).getAttachmentId(), true)); - } + for (Slide slide : slides) { + ApplicationContext.getInstance(context) + .getJobManager() + .add(new AttachmentDownloadJob(messageRecord.getId(), + ((DatabaseAttachment)slide.asAttachment()).getAttachmentId(), true)); } } } @@ -1224,58 +1210,7 @@ public class ConversationItem extends LinearLayout intent.putExtra(MessageDetailsActivity.IS_PUSH_GROUP_EXTRA, groupThread && messageRecord.isPush()); intent.putExtra(MessageDetailsActivity.ADDRESS_EXTRA, conversationRecipient.getAddress()); context.startActivity(intent); - } else if (!messageRecord.isOutgoing() && messageRecord.isIdentityMismatchFailure()) { -// handleApproveIdentity(); - } else if (messageRecord.isPendingInsecureSmsFallback()) { - handleMessageApproval(); } } } - - private void handleMessageApproval() { - final int title; - final int message; - - if (messageRecord.isMms()) title = R.string.ConversationItem_click_to_approve_unencrypted_mms_dialog_title; - else title = R.string.ConversationItem_click_to_approve_unencrypted_sms_dialog_title; - - message = R.string.ConversationItem_click_to_approve_unencrypted_dialog_message; - - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(title); - - if (message > -1) builder.setMessage(message); - - builder.setPositiveButton(R.string.yes, (dialogInterface, i) -> { - if (messageRecord.isMms()) { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - database.markAsInsecure(messageRecord.getId()); - database.markAsOutbox(messageRecord.getId()); - database.markAsForcedSms(messageRecord.getId()); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MmsSendJob(messageRecord.getId())); - } else { - SmsDatabase database = DatabaseFactory.getSmsDatabase(context); - database.markAsInsecure(messageRecord.getId()); - database.markAsOutbox(messageRecord.getId()); - database.markAsForcedSms(messageRecord.getId()); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new SmsSendJob(context, messageRecord.getId(), - messageRecord.getIndividualRecipient().getAddress().serialize())); - } - }); - - builder.setNegativeButton(R.string.no, (dialogInterface, i) -> { - if (messageRecord.isMms()) { - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageRecord.getId()); - } else { - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageRecord.getId()); - } - }); - builder.show(); - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 2a4e6e0056..4ad8e84356 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -244,7 +244,13 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { "ClosedGroupUpdateMessageSendJob", "NullMessageSendJob", "StickerDownloadJob", - "StickerPackDownloadJob"); + "StickerPackDownloadJob", + "MmsSendJob", + "MmsReceiveJob", + "MmsDownloadJob", + "SmsSendJob", + "SmsSentJob", + "SmsReceiveJob"); } db.setTransactionSuccessful(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index 3333555dc6..ad01307c65 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -37,9 +37,6 @@ public final class JobManagerFactories { put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory()); put(ClosedGroupUpdateMessageSendJobV2.KEY, new ClosedGroupUpdateMessageSendJobV2.Factory()); put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); - put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory()); - put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory()); - put(MmsSendJob.KEY, new MmsSendJob.Factory()); put(PushContentReceiveJob.KEY, new PushContentReceiveJob.Factory()); put(PushDecryptJob.KEY, new PushDecryptJob.Factory()); put(PushGroupSendJob.KEY, new PushGroupSendJob.Factory()); @@ -50,9 +47,6 @@ public final class JobManagerFactories { put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application)); put(SendDeliveryReceiptJob.KEY, new SendDeliveryReceiptJob.Factory()); put(SendReadReceiptJob.KEY, new SendReadReceiptJob.Factory()); - put(SmsReceiveJob.KEY, new SmsReceiveJob.Factory()); - put(SmsSendJob.KEY, new SmsSendJob.Factory()); - put(SmsSentJob.KEY, new SmsSentJob.Factory()); put(TrimThreadJob.KEY, new TrimThreadJob.Factory()); put(TypingSendJob.KEY, new TypingSendJob.Factory()); put(UpdateApkJob.KEY, new UpdateApkJob.Factory()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java deleted file mode 100644 index bb10fc1b0b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ /dev/null @@ -1,268 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.google.android.mms.pdu_alt.CharacterSets; -import com.google.android.mms.pdu_alt.EncodedStringValue; -import com.google.android.mms.pdu_alt.PduBody; -import com.google.android.mms.pdu_alt.PduPart; -import com.google.android.mms.pdu_alt.RetrieveConf; - -import org.session.libsession.messaging.jobs.Data; -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.session.libsignal.utilities.logging.Log; -import org.thoughtcrime.securesms.mms.ApnUnavailableException; -import org.thoughtcrime.securesms.mms.CompatMmsConnection; -import org.thoughtcrime.securesms.mms.IncomingMediaMessage; -import org.thoughtcrime.securesms.mms.MmsException; -import org.thoughtcrime.securesms.mms.MmsRadioException; -import org.thoughtcrime.securesms.mms.PartParser; -import org.thoughtcrime.securesms.providers.BlobProvider; -import org.thoughtcrime.securesms.service.KeyCachingService; -import org.session.libsignal.libsignal.util.guava.Optional; - -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; -import org.session.libsession.messaging.threads.Address; -import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; -import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsession.utilities.Util; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public class MmsDownloadJob extends BaseJob { - - public static final String KEY = "MmsDownloadJob"; - - private static final String TAG = MmsDownloadJob.class.getSimpleName(); - - private static final String KEY_MESSAGE_ID = "message_id"; - private static final String KEY_THREAD_ID = "thread_id"; - private static final String KEY_AUTOMATIC = "automatic"; - - private long messageId; - private long threadId; - private boolean automatic; - private MessageNotifier messageNotifier; - - public MmsDownloadJob(long messageId, long threadId, boolean automatic) { - this(new Job.Parameters.Builder() - .setQueue("mms-operation") - .setMaxAttempts(25) - .build(), - messageId, - threadId, - automatic); - - } - - private MmsDownloadJob(@NonNull Job.Parameters parameters, long messageId, long threadId, boolean automatic) { - super(parameters); - - this.messageId = messageId; - this.threadId = threadId; - this.automatic = automatic; - this.messageNotifier = ApplicationContext.getInstance(context).messageNotifier; - } - - @Override - public @NonNull - Data serialize() { - return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId) - .putLong(KEY_THREAD_ID, threadId) - .putBoolean(KEY_AUTOMATIC, automatic) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onAdded() { - if (automatic && KeyCachingService.isLocked(context)) { - DatabaseFactory.getMmsDatabase(context).markIncomingNotificationReceived(threadId); - messageNotifier.updateNotification(context); - } - } - - @Override - public void onRun() { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - Optional notification = database.getNotification(messageId); - - if (!notification.isPresent()) { - Log.w(TAG, "No notification for ID: " + messageId); - return; - } - - try { - if (notification.get().getContentLocation() == null) { - throw new MmsException("Notification content location was null."); - } - - if (!TextSecurePreferences.isPushRegistered(context)) { - throw new MmsException("Not registered"); - } - - database.markDownloadState(messageId, MmsDatabase.Status.DOWNLOAD_CONNECTING); - - String contentLocation = notification.get().getContentLocation(); - byte[] transactionId = new byte[0]; - - try { - if (notification.get().getTransactionId() != null) { - transactionId = notification.get().getTransactionId().getBytes(CharacterSets.MIMENAME_ISO_8859_1); - } else { - Log.w(TAG, "No transaction ID!"); - } - } catch (UnsupportedEncodingException e) { - Log.w(TAG, e); - } - - Log.i(TAG, "Downloading mms at " + Uri.parse(contentLocation).getHost() + ", subscription ID: " + notification.get().getSubscriptionId()); - - RetrieveConf retrieveConf = new CompatMmsConnection(context).retrieve(contentLocation, transactionId, notification.get().getSubscriptionId()); - - if (retrieveConf == null) { - throw new MmsException("RetrieveConf was null"); - } - - storeRetrievedMms(contentLocation, messageId, threadId, retrieveConf, notification.get().getSubscriptionId(), notification.get().getFrom()); - } catch (ApnUnavailableException e) { - Log.w(TAG, e); - handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_APN_UNAVAILABLE, - automatic); - } catch (MmsException e) { - Log.w(TAG, e); - handleDownloadError(messageId, threadId, - MmsDatabase.Status.DOWNLOAD_HARD_FAILURE, - automatic); - } catch (MmsRadioException | IOException e) { - Log.w(TAG, e); - handleDownloadError(messageId, threadId, - MmsDatabase.Status.DOWNLOAD_SOFT_FAILURE, - automatic); - } - } - - @Override - public void onCanceled() { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - database.markDownloadState(messageId, MmsDatabase.Status.DOWNLOAD_SOFT_FAILURE); - - if (automatic) { - database.markIncomingNotificationReceived(threadId); - messageNotifier.updateNotification(context, threadId); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return false; - } - - private void storeRetrievedMms(String contentLocation, - long messageId, long threadId, RetrieveConf retrieved, - int subscriptionId, @Nullable Address notificationFrom) - throws MmsException - { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - Optional
group = Optional.absent(); - Set
members = new HashSet<>(); - String body = null; - List attachments = new LinkedList<>(); - - Address from; - - if (retrieved.getFrom() != null) { - from = Address.fromExternal(context, Util.toIsoString(retrieved.getFrom().getTextString())); - } else if (notificationFrom != null) { - from = notificationFrom; - } else { - from = Address.Companion.getUNKNOWN(); - } - - if (retrieved.getTo() != null) { - for (EncodedStringValue toValue : retrieved.getTo()) { - members.add(Address.fromExternal(context, Util.toIsoString(toValue.getTextString()))); - } - } - - if (retrieved.getCc() != null) { - for (EncodedStringValue ccValue : retrieved.getCc()) { - members.add(Address.fromExternal(context, Util.toIsoString(ccValue.getTextString()))); - } - } - - members.add(from); - members.add(Address.fromExternal(context, TextSecurePreferences.getLocalNumber(context))); - - if (retrieved.getBody() != null) { - body = PartParser.getMessageText(retrieved.getBody()); - PduBody media = PartParser.getSupportedMediaParts(retrieved.getBody()); - - for (int i=0;i 2) { - group = Optional.of(Address.fromSerialized(DatabaseFactory.getGroupDatabase(context).getOrCreateGroupForMembers(new LinkedList<>(members), new LinkedList<>()))); - } - - IncomingMediaMessage message = new IncomingMediaMessage(from, group, body, retrieved.getDate() * 1000L, attachments, subscriptionId, 0, false, false); - Optional insertResult = database.insertMessageInbox(message, contentLocation, threadId); - - if (insertResult.isPresent()) { - database.delete(messageId); - messageNotifier.updateNotification(context, insertResult.get().getThreadId()); - } - } - - private void handleDownloadError(long messageId, long threadId, int downloadStatus, boolean automatic) - { - MmsDatabase db = DatabaseFactory.getMmsDatabase(context); - - db.markDownloadState(messageId, downloadStatus); - - if (automatic) { - db.markIncomingNotificationReceived(threadId); - messageNotifier.updateNotification(context, threadId); - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MmsDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MmsDownloadJob(parameters, - data.getLong(KEY_MESSAGE_ID), - data.getLong(KEY_THREAD_ID), - data.getBoolean(KEY_AUTOMATIC)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java deleted file mode 100644 index e38a3148f3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import org.session.libsession.messaging.jobs.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.session.libsignal.utilities.logging.Log; - -import androidx.annotation.NonNull; -import android.util.Pair; - -import com.google.android.mms.pdu_alt.GenericPdu; -import com.google.android.mms.pdu_alt.NotificationInd; -import com.google.android.mms.pdu_alt.PduHeaders; -import com.google.android.mms.pdu_alt.PduParser; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.session.libsession.messaging.threads.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.session.libsession.messaging.threads.recipients.Recipient; -import org.session.libsignal.utilities.Base64; -import org.session.libsession.utilities.Util; - -import java.io.IOException; - -public class MmsReceiveJob extends BaseJob { - - public static final String KEY = "MmsReceiveJob"; - - private static final String TAG = MmsReceiveJob.class.getSimpleName(); - - private static final String KEY_DATA = "data"; - private static final String KEY_SUBSCRIPTION_ID = "subscription_id"; - - private byte[] data; - private int subscriptionId; - - public MmsReceiveJob(byte[] data, int subscriptionId) { - this(new Job.Parameters.Builder().setMaxAttempts(25).build(), data, subscriptionId); - } - - private MmsReceiveJob(@NonNull Job.Parameters parameters, byte[] data, int subscriptionId) { - super(parameters); - - this.data = data; - this.subscriptionId = subscriptionId; - } - - @Override - public @NonNull - Data serialize() { - return new Data.Builder().putString(KEY_DATA, Base64.encodeBytes(data)) - .putInt(KEY_SUBSCRIPTION_ID, subscriptionId) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() { - if (data == null) { - Log.w(TAG, "Received NULL pdu, ignoring..."); - return; - } - - PduParser parser = new PduParser(data); - GenericPdu pdu = null; - - try { - pdu = parser.parse(); - } catch (RuntimeException e) { - Log.w(TAG, e); - } - - if (isNotification(pdu) && !isBlocked(pdu)) { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - Pair messageAndThreadId = database.insertMessageInbox((NotificationInd)pdu, subscriptionId); - - Log.i(TAG, "Inserted received MMS notification..."); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MmsDownloadJob(messageAndThreadId.first, - messageAndThreadId.second, - true)); - } else if (isNotification(pdu)) { - Log.w(TAG, "*** Received blocked MMS, ignoring..."); - } - } - - @Override - public void onCanceled() { - // TODO - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return false; - } - - private boolean isBlocked(GenericPdu pdu) { - if (pdu.getFrom() != null && pdu.getFrom().getTextString() != null) { - Recipient recipients = Recipient.from(context, Address.fromExternal(context, Util.toIsoString(pdu.getFrom().getTextString())), false); - return recipients.isBlocked(); - } - - return false; - } - - private boolean isNotification(GenericPdu pdu) { - return pdu != null && pdu.getMessageType() == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND; - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MmsReceiveJob create(@NonNull Parameters parameters, @NonNull Data data) { - try { - return new MmsReceiveJob(parameters, Base64.decode(data.getString(KEY_DATA)), data.getInt(KEY_SUBSCRIPTION_ID)); - } catch (IOException e) { - throw new AssertionError(e); - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java deleted file mode 100644 index 53b42d872c..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsSendJob.java +++ /dev/null @@ -1,326 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.content.Context; -import androidx.annotation.NonNull; -import android.text.TextUtils; -import android.webkit.MimeTypeMap; - -import com.android.mms.dom.smil.parser.SmilXmlSerializer; -import com.google.android.mms.ContentType; -import com.google.android.mms.InvalidHeaderValueException; -import com.google.android.mms.pdu_alt.CharacterSets; -import com.google.android.mms.pdu_alt.EncodedStringValue; -import com.google.android.mms.pdu_alt.PduBody; -import com.google.android.mms.pdu_alt.PduComposer; -import com.google.android.mms.pdu_alt.PduHeaders; -import com.google.android.mms.pdu_alt.PduPart; -import com.google.android.mms.pdu_alt.SendConf; -import com.google.android.mms.pdu_alt.SendReq; -import com.google.android.mms.smil.SmilHelper; -import com.klinker.android.send_message.Utils; - -import org.session.libsession.messaging.jobs.Data; -import org.thoughtcrime.securesms.ApplicationContext; -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.messaging.threads.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.NoSuchMessageException; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.session.libsignal.utilities.logging.Log; -import org.thoughtcrime.securesms.mms.CompatMmsConnection; -import org.thoughtcrime.securesms.mms.MediaConstraints; -import org.thoughtcrime.securesms.mms.MmsException; -import org.thoughtcrime.securesms.mms.MmsSendResult; -import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; -import org.thoughtcrime.securesms.mms.PartAuthority; -import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException; -import org.thoughtcrime.securesms.transport.UndeliverableMessageException; -import org.session.libsignal.utilities.Hex; -import org.session.libsession.utilities.NumberUtil; -import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsession.utilities.Util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -public class MmsSendJob extends SendJob { - - public static final String KEY = "MmsSendJob"; - - private static final String TAG = MmsSendJob.class.getSimpleName(); - - private static final String KEY_MESSAGE_ID = "message_id"; - - private long messageId; - - public MmsSendJob(long messageId) { - this(new Job.Parameters.Builder() - .setQueue("mms-operation") - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(25) - .build(), - messageId); - } - - private MmsSendJob(@NonNull Job.Parameters parameters, long messageId) { - super(parameters); - this.messageId = messageId; - } - - @Override - public @NonNull - Data serialize() { - return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId).build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onSend() throws MmsException, NoSuchMessageException, IOException { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - OutgoingMediaMessage message = database.getOutgoingMessage(messageId); - - if (database.isSent(messageId)) { - Log.w(TAG, "Message " + messageId + " was already sent. Ignoring."); - return; - } - - try { - Log.i(TAG, "Sending message: " + messageId); - - SendReq pdu = constructSendPdu(message); - - validateDestinations(message, pdu); - - final byte[] pduBytes = getPduBytes(pdu); - final SendConf sendConf = new CompatMmsConnection(context).send(pduBytes, message.getSubscriptionId()); - final MmsSendResult result = getSendResult(sendConf, pdu); - - database.markAsSent(messageId, false); - markAttachmentsUploaded(messageId, message.getAttachments()); - - Log.i(TAG, "Sent message: " + messageId); - } catch (UndeliverableMessageException | IOException e) { - Log.w(TAG, e); - database.markAsSentFailed(messageId); - notifyMediaMessageDeliveryFailed(context, messageId); - } catch (InsecureFallbackApprovalException e) { - Log.w(TAG, e); - database.markAsPendingInsecureSmsFallback(messageId); - notifyMediaMessageDeliveryFailed(context, messageId); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return false; - } - - @Override - public void onCanceled() { - Log.i(TAG, "onCanceled() messageId: " + messageId); - DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageId); - notifyMediaMessageDeliveryFailed(context, messageId); - } - - private byte[] getPduBytes(SendReq message) - throws IOException, UndeliverableMessageException, InsecureFallbackApprovalException - { - byte[] pduBytes = new PduComposer(context, message).make(); - - if (pduBytes == null) { - throw new UndeliverableMessageException("PDU composition failed, null payload"); - } - - return pduBytes; - } - - private MmsSendResult getSendResult(SendConf conf, SendReq message) - throws UndeliverableMessageException - { - if (conf == null) { - throw new UndeliverableMessageException("No M-Send.conf received in response to send."); - } else if (conf.getResponseStatus() != PduHeaders.RESPONSE_STATUS_OK) { - throw new UndeliverableMessageException("Got bad response: " + conf.getResponseStatus()); - } else if (isInconsistentResponse(message, conf)) { - throw new UndeliverableMessageException("Mismatched response!"); - } else { - return new MmsSendResult(conf.getMessageId(), conf.getResponseStatus()); - } - } - - private boolean isInconsistentResponse(SendReq message, SendConf response) { - Log.i(TAG, "Comparing: " + Hex.toString(message.getTransactionId())); - Log.i(TAG, "With: " + Hex.toString(response.getTransactionId())); - return !Arrays.equals(message.getTransactionId(), response.getTransactionId()); - } - - private void validateDestinations(EncodedStringValue[] destinations) throws UndeliverableMessageException { - if (destinations == null) return; - - for (EncodedStringValue destination : destinations) { - if (destination == null || !NumberUtil.isValidSmsOrEmail(destination.getString())) { - throw new UndeliverableMessageException("Invalid destination: " + - (destination == null ? null : destination.getString())); - } - } - } - - private void validateDestinations(OutgoingMediaMessage media, SendReq message) throws UndeliverableMessageException { - validateDestinations(message.getTo()); - validateDestinations(message.getCc()); - validateDestinations(message.getBcc()); - - if (message.getTo() == null && message.getCc() == null && message.getBcc() == null) { - throw new UndeliverableMessageException("No to, cc, or bcc specified!"); - } - - if (media.isSecure()) { - throw new UndeliverableMessageException("Attempt to send encrypted MMS?"); - } - } - - private SendReq constructSendPdu(OutgoingMediaMessage message) - throws UndeliverableMessageException - { - SendReq req = new SendReq(); - String lineNumber = getMyNumber(context); - Address destination = message.getRecipient().getAddress(); - MediaConstraints mediaConstraints = MediaConstraints.getMmsMediaConstraints(message.getSubscriptionId()); - List scaledAttachments = scaleAndStripExifFromAttachments(mediaConstraints, message.getAttachments()); - - if (!TextUtils.isEmpty(lineNumber)) { - req.setFrom(new EncodedStringValue(lineNumber)); - } else { - req.setFrom(new EncodedStringValue(TextSecurePreferences.getLocalNumber(context))); - } - - if (destination.isMmsGroup()) { - List members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(destination.toGroupString(), false); - - for (Recipient member : members) { - if (message.getDistributionType() == ThreadDatabase.DistributionTypes.BROADCAST) { - req.addBcc(new EncodedStringValue(member.getAddress().serialize())); - } else { - req.addTo(new EncodedStringValue(member.getAddress().serialize())); - } - } - } else { - req.addTo(new EncodedStringValue(destination.serialize())); - } - - req.setDate(System.currentTimeMillis() / 1000); - - PduBody body = new PduBody(); - int size = 0; - - if (!TextUtils.isEmpty(message.getBody())) { - PduPart part = new PduPart(); - String name = String.valueOf(System.currentTimeMillis()); - part.setData(Util.toUtf8Bytes(message.getBody())); - part.setCharset(CharacterSets.UTF_8); - part.setContentType(ContentType.TEXT_PLAIN.getBytes()); - part.setContentId(name.getBytes()); - part.setContentLocation((name + ".txt").getBytes()); - part.setName((name + ".txt").getBytes()); - - body.addPart(part); - size += getPartSize(part); - } - - for (Attachment attachment : scaledAttachments) { - try { - if (attachment.getDataUri() == null) throw new IOException("Assertion failed, attachment for outgoing MMS has no data!"); - - String fileName = attachment.getFileName(); - PduPart part = new PduPart(); - - if (fileName == null) { - fileName = String.valueOf(Math.abs(Util.getSecureRandom().nextLong())); - String fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(attachment.getContentType()); - - if (fileExtension != null) fileName = fileName + "." + fileExtension; - } - - if (attachment.getContentType().startsWith("text")) { - part.setCharset(CharacterSets.UTF_8); - } - - part.setContentType(attachment.getContentType().getBytes()); - part.setContentLocation(fileName.getBytes()); - part.setName(fileName.getBytes()); - - int index = fileName.lastIndexOf("."); - String contentId = (index == -1) ? fileName : fileName.substring(0, index); - part.setContentId(contentId.getBytes()); - part.setData(Util.readFully(PartAuthority.getAttachmentStream(context, attachment.getDataUri()))); - - body.addPart(part); - size += getPartSize(part); - } catch (IOException e) { - Log.w(TAG, e); - } - } - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - SmilXmlSerializer.serialize(SmilHelper.createSmilDocument(body), out); - PduPart smilPart = new PduPart(); - smilPart.setContentId("smil".getBytes()); - smilPart.setContentLocation("smil.xml".getBytes()); - smilPart.setContentType(ContentType.APP_SMIL.getBytes()); - smilPart.setData(out.toByteArray()); - body.addPart(0, smilPart); - - req.setBody(body); - req.setMessageSize(size); - req.setMessageClass(PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes()); - req.setExpiry(7 * 24 * 60 * 60); - - try { - req.setPriority(PduHeaders.PRIORITY_NORMAL); - req.setDeliveryReport(PduHeaders.VALUE_NO); - req.setReadReport(PduHeaders.VALUE_NO); - } catch (InvalidHeaderValueException e) {} - - return req; - } - - private long getPartSize(PduPart part) { - return part.getName().length + part.getContentLocation().length + - part.getContentType().length + part.getData().length + - part.getContentId().length; - } - - private void notifyMediaMessageDeliveryFailed(Context context, long messageId) { - long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); - - if (recipient != null) { - ApplicationContext.getInstance(context).messageNotifier.notifyMessageDeliveryFailed(context, recipient, threadId); - } - } - - private String getMyNumber(Context context) throws UndeliverableMessageException { - try { - return Utils.getMyPhoneNumber(context); - } catch (SecurityException e) { - throw new UndeliverableMessageException(e); - } - } - - public static class Factory implements Job.Factory { - @Override - public @NonNull MmsSendJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MmsSendJob(parameters, data.getLong(KEY_MESSAGE_ID)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java deleted file mode 100644 index 053bc904ac..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.telephony.SmsMessage; - -import org.session.libsession.messaging.jobs.Data; -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint; -import org.session.libsignal.utilities.logging.Log; - -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.sms.IncomingTextMessage; - -import org.session.libsignal.utilities.Base64; -import org.session.libsession.utilities.TextSecurePreferences; - -import org.session.libsignal.libsignal.util.guava.Optional; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -public class SmsReceiveJob extends BaseJob { - - public static final String KEY = "SmsReceiveJob"; - - private static final String TAG = SmsReceiveJob.class.getSimpleName(); - - private static final String KEY_PDUS = "pdus"; - private static final String KEY_SUBSCRIPTION_ID = "subscription_id"; - - private @Nullable Object[] pdus; - - private int subscriptionId; - - public SmsReceiveJob(@Nullable Object[] pdus, int subscriptionId) { - this(new Job.Parameters.Builder() - .addConstraint(SqlCipherMigrationConstraint.KEY) - .setMaxAttempts(25) - .build(), - pdus, - subscriptionId); - } - - private SmsReceiveJob(@NonNull Job.Parameters parameters, @Nullable Object[] pdus, int subscriptionId) { - super(parameters); - - this.pdus = pdus; - this.subscriptionId = subscriptionId; - } - - @Override - public @NonNull - Data serialize() { - String[] encoded = new String[pdus.length]; - for (int i = 0; i < pdus.length; i++) { - encoded[i] = Base64.encodeBytes((byte[]) pdus[i]); - } - - return new Data.Builder().putStringArray(KEY_PDUS, encoded) - .putInt(KEY_SUBSCRIPTION_ID, subscriptionId) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws MigrationPendingException { - Log.i(TAG, "onRun()"); - - Optional message = assembleMessageFragments(pdus, subscriptionId); - - if (message.isPresent() && !isBlocked(message.get())) { - Optional insertResult = storeMessage(message.get()); - - if (insertResult.isPresent()) { - ApplicationContext.getInstance(context).messageNotifier.updateNotification(context, insertResult.get().getThreadId()); - } - } else if (message.isPresent()) { - Log.w(TAG, "*** Received blocked SMS, ignoring..."); - } else { - Log.w(TAG, "*** Failed to assemble message fragments!"); - } - } - - @Override - public void onCanceled() { - - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return exception instanceof MigrationPendingException; - } - - private boolean isBlocked(IncomingTextMessage message) { - if (message.getSender() != null) { - Recipient recipient = Recipient.from(context, message.getSender(), false); - return recipient.isBlocked(); - } - - return false; - } - - private Optional storeMessage(IncomingTextMessage message) throws MigrationPendingException { - SmsDatabase database = DatabaseFactory.getSmsDatabase(context); - database.ensureMigration(); - - if (TextSecurePreferences.getNeedsSqlCipherMigration(context)) { - throw new MigrationPendingException(); - } - - if (message.isSecureMessage()) { - IncomingTextMessage placeholder = new IncomingTextMessage(message, ""); - Optional insertResult = database.insertMessageInbox(placeholder); - database.markAsLegacyVersion(insertResult.get().getMessageId()); - - return insertResult; - } else { - return database.insertMessageInbox(message); - } - } - - private Optional assembleMessageFragments(@Nullable Object[] pdus, int subscriptionId) { - if (pdus == null) { - return Optional.absent(); - } - - List messages = new LinkedList<>(); - - for (Object pdu : pdus) { - messages.add(new IncomingTextMessage(context, SmsMessage.createFromPdu((byte[])pdu), subscriptionId)); - } - - if (messages.isEmpty()) { - return Optional.absent(); - } - - return Optional.of(new IncomingTextMessage(messages)); - } - - private class MigrationPendingException extends Exception { - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull SmsReceiveJob create(@NonNull Parameters parameters, @NonNull Data data) { - try { - int subscriptionId = data.getInt(KEY_SUBSCRIPTION_ID); - String[] encoded = data.getStringArray(KEY_PDUS); - Object[] pdus = new Object[encoded.length]; - - for (int i = 0; i < encoded.length; i++) { - pdus[i] = Base64.decode(encoded[i]); - } - - return new SmsReceiveJob(parameters, pdus, subscriptionId); - } catch (IOException e) { - throw new AssertionError(e); - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java deleted file mode 100644 index 54f5bc8c87..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSendJob.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import androidx.annotation.NonNull; -import android.telephony.PhoneNumberUtils; -import android.telephony.SmsManager; - -import org.session.libsession.messaging.jobs.Data; -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint; -import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint; - -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.NoSuchMessageException; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.model.SmsMessageRecord; -import org.thoughtcrime.securesms.service.SmsDeliveryListener; -import org.thoughtcrime.securesms.transport.UndeliverableMessageException; - -import org.session.libsession.messaging.threads.recipients.Recipient; -import org.session.libsession.utilities.NumberUtil; -import org.session.libsession.utilities.TextSecurePreferences; - -import java.util.ArrayList; - -public class SmsSendJob extends SendJob { - - public static final String KEY = "SmsSendJob"; - - private static final String TAG = SmsSendJob.class.getSimpleName(); - private static final int MAX_ATTEMPTS = 25; - private static final String KEY_MESSAGE_ID = "message_id"; - private static final String KEY_RUN_ATTEMPT = "run_attempt"; - - private long messageId; - private int runAttempt; - - public SmsSendJob(Context context, long messageId, String name) { - this(context, messageId, name, 0); - } - - public SmsSendJob(Context context, long messageId, String name, int runAttempt) { - this(constructParameters(context, name), messageId, runAttempt); - } - - private SmsSendJob(@NonNull Job.Parameters parameters, long messageId, int runAttempt) { - super(parameters); - - this.messageId = messageId; - this.runAttempt = runAttempt; - } - - @Override - public @NonNull - Data serialize() { - return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId) - .putInt(KEY_RUN_ATTEMPT, runAttempt) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onSend() throws NoSuchMessageException, TooManyRetriesException { - if (runAttempt >= MAX_ATTEMPTS) { - warn(TAG, "Hit the retry limit. Failing."); - throw new TooManyRetriesException(); - } - - SmsDatabase database = DatabaseFactory.getSmsDatabase(context); - SmsMessageRecord record = database.getMessage(messageId); - - if (!record.isPending() && !record.isFailed()) { - warn(TAG, "Message " + messageId + " was already sent. Ignoring."); - return; - } - - try { - log(TAG, "Sending message: " + messageId + " (attempt " + runAttempt + ")"); - deliver(record); - log(TAG, "Sent message: " + messageId); - } catch (UndeliverableMessageException ude) { - warn(TAG, ude); - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(record.getId()); - ApplicationContext.getInstance(context).messageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId()); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception throwable) { - return false; - } - - @Override - public void onCanceled() { - warn(TAG, "onCanceled() messageId: " + messageId); - long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId); - Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId); - - DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId); - - if (threadId != -1 && recipient != null) { - ApplicationContext.getInstance(context).messageNotifier.notifyMessageDeliveryFailed(context, recipient, threadId); - } - } - - private void deliver(SmsMessageRecord message) - throws UndeliverableMessageException - { - if (message.isSecure() || message.isKeyExchange() || message.isEndSession()) { - throw new UndeliverableMessageException("Trying to send a secure SMS?"); - } - - String recipient = message.getIndividualRecipient().getAddress().serialize(); - - // See issue #1516 for bug report, and discussion on commits related to #4833 for problems - // related to the original fix to #1516. This still may not be a correct fix if networks allow - // SMS/MMS sending to alphanumeric recipients other than email addresses, but should also - // help to fix issue #3099. - if (!NumberUtil.isValidEmail(recipient)) { - recipient = PhoneNumberUtils.stripSeparators(PhoneNumberUtils.convertKeypadLettersToDigits(recipient)); - } - - if (!NumberUtil.isValidSmsOrEmail(recipient)) { - throw new UndeliverableMessageException("Not a valid SMS destination! " + recipient); - } - - ArrayList messages = SmsManager.getDefault().divideMessage(message.getBody()); - ArrayList sentIntents = constructSentIntents(message.getId(), message.getType(), messages, false); - ArrayList deliveredIntents = constructDeliveredIntents(message.getId(), message.getType(), messages); - - // NOTE 11/04/14 -- There's apparently a bug where for some unknown recipients - // and messages, this will throw an NPE. We have no idea why, so we're just - // catching it and marking the message as a failure. That way at least it doesn't - // repeatedly crash every time you start the app. - try { - getSmsManagerFor(message.getSubscriptionId()).sendMultipartTextMessage(recipient, null, messages, sentIntents, deliveredIntents); - } catch (NullPointerException | IllegalArgumentException npe) { - warn(TAG, npe); - log(TAG, "Recipient: " + recipient); - log(TAG, "Message Parts: " + messages.size()); - - try { - for (int i=0;i constructSentIntents(long messageId, long type, - ArrayList messages, boolean secure) - { - ArrayList sentIntents = new ArrayList<>(messages.size()); - - for (String ignored : messages) { - sentIntents.add(PendingIntent.getBroadcast(context, 0, - constructSentIntent(context, messageId, type, secure, false), - 0)); - } - - return sentIntents; - } - - private ArrayList constructDeliveredIntents(long messageId, long type, ArrayList messages) { - if (!TextSecurePreferences.isSmsDeliveryReportsEnabled(context)) { - return null; - } - - ArrayList deliveredIntents = new ArrayList<>(messages.size()); - - for (String ignored : messages) { - deliveredIntents.add(PendingIntent.getBroadcast(context, 0, - constructDeliveredIntent(context, messageId, type), - 0)); - } - - return deliveredIntents; - } - - private Intent constructSentIntent(Context context, long messageId, long type, - boolean upgraded, boolean push) - { - Intent pending = new Intent(SmsDeliveryListener.SENT_SMS_ACTION, - Uri.parse("custom://" + messageId + System.currentTimeMillis()), - context, SmsDeliveryListener.class); - - pending.putExtra("type", type); - pending.putExtra("message_id", messageId); - pending.putExtra("run_attempt", Math.max(runAttempt, getRunAttempt())); - pending.putExtra("upgraded", upgraded); - pending.putExtra("push", push); - - return pending; - } - - private Intent constructDeliveredIntent(Context context, long messageId, long type) { - Intent pending = new Intent(SmsDeliveryListener.DELIVERED_SMS_ACTION, - Uri.parse("custom://" + messageId + System.currentTimeMillis()), - context, SmsDeliveryListener.class); - pending.putExtra("type", type); - pending.putExtra("message_id", messageId); - - return pending; - } - - private SmsManager getSmsManagerFor(int subscriptionId) { - if (Build.VERSION.SDK_INT >= 22 && subscriptionId != -1) { - return SmsManager.getSmsManagerForSubscriptionId(subscriptionId); - } else { - return SmsManager.getDefault(); - } - } - - private static Job.Parameters constructParameters(@NonNull Context context, String name) { - String constraint = TextSecurePreferences.isWifiSmsEnabled(context) ? NetworkOrCellServiceConstraint.KEY - : CellServiceConstraint.KEY; - return new Job.Parameters.Builder() - .setMaxAttempts(MAX_ATTEMPTS) - .setQueue(name) - .addConstraint(constraint) - .build(); - } - - private static class TooManyRetriesException extends Exception { } - - public static class Factory implements Job.Factory { - @Override - public @NonNull SmsSendJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new SmsSendJob(parameters, data.getLong(KEY_MESSAGE_ID), data.getInt(KEY_RUN_ATTEMPT)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java deleted file mode 100644 index 6d3473053b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsSentJob.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.app.Activity; -import androidx.annotation.NonNull; -import android.telephony.SmsManager; - -import org.session.libsession.messaging.jobs.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.session.libsignal.utilities.logging.Log; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.NoSuchMessageException; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.model.SmsMessageRecord; -import org.thoughtcrime.securesms.service.SmsDeliveryListener; - -public class SmsSentJob extends BaseJob { - - public static final String KEY = "SmsSentJob"; - - private static final String TAG = SmsSentJob.class.getSimpleName(); - - private static final String KEY_MESSAGE_ID = "message_id"; - private static final String KEY_ACTION = "action"; - private static final String KEY_RESULT = "result"; - private static final String KEY_RUN_ATTEMPT = "run_attempt"; - - private long messageId; - private String action; - private int result; - private int runAttempt; - - public SmsSentJob(long messageId, String action, int result, int runAttempt) { - this(new Job.Parameters.Builder().build(), - messageId, - action, - result, - runAttempt); - } - - private SmsSentJob(@NonNull Job.Parameters parameters, long messageId, String action, int result, int runAttempt) { - super(parameters); - - this.messageId = messageId; - this.action = action; - this.result = result; - this.runAttempt = runAttempt; - } - - @Override - public @NonNull - Data serialize() { - return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId) - .putString(KEY_ACTION, action) - .putInt(KEY_RESULT, result) - .putInt(KEY_RUN_ATTEMPT, runAttempt) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() { - Log.i(TAG, "Got SMS callback: " + action + " , " + result); - - switch (action) { - case SmsDeliveryListener.SENT_SMS_ACTION: - handleSentResult(messageId, result); - break; - case SmsDeliveryListener.DELIVERED_SMS_ACTION: - handleDeliveredResult(messageId, result); - break; - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception throwable) { - return false; - } - - @Override - public void onCanceled() { - } - - private void handleDeliveredResult(long messageId, int result) { - DatabaseFactory.getSmsDatabase(context).markStatus(messageId, result); - } - - private void handleSentResult(long messageId, int result) { - try { - SmsDatabase database = DatabaseFactory.getSmsDatabase(context); - SmsMessageRecord record = database.getMessage(messageId); - - switch (result) { - case Activity.RESULT_OK: - database.markAsSent(messageId, false); - break; - case SmsManager.RESULT_ERROR_NO_SERVICE: - case SmsManager.RESULT_ERROR_RADIO_OFF: - Log.w(TAG, "Service connectivity problem, requeuing..."); - ApplicationContext.getInstance(context) - .getJobManager() - .add(new SmsSendJob(context, messageId, record.getIndividualRecipient().getAddress().serialize(), runAttempt + 1)); - break; - default: - database.markAsSentFailed(messageId); - ApplicationContext.getInstance(context).messageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId()); - } - } catch (NoSuchMessageException e) { - Log.w(TAG, e); - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull SmsSentJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new SmsSentJob(parameters, - data.getLong(KEY_MESSAGE_ID), - data.getString(KEY_ACTION), - data.getInt(KEY_RESULT), - data.getInt(KEY_RUN_ATTEMPT)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/CompatMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/CompatMmsConnection.java deleted file mode 100644 index 7ea011f1d9..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/CompatMmsConnection.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.thoughtcrime.securesms.mms; - -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import org.session.libsignal.utilities.logging.Log; - -import com.google.android.mms.pdu_alt.PduHeaders; -import com.google.android.mms.pdu_alt.RetrieveConf; -import com.google.android.mms.pdu_alt.SendConf; - -import org.thoughtcrime.securesms.transport.UndeliverableMessageException; - -import java.io.IOException; - -public class CompatMmsConnection implements OutgoingMmsConnection, IncomingMmsConnection { - private static final String TAG = CompatMmsConnection.class.getSimpleName(); - - private Context context; - - public CompatMmsConnection(Context context) { - this.context = context; - } - - @Nullable - @Override - public SendConf send(@NonNull byte[] pduBytes, int subscriptionId) - throws UndeliverableMessageException - { - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP_MR1) { - try { - Log.i(TAG, "Sending via Lollipop API"); - return new OutgoingLollipopMmsConnection(context).send(pduBytes, subscriptionId); - } catch (UndeliverableMessageException e) { - Log.w(TAG, e); - } - - Log.i(TAG, "Falling back to legacy connection..."); - } - - if (subscriptionId == -1) { - Log.i(TAG, "Sending via legacy connection"); - try { - SendConf result = new OutgoingLegacyMmsConnection(context).send(pduBytes, subscriptionId); - - if (result != null && result.getResponseStatus() == PduHeaders.RESPONSE_STATUS_OK) { - return result; - } else { - Log.w(TAG, "Got bad legacy response: " + (result != null ? result.getResponseStatus() : null)); - } - } catch (UndeliverableMessageException | ApnUnavailableException e) { - Log.w(TAG, e); - } - } - - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && VERSION.SDK_INT < VERSION_CODES.LOLLIPOP_MR1) { - Log.i(TAG, "Falling back to sending via Lollipop API"); - return new OutgoingLollipopMmsConnection(context).send(pduBytes, subscriptionId); - } - - throw new UndeliverableMessageException("Both lollipop and legacy connections failed..."); - } - - @Nullable - @Override - public RetrieveConf retrieve(@NonNull String contentLocation, - byte[] transactionId, - int subscriptionId) - throws MmsException, MmsRadioException, ApnUnavailableException, IOException - { - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP_MR1) { - Log.i(TAG, "Receiving via Lollipop API"); - try { - return new IncomingLollipopMmsConnection(context).retrieve(contentLocation, transactionId, subscriptionId); - } catch (MmsException e) { - Log.w(TAG, e); - } - - Log.i(TAG, "Falling back to receiving via legacy connection"); - } - - if (VERSION.SDK_INT < 22 || subscriptionId == -1) { - Log.i(TAG, "Receiving via legacy API"); - try { - return new IncomingLegacyMmsConnection(context).retrieve(contentLocation, transactionId, subscriptionId); - } catch (MmsRadioException | ApnUnavailableException | IOException e) { - Log.w(TAG, e); - } - } - - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && VERSION.SDK_INT < VERSION_CODES.LOLLIPOP_MR1) { - Log.i(TAG, "Falling back to receiving via Lollipop API"); - return new IncomingLollipopMmsConnection(context).retrieve(contentLocation, transactionId, subscriptionId); - } - - throw new IOException("Both lollipop and fallback APIs failed..."); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java deleted file mode 100644 index a9274d0820..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Copyright (C) 2015 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.mms; - -import android.content.Context; -import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import org.session.libsignal.utilities.logging.Log; - -import com.google.android.mms.InvalidHeaderValueException; -import com.google.android.mms.pdu_alt.NotifyRespInd; -import com.google.android.mms.pdu_alt.PduComposer; -import com.google.android.mms.pdu_alt.PduHeaders; -import com.google.android.mms.pdu_alt.PduParser; -import com.google.android.mms.pdu_alt.RetrieveConf; - -import org.apache.http.Header; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGetHC4; -import org.apache.http.client.methods.HttpUriRequest; - -import java.io.IOException; -import java.util.Arrays; - - -@SuppressWarnings("deprecation") -public class IncomingLegacyMmsConnection extends LegacyMmsConnection implements IncomingMmsConnection { - private static final String TAG = IncomingLegacyMmsConnection.class.getSimpleName(); - - public IncomingLegacyMmsConnection(Context context) throws ApnUnavailableException { - super(context); - } - - private HttpUriRequest constructRequest(Apn contentApn, boolean useProxy) throws IOException { - HttpGetHC4 request; - - try { - request = new HttpGetHC4(contentApn.getMmsc()); - } catch (IllegalArgumentException e) { - // #7339 - throw new IOException(e); - } - - for (Header header : getBaseHeaders()) { - request.addHeader(header); - } - - if (useProxy) { - HttpHost proxy = new HttpHost(contentApn.getProxy(), contentApn.getPort()); - request.setConfig(RequestConfig.custom().setProxy(proxy).build()); - } - - return request; - } - - @Override - public @Nullable RetrieveConf retrieve(@NonNull String contentLocation, - byte[] transactionId, int subscriptionId) - throws MmsRadioException, ApnUnavailableException, IOException - { - MmsRadio radio = MmsRadio.getInstance(context); - Apn contentApn = new Apn(contentLocation, apn.getProxy(), Integer.toString(apn.getPort()), apn.getUsername(), apn.getPassword()); - - if (isDirectConnect()) { - Log.i(TAG, "Connecting directly..."); - try { - return retrieve(contentApn, transactionId, false, false); - } catch (IOException | ApnUnavailableException e) { - Log.w(TAG, e); - } - } - - Log.i(TAG, "Changing radio to MMS mode.."); - radio.connect(); - - try { - Log.i(TAG, "Downloading in MMS mode with proxy..."); - - try { - return retrieve(contentApn, transactionId, true, true); - } catch (IOException | ApnUnavailableException e) { - Log.w(TAG, e); - } - - Log.i(TAG, "Downloading in MMS mode without proxy..."); - - return retrieve(contentApn, transactionId, true, false); - - } finally { - radio.disconnect(); - } - } - - public RetrieveConf retrieve(Apn contentApn, byte[] transactionId, boolean usingMmsRadio, boolean useProxyIfAvailable) - throws IOException, ApnUnavailableException - { - byte[] pdu = null; - - final boolean useProxy = useProxyIfAvailable && contentApn.hasProxy(); - final String targetHost = useProxy - ? contentApn.getProxy() - : Uri.parse(contentApn.getMmsc()).getHost(); - if (checkRouteToHost(context, targetHost, usingMmsRadio)) { - Log.i(TAG, "got successful route to host " + targetHost); - pdu = execute(constructRequest(contentApn, useProxy)); - } - - if (pdu == null) { - throw new IOException("Connection manager could not obtain route to host."); - } - - RetrieveConf retrieved = (RetrieveConf)new PduParser(pdu).parse(); - - if (retrieved == null) { - Log.w(TAG, "Couldn't parse PDU, byte response: " + Arrays.toString(pdu)); - Log.w(TAG, "Couldn't parse PDU, ASCII: " + new String(pdu)); - throw new IOException("Bad retrieved PDU"); - } - - sendRetrievedAcknowledgement(transactionId, usingMmsRadio, useProxy); - return retrieved; - } - - private void sendRetrievedAcknowledgement(byte[] transactionId, - boolean usingRadio, - boolean useProxy) - throws ApnUnavailableException - { - try { - NotifyRespInd notifyResponse = new NotifyRespInd(PduHeaders.CURRENT_MMS_VERSION, - transactionId, - PduHeaders.STATUS_RETRIEVED); - - OutgoingLegacyMmsConnection connection = new OutgoingLegacyMmsConnection(context); - connection.sendNotificationReceived(new PduComposer(context, notifyResponse).make(), usingRadio, useProxy); - } catch (InvalidHeaderValueException | IOException e) { - Log.w(TAG, e); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java deleted file mode 100644 index 08572eade5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Copyright (C) 2015 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.mms; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import org.session.libsignal.utilities.logging.Log; - -import com.google.android.mms.pdu_alt.PduParser; -import com.google.android.mms.pdu_alt.SendConf; - -import org.apache.http.Header; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpPostHC4; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.entity.ByteArrayEntityHC4; -import org.thoughtcrime.securesms.transport.UndeliverableMessageException; - -import java.io.IOException; - - -@SuppressWarnings("deprecation") -public class OutgoingLegacyMmsConnection extends LegacyMmsConnection implements OutgoingMmsConnection { - private final static String TAG = OutgoingLegacyMmsConnection.class.getSimpleName(); - - public OutgoingLegacyMmsConnection(Context context) throws ApnUnavailableException { - super(context); - } - - private HttpUriRequest constructRequest(byte[] pduBytes, boolean useProxy) - throws IOException - { - try { - HttpPostHC4 request = new HttpPostHC4(apn.getMmsc()); - for (Header header : getBaseHeaders()) { - request.addHeader(header); - } - - request.setEntity(new ByteArrayEntityHC4(pduBytes)); - if (useProxy) { - HttpHost proxy = new HttpHost(apn.getProxy(), apn.getPort()); - request.setConfig(RequestConfig.custom().setProxy(proxy).build()); - } - return request; - } catch (IllegalArgumentException iae) { - throw new IOException(iae); - } - } - - public void sendNotificationReceived(byte[] pduBytes, boolean usingMmsRadio, boolean useProxyIfAvailable) - throws IOException - { - sendBytes(pduBytes, usingMmsRadio, useProxyIfAvailable); - } - - @Override - public @Nullable SendConf send(@NonNull byte[] pduBytes, int subscriptionId) throws UndeliverableMessageException { - try { - MmsRadio radio = MmsRadio.getInstance(context); - - if (isDirectConnect()) { - Log.i(TAG, "Sending MMS directly without radio change..."); - try { - return send(pduBytes, false, false); - } catch (IOException e) { - Log.w(TAG, e); - } - } - - Log.i(TAG, "Sending MMS with radio change and proxy..."); - radio.connect(); - - try { - try { - return send(pduBytes, true, true); - } catch (IOException e) { - Log.w(TAG, e); - } - - Log.i(TAG, "Sending MMS with radio change and without proxy..."); - - try { - return send(pduBytes, true, false); - } catch (IOException ioe) { - Log.w(TAG, ioe); - throw new UndeliverableMessageException(ioe); - } - } finally { - radio.disconnect(); - } - - } catch (MmsRadioException e) { - Log.w(TAG, e); - throw new UndeliverableMessageException(e); - } - - } - - private SendConf send(byte[] pduBytes, boolean useMmsRadio, boolean useProxyIfAvailable) throws IOException { - byte[] response = sendBytes(pduBytes, useMmsRadio, useProxyIfAvailable); - return (SendConf) new PduParser(response).parse(); - } - - private byte[] sendBytes(byte[] pduBytes, boolean useMmsRadio, boolean useProxyIfAvailable) throws IOException { - final boolean useProxy = useProxyIfAvailable && apn.hasProxy(); - final String targetHost = useProxy - ? apn.getProxy() - : Uri.parse(apn.getMmsc()).getHost(); - - Log.i(TAG, "Sending MMS of length: " + pduBytes.length - + (useMmsRadio ? ", using mms radio" : "") - + (useProxy ? ", using proxy" : "")); - - try { - if (checkRouteToHost(context, targetHost, useMmsRadio)) { - Log.i(TAG, "got successful route to host " + targetHost); - byte[] response = execute(constructRequest(pduBytes, useProxy)); - if (response != null) return response; - } - } catch (IOException ioe) { - Log.w(TAG, ioe); - } - throw new IOException("Connection manager could not obtain route to host."); - } - - - public static boolean isConnectionPossible(Context context) { - try { - ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = connectivityManager.getNetworkInfo(MmsRadio.TYPE_MOBILE_MMS); - if (networkInfo == null) { - Log.w(TAG, "MMS network info was null, unsupported by this device"); - return false; - } - - getApn(context); - return true; - } catch (ApnUnavailableException e) { - Log.w(TAG, e); - return false; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java deleted file mode 100644 index 65e0142948..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.service; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.provider.Telephony; -import org.session.libsignal.utilities.logging.Log; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.jobs.MmsReceiveJob; -import org.session.libsession.utilities.Util; - -public class MmsListener extends BroadcastReceiver { - - private static final String TAG = MmsListener.class.getSimpleName(); - - private boolean isRelevant(Context context, Intent intent) { - if (!ApplicationMigrationService.isDatabaseImported(context)) { - return false; - } - - if (Telephony.Sms.Intents.WAP_PUSH_RECEIVED_ACTION.equals(intent.getAction()) && Util.isDefaultSmsProvider(context)) { - return false; - } - - return false; - } - - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "Got MMS broadcast..." + intent.getAction()); - - if ((Telephony.Sms.Intents.WAP_PUSH_DELIVER_ACTION.equals(intent.getAction()) && - Util.isDefaultSmsProvider(context)) || - (Telephony.Sms.Intents.WAP_PUSH_RECEIVED_ACTION.equals(intent.getAction()) && - isRelevant(context, intent))) - { - Log.i(TAG, "Relevant!"); - int subscriptionId = intent.getExtras().getInt("subscription", -1); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MmsReceiveJob(intent.getByteArrayExtra("data"), subscriptionId)); - - abortBroadcast(); - } - } - - - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/SmsDeliveryListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/SmsDeliveryListener.java deleted file mode 100644 index c8e12ac054..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/SmsDeliveryListener.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.thoughtcrime.securesms.service; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.telephony.SmsMessage; - -import org.thoughtcrime.securesms.jobmanager.JobManager; -import org.session.libsignal.utilities.logging.Log; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.jobs.SmsSentJob; - -public class SmsDeliveryListener extends BroadcastReceiver { - - private static final String TAG = SmsDeliveryListener.class.getSimpleName(); - - public static final String SENT_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SENT_SMS_ACTION"; - public static final String DELIVERED_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DELIVERED_SMS_ACTION"; - - @Override - public void onReceive(Context context, Intent intent) { - JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - long messageId = intent.getLongExtra("message_id", -1); - int runAttempt = intent.getIntExtra("run_attempt", 0); - - switch (intent.getAction()) { - case SENT_SMS_ACTION: - int result = getResultCode(); - - jobManager.add(new SmsSentJob(messageId, SENT_SMS_ACTION, result, runAttempt)); - break; - case DELIVERED_SMS_ACTION: - byte[] pdu = intent.getByteArrayExtra("pdu"); - - if (pdu == null) { - Log.w(TAG, "No PDU in delivery receipt!"); - break; - } - - SmsMessage message = SmsMessage.createFromPdu(pdu); - - if (message == null) { - Log.w(TAG, "Delivery receipt failed to parse!"); - break; - } - - int status = message.getStatus(); - - Log.i(TAG, "Original status: " + status); - - // Note: https://developer.android.com/reference/android/telephony/SmsMessage.html#getStatus() - // " CDMA: For not interfering with status codes from GSM, the value is shifted to the bits 31-16" - // Note: https://stackoverflow.com/a/33240109 - if ("3gpp2".equals(intent.getStringExtra("format"))) { - Log.w(TAG, "Correcting for CDMA delivery receipt..."); - if (status >> 24 <= 0) status = SmsDatabase.Status.STATUS_COMPLETE; - else if (status >> 24 == 2) status = SmsDatabase.Status.STATUS_PENDING; - else if (status >> 24 == 3) status = SmsDatabase.Status.STATUS_FAILED; - } - - jobManager.add(new SmsSentJob(messageId, DELIVERED_SMS_ACTION, status, runAttempt)); - break; - default: - Log.w(TAG, "Unknown action: " + intent.getAction()); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java deleted file mode 100644 index 9014086795..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.service; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.provider.Telephony; -import android.telephony.SmsMessage; -import org.session.libsignal.utilities.logging.Log; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.jobs.SmsReceiveJob; -import org.session.libsession.utilities.Util; - -public class SmsListener extends BroadcastReceiver { - - private static final String SMS_RECEIVED_ACTION = Telephony.Sms.Intents.SMS_RECEIVED_ACTION; - private static final String SMS_DELIVERED_ACTION = Telephony.Sms.Intents.SMS_DELIVER_ACTION; - - private boolean isExemption(SmsMessage message, String messageBody) { - - // ignore CLASS0 ("flash") messages - if (message.getMessageClass() == SmsMessage.MessageClass.CLASS_0) - return true; - - // ignore OTP messages from Sparebank1 (Norwegian bank) - if (messageBody.startsWith("Sparebank1://otp?")) { - return true; - } - - return - message.getOriginatingAddress().length() < 7 && - (messageBody.toUpperCase().startsWith("//ANDROID:") || // Sprint Visual Voicemail - messageBody.startsWith("//BREW:")); //BREW stands for “Binary Runtime Environment for Wireless" - } - - private SmsMessage getSmsMessageFromIntent(Intent intent) { - Bundle bundle = intent.getExtras(); - Object[] pdus = (Object[])bundle.get("pdus"); - - if (pdus == null || pdus.length == 0) - return null; - - return SmsMessage.createFromPdu((byte[])pdus[0]); - } - - private String getSmsMessageBodyFromIntent(Intent intent) { - Bundle bundle = intent.getExtras(); - Object[] pdus = (Object[])bundle.get("pdus"); - StringBuilder bodyBuilder = new StringBuilder(); - - if (pdus == null) - return null; - - for (Object pdu : pdus) - bodyBuilder.append(SmsMessage.createFromPdu((byte[])pdu).getDisplayMessageBody()); - - return bodyBuilder.toString(); - } - - private boolean isRelevant(Context context, Intent intent) { - SmsMessage message = getSmsMessageFromIntent(intent); - String messageBody = getSmsMessageBodyFromIntent(intent); - - if (message == null && messageBody == null) - return false; - - if (isExemption(message, messageBody)) - return false; - - if (!ApplicationMigrationService.isDatabaseImported(context)) - return false; - - if (SMS_RECEIVED_ACTION.equals(intent.getAction()) && Util.isDefaultSmsProvider(context)) { - return false; - } - - return false; - } - - @Override - public void onReceive(Context context, Intent intent) { - Log.i("SMSListener", "Got SMS broadcast..."); - - if ((intent.getAction().equals(SMS_DELIVERED_ACTION)) || - (intent.getAction().equals(SMS_RECEIVED_ACTION)) && isRelevant(context, intent)) - { - Log.i("SmsListener", "Constructing SmsReceiveJob..."); - Object[] pdus = (Object[]) intent.getExtras().get("pdus"); - int subscriptionId = intent.getExtras().getInt("subscription", -1); - - ApplicationContext.getInstance(context).getJobManager().add(new SmsReceiveJob(pdus, subscriptionId)); - - abortBroadcast(); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java index 85a34df8c9..cc526313a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java @@ -33,11 +33,9 @@ import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.jobmanager.JobManager; -import org.thoughtcrime.securesms.jobs.MmsSendJob; import org.thoughtcrime.securesms.jobs.PushGroupSendJob; import org.thoughtcrime.securesms.jobs.PushMediaSendJob; import org.thoughtcrime.securesms.jobs.PushTextSendJob; -import org.thoughtcrime.securesms.jobs.SmsSendJob; import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; @@ -142,13 +140,11 @@ public class MessageSender { private static void sendTextPush(Context context, Recipient recipient, long messageId) { JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); jobManager.add(new PushTextSendJob(messageId, recipient.getAddress())); -// MultiDeviceProtocol.sendTextPush(context, recipient, messageId); } private static void sendMediaPush(Context context, Recipient recipient, long messageId) { JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); PushMediaSendJob.enqueue(context, jobManager, messageId, recipient.getAddress()); -// MultiDeviceProtocol.sendMediaPush(context, recipient, messageId); } private static void sendGroupPush(Context context, Recipient recipient, long messageId, Address filterAddress) { @@ -156,48 +152,6 @@ public class MessageSender { PushGroupSendJob.enqueue(context, jobManager, messageId, recipient.getAddress(), filterAddress); } - private static void sendSms(Context context, Recipient recipient, long messageId) { - JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - jobManager.add(new SmsSendJob(context, messageId, recipient.getName())); - } - - private static void sendMms(Context context, long messageId) { - JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - jobManager.add(new MmsSendJob(messageId)); - } - - private static boolean isPushTextSend(Context context, Recipient recipient, boolean keyExchange) { - return true; - // Loki - Original code - // ======== -// if (!TextSecurePreferences.isPushRegistered(context)) { -// return false; -// } -// -// if (keyExchange) { -// return false; -// } -// -// return isPushDestination(context, recipient); - // ======== - } - - private static boolean isPushMediaSend(Context context, Recipient recipient) { - return true; - // Loki - Original code - // ======== -// if (!TextSecurePreferences.isPushRegistered(context)) { -// return false; -// } -// -// if (recipient.isGroupRecipient()) { -// return false; -// } -// -// return isPushDestination(context, recipient); - // ======== - } - private static boolean isGroupPushSend(Recipient recipient) { return recipient.getAddress().isGroup() && !recipient.getAddress().isMmsGroup(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Util.java b/app/src/main/java/org/thoughtcrime/securesms/util/Util.java index b21fbd17fa..e2c417f172 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Util.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Util.java @@ -25,7 +25,6 @@ import android.os.Build.VERSION_CODES; import android.text.TextUtils; import org.thoughtcrime.securesms.components.ComposeText; -import org.thoughtcrime.securesms.mms.OutgoingLegacyMmsConnection; import network.loki.messenger.BuildConfig; @@ -70,6 +69,6 @@ public class Util { @TargetApi(VERSION_CODES.LOLLIPOP) public static boolean isMmsCapable(Context context) { - return (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) || OutgoingLegacyMmsConnection.isConnectionPossible(context); + return VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP; } }