diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 34ab00ba8c..ee2cb903ee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1203,18 +1203,6 @@ - - - - - - - - - @@ -1222,20 +1210,6 @@ - - - - - - - - - - - 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 10835aefdf..b701c61231 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -115,7 +115,6 @@ import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy; import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicyEnforcer; import org.thoughtcrime.securesms.jobmanager.JobManager; 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.keyvalue.SignalStore; @@ -2436,10 +2435,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo 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"); - ApplicationDependencies.getJobManager().add(new MmsDownloadJob(messageRecord.getId(), - messageRecord.getThreadId(), - false)); + Log.w(TAG, "Ignoring MMS download."); } else { Log.i(TAG, "Scheduling push attachment downloads for " + slides.size() + " items"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index 98d92062ad..f6a5260e4b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -2789,39 +2789,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat return insertMessageInbox(retrieved, "", threadId, type, edittedMediaMessage, notifyObservers) } - fun insertMessageInbox(notification: NotificationInd, subscriptionId: Int): Pair { - Log.i(TAG, "Message received type: " + notification.messageType) - - val threadId = getThreadIdFor(notification) - - val authorId: String = if (notification.from != null) { - Recipient.external(context, Util.toIsoString(notification.from.textString)).id.serialize() - } else { - RecipientId.UNKNOWN.serialize() - } - - val messageId = writableDatabase - .insertInto(TABLE_NAME) - .values( - MMS_CONTENT_LOCATION to notification.contentLocation.toIsoString(), - DATE_SENT to System.currentTimeMillis(), - MMS_EXPIRY to if (notification.expiry != -1L) notification.expiry else null, - MMS_MESSAGE_SIZE to if (notification.messageSize != -1L) notification.messageSize else null, - MMS_TRANSACTION_ID to notification.transactionId.toIsoString(), - MMS_MESSAGE_TYPE to if (notification.messageType != 0) notification.messageType else null, - FROM_RECIPIENT_ID to authorId, - TYPE to MessageTypes.BASE_INBOX_TYPE, - THREAD_ID to threadId, - MMS_STATUS to MmsStatus.DOWNLOAD_INITIALIZED, - DATE_RECEIVED to generatePduCompatTimestamp(System.currentTimeMillis()), - READ to if (Util.isDefaultSmsProvider(context)) 0 else 1, - SMS_SUBSCRIPTION_ID to subscriptionId - ) - .run(SQLiteDatabase.CONFLICT_IGNORE) - - return Pair(messageId, threadId) - } - fun insertChatSessionRefreshedMessage(recipientId: RecipientId, senderDeviceId: Long, sentTimestamp: Long): InsertResult { val threadId = threads.getOrCreateThreadIdFor(Recipient.resolved(recipientId)) var type = MessageTypes.SECURE_MESSAGE_BIT or MessageTypes.PUSH_MESSAGE_BIT 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 655e60d36f..bbff66c7c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -135,8 +135,6 @@ public final class JobManagerFactories { put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); put(LocalBackupJobApi29.KEY, new LocalBackupJobApi29.Factory()); put(MarkerJob.KEY, new MarkerJob.Factory()); - put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory()); - put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory()); put(MmsSendJob.KEY, new MmsSendJob.Factory()); put(MultiDeviceBlockedUpdateJob.KEY, new MultiDeviceBlockedUpdateJob.Factory()); put(MultiDeviceCallLinkSyncJob.KEY, new MultiDeviceCallLinkSyncJob.Factory()); @@ -204,7 +202,6 @@ public final class JobManagerFactories { put(MultiDeviceStorySendSyncJob.KEY, new MultiDeviceStorySendSyncJob.Factory()); put(ResetSvrGuessCountJob.KEY, new ResetSvrGuessCountJob.Factory()); put(ServiceOutageDetectionJob.KEY, new ServiceOutageDetectionJob.Factory()); - put(SmsReceiveJob.KEY, new SmsReceiveJob.Factory()); put(SmsSendJob.KEY, new SmsSendJob.Factory()); put(SmsSentJob.KEY, new SmsSentJob.Factory()); put(StickerDownloadJob.KEY, new StickerDownloadJob.Factory()); @@ -303,6 +300,9 @@ public final class JobManagerFactories { put("PushDecryptDrainedJob", new FailingJob.Factory()); put("PushProcessJob", new FailingJob.Factory()); put("DecryptionsDrainedMigrationJob", new PassingMigrationJob.Factory()); + put("MmsReceiveJob", new FailingJob.Factory()); + put("MmsDownloadJob", new FailingJob.Factory()); + put("SmsReceiveJob", new FailingJob.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 d1ab286f7f..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ /dev/null @@ -1,285 +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.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.attachments.UriAttachment; -import org.thoughtcrime.securesms.contactshare.Contact; -import org.thoughtcrime.securesms.contactshare.VCardUtil; -import org.thoughtcrime.securesms.database.AttachmentTable; -import org.thoughtcrime.securesms.database.MessageTable; -import org.thoughtcrime.securesms.database.MessageTable.InsertResult; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.jobmanager.JsonJobData; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -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.notifications.v2.ConversationId; -import org.thoughtcrime.securesms.providers.BlobProvider; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.service.KeyCachingService; -import org.thoughtcrime.securesms.util.MediaUtil; -import org.thoughtcrime.securesms.util.Util; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -public class MmsDownloadJob extends BaseJob { - - public static final String KEY = "MmsDownloadJob"; - - private static final String TAG = Log.tag(MmsDownloadJob.class); - - 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; - - 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; - } - - @Override - public @Nullable byte[] serialize() { - return new JsonJobData.Builder().putLong(KEY_MESSAGE_ID, messageId) - .putLong(KEY_THREAD_ID, threadId) - .putBoolean(KEY_AUTOMATIC, automatic) - .serialize(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onAdded() { - if (automatic && KeyCachingService.isLocked(context)) { - SignalDatabase.messages().markIncomingNotificationReceived(threadId); - ApplicationDependencies.getMessageNotifier().updateNotification(context); - } - } - - @Override - public void onRun() { - if (SignalStore.account().getE164() == null) { - throw new NotReadyException(); - } - - MessageTable database = SignalDatabase.messages(); - 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 (!SignalStore.account().isRegistered()) { - throw new MmsException("Not registered"); - } - - database.markDownloadState(messageId, MessageTable.MmsStatus.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, MessageTable.MmsStatus.DOWNLOAD_APN_UNAVAILABLE, - automatic); - } catch (MmsException e) { - Log.w(TAG, e); - handleDownloadError(messageId, threadId, - MessageTable.MmsStatus.DOWNLOAD_HARD_FAILURE, - automatic); - } catch (MmsRadioException | IOException e) { - Log.w(TAG, e); - handleDownloadError(messageId, threadId, - MessageTable.MmsStatus.DOWNLOAD_SOFT_FAILURE, - automatic); - } - } - - @Override - public void onFailure() { - MessageTable database = SignalDatabase.messages(); - database.markDownloadState(messageId, MessageTable.MmsStatus.DOWNLOAD_SOFT_FAILURE); - - if (automatic) { - database.markIncomingNotificationReceived(threadId); - ApplicationDependencies.getMessageNotifier().updateNotification(context, ConversationId.forConversation(threadId)); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return false; - } - - private void storeRetrievedMms(String contentLocation, - long messageId, long threadId, RetrieveConf retrieved, - int subscriptionId, @Nullable RecipientId notificationFrom) - throws MmsException - { - MessageTable database = SignalDatabase.messages(); - Optional group = Optional.empty(); - Set members = new HashSet<>(); - String body = null; - List attachments = new LinkedList<>(); - List sharedContacts = new LinkedList<>(); - - RecipientId from = null; - - if (retrieved.getFrom() != null) { - from = Recipient.external(context, Util.toIsoString(retrieved.getFrom().getTextString())).getId(); - } else if (notificationFrom != null) { - from = notificationFrom; - } - - if (retrieved.getTo() != null) { - for (EncodedStringValue toValue : retrieved.getTo()) { - members.add(Recipient.external(context, Util.toIsoString(toValue.getTextString())).getId()); - } - } - - if (retrieved.getCc() != null) { - for (EncodedStringValue ccValue : retrieved.getCc()) { - members.add(Recipient.external(context, Util.toIsoString(ccValue.getTextString())).getId()); - } - } - - if (from != null) { - members.add(from); - } - members.add(Recipient.self().getId()); - - if (retrieved.getBody() != null) { - body = PartParser.getMessageText(retrieved.getBody()); - PduBody media = PartParser.getSupportedMediaParts(retrieved.getBody()); - - for (int i=0;i 2) { - Set recipients = new HashSet<>(members); - group = Optional.of(SignalDatabase.groups().getOrCreateMmsGroupForMembers(recipients)); - } - IncomingMediaMessage message = new IncomingMediaMessage(from, group, body, TimeUnit.SECONDS.toMillis(retrieved.getDate()), -1, System.currentTimeMillis(), attachments, subscriptionId, 0, false, false, false, Optional.of(sharedContacts), false, false); - Optional insertResult = database.insertMessageInbox(message, contentLocation, threadId); - - if (insertResult.isPresent()) { - database.deleteMessage(messageId); - ApplicationDependencies.getMessageNotifier().updateNotification(context, ConversationId.forConversation(insertResult.get().getThreadId())); - } - } - - private void handleDownloadError(long messageId, long threadId, int downloadStatus, boolean automatic) - { - MessageTable db = SignalDatabase.messages(); - - db.markDownloadState(messageId, downloadStatus); - - if (automatic) { - db.markIncomingNotificationReceived(threadId); - ApplicationDependencies.getMessageNotifier().updateNotification(context, ConversationId.forConversation(threadId)); - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MmsDownloadJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) { - JsonJobData data = JsonJobData.deserialize(serializedData); - - return new MmsDownloadJob(parameters, - data.getLong(KEY_MESSAGE_ID), - data.getLong(KEY_THREAD_ID), - data.getBoolean(KEY_AUTOMATIC)); - } - } - - private static class NotReadyException extends RuntimeException { - } -} 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 827467cdda..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -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.signal.core.util.logging.Log; -import org.signal.libsignal.protocol.util.Pair; -import org.thoughtcrime.securesms.database.MessageTable; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobmanager.JsonJobData; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.signal.core.util.Base64; -import org.thoughtcrime.securesms.util.Util; - -import java.io.IOException; - -public class MmsReceiveJob extends BaseJob { - - public static final String KEY = "MmsReceiveJob"; - - private static final String TAG = Log.tag(MmsReceiveJob.class); - - 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 @Nullable byte[] serialize() { - return new JsonJobData.Builder().putString(KEY_DATA, Base64.encodeWithPadding(data)) - .putInt(KEY_SUBSCRIPTION_ID, subscriptionId) - .serialize(); - } - - @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)) { - Log.w(TAG, "Received an MMS from a blocked user. Ignoring."); - } else if (isNotification(pdu) && isSelf(pdu)) { - Log.w(TAG, "Received an MMS from ourselves! Ignoring."); - } else if (isNotification(pdu)) { - MessageTable database = SignalDatabase.messages(); - Pair messageAndThreadId = database.insertMessageInbox((NotificationInd)pdu, subscriptionId); - - if (messageAndThreadId.first() > 0) { - Log.i(TAG, "Inserted received MMS notification..."); - - ApplicationDependencies.getJobManager().add(new MmsDownloadJob(messageAndThreadId.first(), - messageAndThreadId.second(), - true)); - } else { - Log.w(TAG, "Did not insert MMS because it was a duplicate!"); - } - } else { - Log.w(TAG, "Unable to process MMS."); - } - } - - @Override - public void onFailure() { - // 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.external(context, Util.toIsoString(pdu.getFrom().getTextString())); - return recipients.isBlocked(); - } - - return false; - } - - private boolean isSelf(GenericPdu pdu) { - if (pdu.getFrom() != null && pdu.getFrom().getTextString() != null) { - Recipient recipients = Recipient.external(context, Util.toIsoString(pdu.getFrom().getTextString())); - return recipients.isSelf(); - } - - 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, @Nullable byte[] serializedData) { - try { - JsonJobData data = JsonJobData.deserialize(serializedData); - 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/SmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java deleted file mode 100644 index 863c4a3d83..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java +++ /dev/null @@ -1,243 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.content.Intent; -import android.telephony.SmsMessage; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import androidx.core.app.Person; - -import com.google.android.gms.auth.api.phone.SmsRetriever; -import com.google.android.gms.common.api.Status; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.MessageTable; -import org.thoughtcrime.securesms.database.MessageTable.InsertResult; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobmanager.JsonJobData; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.notifications.NotificationIds; -import org.thoughtcrime.securesms.notifications.v2.ConversationId; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.service.VerificationCodeParser; -import org.thoughtcrime.securesms.sms.IncomingTextMessage; -import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.signal.core.util.Base64; -import org.thoughtcrime.securesms.util.ServiceUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -public class SmsReceiveJob extends BaseJob { - - public static final String KEY = "SmsReceiveJob"; - - private static final String TAG = Log.tag(SmsReceiveJob.class); - - 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) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .build(), - pdus, - subscriptionId); - } - - private SmsReceiveJob(@NonNull Job.Parameters parameters, @Nullable Object[] pdus, int subscriptionId) { - super(parameters); - - this.pdus = pdus; - this.subscriptionId = subscriptionId; - } - - @Override - public @Nullable byte[] serialize() { - String[] encoded = new String[pdus.length]; - for (int i = 0; i < pdus.length; i++) { - encoded[i] = Base64.encodeWithPadding((byte[]) pdus[i]); - } - - return new JsonJobData.Builder().putStringArray(KEY_PDUS, encoded) - .putInt(KEY_SUBSCRIPTION_ID, subscriptionId) - .serialize(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws MigrationPendingException, RetryLaterException { - Optional message = assembleMessageFragments(pdus, subscriptionId); - - if (SignalStore.account().getE164() == null) { - Log.i(TAG, "Received an SMS before we're registered..."); - - if (message.isPresent()) { - Optional token = VerificationCodeParser.parse(message.get().getMessageBody()); - - if (token.isPresent()) { - Log.i(TAG, "Received something that looks like a registration SMS. Posting a notification and broadcast."); - - NotificationManager manager = ServiceUtil.getNotificationManager(context); - Notification notification = buildPreRegistrationNotification(context, message.get()); - manager.notify(NotificationIds.PRE_REGISTRATION_SMS, notification); - - Intent smsRetrieverIntent = buildSmsRetrieverIntent(message.get()); - context.sendBroadcast(smsRetrieverIntent); - - return; - } else { - Log.w(TAG, "Received an SMS before registration is complete. We'll try again later."); - throw new RetryLaterException(); - } - } else { - Log.w(TAG, "Received an SMS before registration is complete, but couldn't assemble the message anyway. Ignoring."); - return; - } - } - - if (message.isPresent() && SignalStore.account().getE164() != null && message.get().getAuthorId().equals(Recipient.self().getId())) { - Log.w(TAG, "Received an SMS from ourselves! Ignoring."); - } else if (message.isPresent() && !isBlocked(message.get())) { - Optional insertResult = storeMessage(message.get()); - - if (insertResult.isPresent()) { - ApplicationDependencies.getMessageNotifier().updateNotification(context, ConversationId.forConversation(insertResult.get().getThreadId())); - } - } else if (message.isPresent()) { - Log.w(TAG, "Received an SMS from a blocked user. Ignoring."); - } else { - Log.w(TAG, "Failed to assemble message fragments!"); - } - } - - @Override - public void onFailure() { - - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return exception instanceof MigrationPendingException || - exception instanceof RetryLaterException; - } - - private boolean isBlocked(IncomingTextMessage message) { - if (message.getAuthorId() != null) { - Recipient recipient = Recipient.resolved(message.getAuthorId()); - return recipient.isBlocked(); - } - - return false; - } - - private Optional storeMessage(IncomingTextMessage message) throws MigrationPendingException { - MessageTable database = SignalDatabase.messages(); - 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.empty(); - } - - List messages = new LinkedList<>(); - - for (Object pdu : pdus) { - SmsMessage message = SmsMessage.createFromPdu((byte[])pdu); - Recipient recipient = Recipient.external(context, message.getDisplayOriginatingAddress()); - messages.add(new IncomingTextMessage(recipient.getId(), message, subscriptionId)); - } - - if (messages.isEmpty()) { - return Optional.empty(); - } - - return Optional.of(new IncomingTextMessage(messages)); - } - - private static Notification buildPreRegistrationNotification(@NonNull Context context, @NonNull IncomingTextMessage message) { - Recipient sender = Recipient.resolved(message.getAuthorId()); - - return new NotificationCompat.Builder(context, NotificationChannels.getInstance().getMessagesChannel()) - .setStyle(new NotificationCompat.MessagingStyle(new Person.Builder() - .setName(sender.getE164().orElse("")) - .build()) - .addMessage(new NotificationCompat.MessagingStyle.Message(message.getMessageBody(), - message.getSentTimestampMillis(), - (Person) null))) - .setSmallIcon(R.drawable.ic_notification) - .build(); - } - - /** - * @return An intent that is identical to the one the {@link SmsRetriever} API uses, so that - * we can auto-populate the SMS code on capable devices. - */ - private static Intent buildSmsRetrieverIntent(@NonNull IncomingTextMessage message) { - Intent intent = new Intent(SmsRetriever.SMS_RETRIEVED_ACTION); - intent.putExtra(SmsRetriever.EXTRA_STATUS, Status.RESULT_SUCCESS); - intent.putExtra(SmsRetriever.EXTRA_SMS_MESSAGE, message.getMessageBody()); - return intent; - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull SmsReceiveJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) { - JsonJobData data = JsonJobData.deserialize(serializedData); - - 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); - } - } - } - - private class MigrationPendingException extends Exception { - } -} 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 96d8f64ba7..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/MmsListener.java +++ /dev/null @@ -1,61 +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.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobs.MmsReceiveJob; -import org.thoughtcrime.securesms.util.Util; - -public class MmsListener extends BroadcastReceiver { - - private static final String TAG = Log.tag(MmsListener.class); - - private boolean isRelevant(Context context, Intent intent) { - 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); - - ApplicationDependencies.getJobManager().add(new MmsReceiveJob(intent.getByteArrayExtra("data"), subscriptionId)); - - abortBroadcast(); - } - } - - - -} 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 93ac1121ea..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/SmsListener.java +++ /dev/null @@ -1,112 +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.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobs.SmsReceiveJob; -import org.thoughtcrime.securesms.util.Util; - -public class SmsListener extends BroadcastReceiver { - - private static final String TAG = Log.tag(SmsListener.class); - - 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 (SMS_RECEIVED_ACTION.equals(intent.getAction()) && Util.isDefaultSmsProvider(context)) { - return false; - } - - return false; - } - - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "Got SMS broadcast..."); - - if ((intent.getAction().equals(SMS_DELIVERED_ACTION)) || - (intent.getAction().equals(SMS_RECEIVED_ACTION)) && isRelevant(context, intent)) - { - Log.i(TAG, "Constructing SmsReceiveJob..."); - Object[] pdus = (Object[]) intent.getExtras().get("pdus"); - int subscriptionId = intent.getExtras().getInt("subscription", -1); - - ApplicationDependencies.getJobManager().add(new SmsReceiveJob(pdus, subscriptionId)); - - abortBroadcast(); - } - } -}