Support for per-recipient muting, blocking, and ringtones.

Fixes #757
Fixes #354
Fixes #222
Closes #1815
Closes #3378

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-06-09 07:37:20 -07:00
parent cb3cf7789f
commit 40af2a81db
80 changed files with 1858 additions and 321 deletions

View File

@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.util.Log;
import org.thoughtcrime.securesms.BuildConfig;
@@ -11,19 +10,15 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.push.TextSecurePushTrustStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
import org.whispersystems.libaxolotl.InvalidMessageException;
import org.whispersystems.textsecure.api.crypto.AttachmentCipherInputStream;
import org.whispersystems.textsecure.internal.push.PushServiceSocket;
import org.whispersystems.textsecure.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.textsecure.internal.push.PushServiceSocket;
import org.whispersystems.textsecure.internal.util.StaticCredentialsProvider;
import java.io.File;
@@ -72,10 +67,6 @@ public class AvatarDownloadJob extends MasterSecretJob {
Bitmap avatar = BitmapUtil.createScaledBitmap(measureInputStream, scaleInputStream, 500, 500);
database.updateAvatar(groupId, avatar);
Recipient groupRecipient = RecipientFactory.getRecipientsFromString(context, GroupUtil.getEncodedId(groupId), true)
.getPrimaryRecipient();
groupRecipient.setContactPhoto(new BitmapDrawable(avatar));
}
} catch (InvalidMessageException | BitmapDecodingException | NonSuccessfulResponseCodeException e) {
Log.w(TAG, e);

View File

@@ -7,6 +7,9 @@ import android.util.Pair;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.jobqueue.JobParameters;
import ws.com.google.android.mms.pdu.GenericPdu;
@@ -49,7 +52,7 @@ public class MmsReceiveJob extends ContextJob {
Log.w(TAG, e);
}
if (pdu != null && pdu.getMessageType() == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
if (isNotification(pdu) && !isBlocked(pdu)) {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Pair<Long, Long> messageAndThreadId = database.insertMessageInbox((NotificationInd)pdu);
@@ -61,6 +64,8 @@ public class MmsReceiveJob extends ContextJob {
messageAndThreadId.first,
messageAndThreadId.second,
true));
} else if (isNotification(pdu)) {
Log.w(TAG, "*** Received blocked MMS, ignoring...");
}
}
@@ -73,4 +78,17 @@ public class MmsReceiveJob extends ContextJob {
public boolean onShouldRetry(Exception exception) {
return false;
}
private boolean isBlocked(GenericPdu pdu) {
if (pdu.getFrom() != null && pdu.getFrom().getTextString() != null) {
Recipients recipients = RecipientFactory.getRecipientsFromString(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;
}
}

View File

@@ -7,6 +7,8 @@ import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.NotInDirectoryException;
import org.thoughtcrime.securesms.database.TextSecureDirectory;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.whispersystems.jobqueue.JobManager;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope;
@@ -34,16 +36,21 @@ public abstract class PushReceivedJob extends ContextJob {
}
private void handleMessage(TextSecureEnvelope envelope, boolean sendExplicitReceipt) {
Recipients recipients = RecipientFactory.getRecipientsFromString(context, envelope.getSource(), false);
JobManager jobManager = ApplicationContext.getInstance(context).getJobManager();
long messageId = DatabaseFactory.getPushDatabase(context).insert(envelope);
if (!recipients.isBlocked()) {
long messageId = DatabaseFactory.getPushDatabase(context).insert(envelope);
jobManager.add(new PushDecryptJob(context, messageId, envelope.getSource()));
} else {
Log.w(TAG, "*** Received blocked push message, ignoring...");
}
if (sendExplicitReceipt) {
jobManager.add(new DeliveryReceiptJob(context, envelope.getSource(),
envelope.getTimestamp(),
envelope.getRelay()));
}
jobManager.add(new PushDecryptJob(context, messageId, envelope.getSource()));
}
private void handleReceipt(TextSecureEnvelope envelope) {

View File

@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.telephony.SmsMessage;
import android.util.Log;
import android.util.Pair;
import org.thoughtcrime.securesms.ApplicationContext;
@@ -11,6 +12,8 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.protocol.WirePrefix;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
@@ -42,9 +45,11 @@ public class SmsReceiveJob extends ContextJob {
public void onRun() {
Optional<IncomingTextMessage> message = assembleMessageFragments(pdus);
if (message.isPresent()) {
if (message.isPresent() && !isBlocked(message.get())) {
Pair<Long, Long> messageAndThreadId = storeMessage(message.get());
MessageNotifier.updateNotification(context, KeyCachingService.getMasterSecret(context), messageAndThreadId.second);
} else if (message.isPresent()) {
Log.w(TAG, "*** Received blocked SMS, ignoring...");
}
}
@@ -58,6 +63,15 @@ public class SmsReceiveJob extends ContextJob {
return false;
}
private boolean isBlocked(IncomingTextMessage message) {
if (message.getSender() != null) {
Recipients recipients = RecipientFactory.getRecipientsFromString(context, message.getSender(), false);
return recipients.isBlocked();
}
return false;
}
private Pair<Long, Long> storeMessage(IncomingTextMessage message) {
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
MasterSecret masterSecret = KeyCachingService.getMasterSecret(context);