Switch MMS groups to use the group database infrastructure

Eliminate the concept of 'Recipients' (plural). There is now just
a 'Recipient', which contains an Address that is either an individual
or a group ID.

MMS groups now exist as part of the group database, just like push
groups.

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2017-08-01 08:56:00 -07:00
parent 81682e0302
commit 375207f073
106 changed files with 1587 additions and 2192 deletions

View File

@@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.Hex;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@@ -54,8 +55,9 @@ public class AvatarDownloadJob extends MasterSecretJob implements InjectableType
@Override
public void onRun(MasterSecret masterSecret) throws IOException {
String encodeId = GroupUtil.getEncodedId(groupId, false);
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
GroupDatabase.GroupRecord record = database.getGroup(groupId);
GroupDatabase.GroupRecord record = database.getGroup(encodeId);
File attachment = null;
try {
@@ -82,7 +84,7 @@ public class AvatarDownloadJob extends MasterSecretJob implements InjectableType
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE);
Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key), 500, 500);
database.updateAvatar(groupId, avatar);
database.updateAvatar(encodeId, avatar);
inputStream.close();
}
} catch (BitmapDecodingException | NonSuccessfulResponseCodeException | InvalidMessageException e) {

View File

@@ -8,10 +8,9 @@ import android.util.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.SecurityEvent;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
@@ -20,7 +19,7 @@ import java.io.IOException;
public class DirectoryRefreshJob extends ContextJob {
@Nullable private transient Recipients recipients;
@Nullable private transient Recipient recipient;
@Nullable private transient MasterSecret masterSecret;
public DirectoryRefreshJob(@NonNull Context context) {
@@ -29,14 +28,14 @@ public class DirectoryRefreshJob extends ContextJob {
public DirectoryRefreshJob(@NonNull Context context,
@Nullable MasterSecret masterSecret,
@Nullable Recipients recipients)
@Nullable Recipient recipient)
{
super(context, JobParameters.newBuilder()
.withGroupId(DirectoryRefreshJob.class.getSimpleName())
.withRequirement(new NetworkRequirement(context))
.create());
this.recipients = recipients;
this.recipient = recipient;
this.masterSecret = masterSecret;
}
@@ -51,10 +50,10 @@ public class DirectoryRefreshJob extends ContextJob {
try {
wakeLock.acquire();
if (recipients == null) {
if (recipient == null) {
DirectoryHelper.refreshDirectory(context, KeyCachingService.getMasterSecret(context));
} else {
DirectoryHelper.refreshDirectoryFor(context, masterSecret, recipients);
DirectoryHelper.refreshDirectoryFor(context, masterSecret, recipient);
}
SecurityEvent.broadcastSecurityUpdateEvent(context);
} finally {

View File

@@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.UriAttachment;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUnion;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
@@ -28,6 +29,7 @@ import org.thoughtcrime.securesms.mms.PartParser;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.providers.SingleUseBlobProvider;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@@ -39,8 +41,10 @@ import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class MmsDownloadJob extends MasterSecretJob {
@@ -88,6 +92,10 @@ public class MmsDownloadJob extends MasterSecretJob {
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();
@@ -161,28 +169,33 @@ public class MmsDownloadJob extends MasterSecretJob {
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
SingleUseBlobProvider provider = SingleUseBlobProvider.getInstance();
String from = null;
List<String> to = new LinkedList<>();
List<String> cc = new LinkedList<>();
Optional<Address> group = Optional.absent();
Set<Address> members = new HashSet<>();
String body = null;
List<Attachment> attachments = new LinkedList<>();
Address from;
if (retrieved.getFrom() != null) {
from = Util.toIsoString(retrieved.getFrom().getTextString());
from = Address.fromExternal(context, Util.toIsoString(retrieved.getFrom().getTextString()));
} else {
from = Address.UNKNOWN;
}
if (retrieved.getTo() != null) {
for (EncodedStringValue toValue : retrieved.getTo()) {
to.add(Util.toIsoString(toValue.getTextString()));
members.add(Address.fromExternal(context, Util.toIsoString(toValue.getTextString())));
}
}
if (retrieved.getCc() != null) {
for (EncodedStringValue ccValue : retrieved.getCc()) {
cc.add(Util.toIsoString(ccValue.getTextString()));
members.add(Address.fromExternal(context, Util.toIsoString(ccValue.getTextString())));
}
}
members.add(Address.fromExternal(context, TextSecurePreferences.getLocalNumber(context)));
if (retrieved.getBody() != null) {
body = PartParser.getMessageText(retrieved.getBody());
PduBody media = PartParser.getSupportedMediaParts(retrieved.getBody());
@@ -203,9 +216,11 @@ public class MmsDownloadJob extends MasterSecretJob {
}
}
if (members.size() > 1) {
group = Optional.of(Address.fromSerialized(DatabaseFactory.getGroupDatabase(context).getOrCreateGroupForMembers(new LinkedList<>(members), true)));
}
IncomingMediaMessage message = new IncomingMediaMessage(context, from, to, cc, body, retrieved.getDate() * 1000L, attachments, subscriptionId, 0, false);
IncomingMediaMessage message = new IncomingMediaMessage(from, group, body, retrieved.getDate() * 1000L, attachments, subscriptionId, 0, false);
Optional<InsertResult> insertResult = database.insertMessageInbox(new MasterSecretUnion(masterSecret),
message, contentLocation, threadId);

View File

@@ -13,8 +13,8 @@ import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.jobqueue.JobParameters;
@@ -86,7 +86,7 @@ public class MmsReceiveJob extends ContextJob {
private boolean isBlocked(GenericPdu pdu) {
if (pdu.getFrom() != null && pdu.getFrom().getTextString() != null) {
Recipients recipients = RecipientFactory.getRecipientsFor(context, new Address[] {Address.fromExternal(context, Util.toIsoString(pdu.getFrom().getTextString()))}, false);
Recipient recipients = RecipientFactory.getRecipientFor(context, Address.fromExternal(context, Util.toIsoString(pdu.getFrom().getTextString())), false);
return recipients.isBlocked();
}

View File

@@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.CompatMmsConnection;
import org.thoughtcrime.securesms.mms.MediaConstraints;
@@ -33,11 +34,12 @@ import org.thoughtcrime.securesms.mms.MmsSendResult;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.Hex;
import org.thoughtcrime.securesms.util.NumberUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@@ -171,16 +173,28 @@ public class MmsSendJob extends SendJob {
{
SendReq req = new SendReq();
String lineNumber = Utils.getMyPhoneNumber(context);
Address[] numbers = message.getRecipients().getAddresses();
Address destination = message.getRecipient().getAddress();
MediaConstraints mediaConstraints = MediaConstraints.getMmsMediaConstraints(message.getSubscriptionId());
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
if (!TextUtils.isEmpty(lineNumber)) {
req.setFrom(new EncodedStringValue(lineNumber));
} else {
req.setFrom(new EncodedStringValue(TextSecurePreferences.getLocalNumber(context)));
}
for (Address recipient : numbers) {
req.addTo(new EncodedStringValue(recipient.serialize()));
if (destination.isMmsGroup()) {
List<Recipient> 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);
@@ -266,11 +280,11 @@ public class MmsSendJob extends SendJob {
}
private void notifyMediaMessageDeliveryFailed(Context context, long messageId) {
long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId);
Recipients recipients = DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);
long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId);
Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId);
if (recipients != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
if (recipient != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipient, threadId);
}
}
}

View File

@@ -9,7 +9,7 @@ import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.BlockedRe
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -50,11 +50,11 @@ public class MultiDeviceBlockedUpdateJob extends MasterSecretJob implements Inje
BlockedReader reader = database.readerForBlocked(database.getBlocked());
List<String> blocked = new LinkedList<>();
Recipients recipients;
Recipient recipient;
while ((recipients = reader.getNext()) != null) {
if (recipients.isSingleRecipient() && !recipients.isGroupRecipient()) {
blocked.add(recipients.getPrimaryRecipient().getAddress().serialize());
while ((recipient = reader.getNext()) != null) {
if (!recipient.isGroupRecipient()) {
blocked.add(recipient.getAddress().serialize());
}
}

View File

@@ -34,8 +34,8 @@ import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.WebRtcCallService;
import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
@@ -80,7 +80,6 @@ import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptM
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -162,7 +161,7 @@ public class PushDecryptJob extends ContextJob {
else if (message.getAttachments().isPresent()) handleMediaMessage(masterSecret, envelope, message, smsMessageId);
else handleTextMessage(masterSecret, envelope, message, smsMessageId);
if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(message.getGroupInfo().get().getGroupId())) {
if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false))) {
handleUnknownGroupMessage(envelope, message.getGroupInfo().get());
}
} else if (content.getSyncMessage().isPresent()) {
@@ -322,15 +321,15 @@ public class PushDecryptJob extends ContextJob {
@NonNull Optional<Long> smsMessageId)
{
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
Recipients recipients = getSyncMessageDestination(message);
OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipients, "", -1);
Recipient recipient = getSyncMessageDestination(message);
OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipient, "", -1);
OutgoingEndSessionMessage outgoingEndSessionMessage = new OutgoingEndSessionMessage(outgoingTextMessage);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
if (recipients.isSingleRecipient() && !recipients.isGroupRecipient()) {
if (!recipient.isGroupRecipient()) {
SessionStore sessionStore = new TextSecureSessionStore(context);
sessionStore.deleteAllSessions(recipients.getPrimaryRecipient().getAddress().toPhoneString());
sessionStore.deleteAllSessions(recipient.getAddress().toPhoneString());
SecurityEvent.broadcastSecurityUpdateEvent(context);
@@ -373,11 +372,9 @@ public class PushDecryptJob extends ContextJob {
throws MmsException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
String localNumber = TextSecurePreferences.getLocalNumber(context);
Recipients recipients = getMessageDestination(envelope, message);
Recipient recipient = getMessageDestination(envelope, message);
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterSecret,
Address.fromExternal(context, envelope.getSource()),
Address.fromSerialized(localNumber),
message.getTimestamp(), -1,
message.getExpiresInSeconds() * 1000, true,
Optional.fromNullable(envelope.getRelay()),
@@ -388,7 +385,7 @@ public class PushDecryptJob extends ContextJob {
database.insertSecureDecryptedMessageInbox(masterSecret, mediaMessage, -1);
DatabaseFactory.getRecipientPreferenceDatabase(context).setExpireMessages(recipients, message.getExpiresInSeconds());
DatabaseFactory.getRecipientPreferenceDatabase(context).setExpireMessages(recipient, message.getExpiresInSeconds());
if (smsMessageId.isPresent()) {
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
@@ -423,7 +420,7 @@ public class PushDecryptJob extends ContextJob {
threadId = handleSynchronizeSentTextMessage(masterSecret, message, smsMessageId);
}
if (message.getMessage().getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(message.getMessage().getGroupInfo().get().getGroupId())) {
if (message.getMessage().getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId(), false))) {
handleUnknownGroupMessage(envelope, message.getMessage().getGroupInfo().get());
}
@@ -490,11 +487,9 @@ public class PushDecryptJob extends ContextJob {
throws MmsException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
String localNumber = TextSecurePreferences.getLocalNumber(context);
Recipients recipients = getMessageDestination(envelope, message);
Recipient recipient = getMessageDestination(envelope, message);
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterSecret,
Address.fromExternal(context, envelope.getSource()),
Address.fromSerialized(localNumber),
message.getTimestamp(), -1,
message.getExpiresInSeconds() * 1000, false,
Optional.fromNullable(envelope.getRelay()),
@@ -502,7 +497,7 @@ public class PushDecryptJob extends ContextJob {
message.getGroupInfo(),
message.getAttachments());
if (message.getExpiresInSeconds() != recipients.getExpireMessages()) {
if (message.getExpiresInSeconds() != recipient.getExpireMessages()) {
handleExpirationUpdate(masterSecret, envelope, message, Optional.<Long>absent());
}
@@ -537,18 +532,18 @@ public class PushDecryptJob extends ContextJob {
throws MmsException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Recipients recipients = getSyncMessageDestination(message);
Recipient recipient = getSyncMessageDestination(message);
OutgoingExpirationUpdateMessage expirationUpdateMessage = new OutgoingExpirationUpdateMessage(recipients,
OutgoingExpirationUpdateMessage expirationUpdateMessage = new OutgoingExpirationUpdateMessage(recipient,
message.getTimestamp(),
message.getMessage().getExpiresInSeconds() * 1000);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
long messageId = database.insertMessageOutbox(masterSecret, expirationUpdateMessage, threadId, false, null);
database.markAsSent(messageId, true);
DatabaseFactory.getRecipientPreferenceDatabase(context).setExpireMessages(recipients, message.getMessage().getExpiresInSeconds());
DatabaseFactory.getRecipientPreferenceDatabase(context).setExpireMessages(recipient, message.getMessage().getExpiresInSeconds());
if (smsMessageId.isPresent()) {
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
@@ -563,7 +558,7 @@ public class PushDecryptJob extends ContextJob {
throws MmsException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Recipients recipients = getSyncMessageDestination(message);
Recipient recipients = getSyncMessageDestination(message);
OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipients, message.getMessage().getBody().orNull(),
PointerAttachment.forPointers(masterSecret, message.getMessage().getAttachments()),
message.getTimestamp(), -1,
@@ -611,9 +606,9 @@ public class PushDecryptJob extends ContextJob {
{
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
String body = message.getBody().isPresent() ? message.getBody().get() : "";
Recipients recipients = getMessageDestination(envelope, message);
Recipient recipient = getMessageDestination(envelope, message);
if (message.getExpiresInSeconds() != recipients.getExpireMessages()) {
if (message.getExpiresInSeconds() != recipient.getExpireMessages()) {
handleExpirationUpdate(masterSecret, envelope, message, Optional.<Long>absent());
}
@@ -648,16 +643,16 @@ public class PushDecryptJob extends ContextJob {
throws MmsException
{
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
Recipients recipients = getSyncMessageDestination(message);
Recipient recipient = getSyncMessageDestination(message);
String body = message.getMessage().getBody().or("");
long expiresInMillis = message.getMessage().getExpiresInSeconds() * 1000;
OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipients, body, expiresInMillis, -1);
OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipient, body, expiresInMillis, -1);
if (recipients.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
if (recipient.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
handleSynchronizeSentExpirationUpdate(masterSecret, message, Optional.<Long>absent());
}
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
long messageId = database.insertMessageOutbox(masterSecret, threadId, outgoingTextMessage, false, message.getTimestamp(), null);
database.markAsSent(messageId, true);
@@ -810,19 +805,19 @@ public class PushDecryptJob extends ContextJob {
return database.insertMessageInbox(textMessage);
}
private Recipients getSyncMessageDestination(SentTranscriptMessage message) {
private Recipient getSyncMessageDestination(SentTranscriptMessage message) {
if (message.getMessage().getGroupInfo().isPresent()) {
return RecipientFactory.getRecipientsFor(context, new Address[] {Address.fromExternal(context, GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId()))}, false);
return RecipientFactory.getRecipientFor(context, Address.fromExternal(context, GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId(), false)), false);
} else {
return RecipientFactory.getRecipientsFor(context, new Address[] {Address.fromExternal(context, message.getDestination().get())}, false);
return RecipientFactory.getRecipientFor(context, Address.fromExternal(context, message.getDestination().get()), false);
}
}
private Recipients getMessageDestination(SignalServiceEnvelope envelope, SignalServiceDataMessage message) {
private Recipient getMessageDestination(SignalServiceEnvelope envelope, SignalServiceDataMessage message) {
if (message.getGroupInfo().isPresent()) {
return RecipientFactory.getRecipientsFor(context, new Address[] {Address.fromExternal(context, GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId()))}, false);
return RecipientFactory.getRecipientFor(context, Address.fromExternal(context, GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false)), false);
} else {
return RecipientFactory.getRecipientsFor(context, new Address[] {Address.fromExternal(context, envelope.getSource())}, false);
return RecipientFactory.getRecipientFor(context, Address.fromExternal(context, envelope.getSource()), false);
}
}
}

View File

@@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.jobqueue.JobParameters;
@@ -138,8 +137,8 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
EncapsulatedExceptions, UndeliverableMessageException
{
SignalServiceMessageSender messageSender = messageSenderFactory.create();
byte[] groupId = GroupUtil.getDecodedId(message.getRecipients().getPrimaryRecipient().getAddress().toGroupString());
Recipients recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
String groupId = message.getRecipient().getAddress().toGroupString();
List<Recipient> recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
@@ -154,12 +153,12 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
GroupContext groupContext = groupMessage.getGroupContext();
SignalServiceAttachment avatar = attachmentStreams.isEmpty() ? null : attachmentStreams.get(0);
SignalServiceGroup.Type type = groupMessage.isGroupQuit() ? SignalServiceGroup.Type.QUIT : SignalServiceGroup.Type.UPDATE;
SignalServiceGroup group = new SignalServiceGroup(type, groupId, groupContext.getName(), groupContext.getMembersList(), avatar);
SignalServiceGroup group = new SignalServiceGroup(type, GroupUtil.getDecodedId(groupId), groupContext.getName(), groupContext.getMembersList(), avatar);
SignalServiceDataMessage groupDataMessage = new SignalServiceDataMessage(message.getSentTimeMillis(), group, null, null);
messageSender.sendMessage(addresses, groupDataMessage);
} else {
SignalServiceGroup group = new SignalServiceGroup(groupId);
SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedId(groupId));
SignalServiceDataMessage groupMessage = new SignalServiceDataMessage(message.getSentTimeMillis(), group,
attachmentStreams, message.getBody(), false,
(int)(message.getExpiresIn() / 1000),
@@ -175,10 +174,10 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
return addresses;
}
private List<SignalServiceAddress> getPushAddresses(Recipients recipients) {
private List<SignalServiceAddress> getPushAddresses(List<Recipient> recipients) {
List<SignalServiceAddress> addresses = new LinkedList<>();
for (Recipient recipient : recipients.getRecipientsList()) {
for (Recipient recipient : recipients) {
addresses.add(getPushAddress(recipient.getAddress()));
}

View File

@@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -59,7 +60,7 @@ public class PushGroupUpdateJob extends ContextJob implements InjectableType {
public void onRun() throws IOException, UntrustedIdentityException {
SignalServiceMessageSender messageSender = messageSenderFactory.create();
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
GroupRecord record = groupDatabase.getGroup(groupId);
GroupRecord record = groupDatabase.getGroup(GroupUtil.getEncodedId(groupId, false));
SignalServiceAttachment avatar = null;
if (record == null) {

View File

@@ -102,14 +102,14 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
throws RetryLaterException, InsecureFallbackApprovalException, UntrustedIdentityException,
UndeliverableMessageException
{
if (message.getRecipients() == null || message.getRecipients().getPrimaryRecipient() == null) {
if (message.getRecipient() == null) {
throw new UndeliverableMessageException("No destination address.");
}
SignalServiceMessageSender messageSender = messageSenderFactory.create();
try {
SignalServiceAddress address = getPushAddress(message.getRecipients().getPrimaryRecipient().getAddress());
SignalServiceAddress address = getPushAddress(message.getRecipient().getAddress());
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);

View File

@@ -9,8 +9,8 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.NotInDirectoryException;
import org.thoughtcrime.securesms.database.TextSecureDirectory;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.whispersystems.jobqueue.JobManager;
import org.whispersystems.jobqueue.JobParameters;
@@ -35,8 +35,8 @@ public abstract class PushReceivedJob extends ContextJob {
directory.setNumber(contactTokenDetails, true);
Recipients recipients = RecipientFactory.getRecipientsFor(context, new Address[] {source}, false);
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, KeyCachingService.getMasterSecret(context), recipients));
Recipient recipient = RecipientFactory.getRecipientFor(context, source, false);
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, KeyCachingService.getMasterSecret(context), recipient));
}
if (envelope.isReceipt()) {
@@ -49,7 +49,7 @@ public abstract class PushReceivedJob extends ContextJob {
}
private void handleMessage(SignalServiceEnvelope envelope, Address source, boolean sendExplicitReceipt) {
Recipients recipients = RecipientFactory.getRecipientsFor(context, new Address[] {source}, false);
Recipient recipients = RecipientFactory.getRecipientFor(context, source, false);
JobManager jobManager = ApplicationContext.getInstance(context).getJobManager();
if (!recipients.isBlocked()) {

View File

@@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.events.PartProgressEvent;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@@ -95,11 +95,11 @@ public abstract class PushSendJob extends SendJob {
}
protected void notifyMediaMessageDeliveryFailed(Context context, long messageId) {
long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId);
Recipients recipients = DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);
long threadId = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId);
Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId);
if (threadId != -1 && recipients != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
if (threadId != -1 && recipient != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipient, threadId);
}
}

View File

@@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
import org.thoughtcrime.securesms.transport.RetryLaterException;
@@ -66,7 +66,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
} catch (InsecureFallbackApprovalException e) {
Log.w(TAG, e);
database.markAsPendingInsecureSmsFallback(record.getId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId());
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context));
} catch (UntrustedIdentityException e) {
Log.w(TAG, e);
@@ -87,11 +87,11 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
public void onCanceled() {
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
Recipients recipients = DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);
long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId);
if (threadId != -1 && recipients != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
if (threadId != -1 && recipient != null) {
MessageNotifier.notifyMessageDeliveryFailed(context, recipient, threadId);
}
}

View File

@@ -9,10 +9,8 @@ import android.util.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.MessageRetrievalService;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.IdentityUtil;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.libsignal.IdentityKey;
@@ -24,6 +22,7 @@ import org.whispersystems.signalservice.api.push.SignalServiceProfile;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
@@ -33,14 +32,14 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
@Inject transient SignalServiceMessageReceiver receiver;
private final Recipients recipients;
private final Recipient recipient;
public RetrieveProfileJob(Context context, Recipients recipients) {
public RetrieveProfileJob(Context context, Recipient recipient) {
super(context, JobParameters.newBuilder()
.withRetryCount(3)
.create());
this.recipients = recipients;
this.recipient = recipient;
}
@Override
@@ -49,10 +48,8 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
@Override
public void onRun() throws IOException, InvalidKeyException {
try {
for (Recipient recipient : recipients) {
if (recipient.isGroupRecipient()) handleGroupRecipient(recipient);
else handleIndividualRecipient(recipient);
}
if (recipient.isGroupRecipient()) handleGroupRecipient(recipient);
else handleIndividualRecipient(recipient);
} catch (InvalidNumberException e) {
Log.w(TAG, e);
}
@@ -93,8 +90,7 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
private void handleGroupRecipient(Recipient group)
throws IOException, InvalidKeyException, InvalidNumberException
{
byte[] groupId = GroupUtil.getDecodedId(group.getAddress().toGroupString());
Recipients recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
List<Recipient> recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(group.getAddress().toGroupString(), false);
for (Recipient recipient : recipients) {
handleIndividualRecipient(recipient);

View File

@@ -9,13 +9,12 @@ import android.util.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUnion;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.whispersystems.jobqueue.JobParameters;
@@ -86,8 +85,8 @@ public class SmsReceiveJob extends ContextJob {
private boolean isBlocked(IncomingTextMessage message) {
if (message.getSender() != null) {
Recipients recipients = RecipientFactory.getRecipientsFor(context, new Address[] {message.getSender()}, false);
return recipients.isBlocked();
Recipient recipient = RecipientFactory.getRecipientFor(context, message.getSender(), false);
return recipient.isBlocked();
}
return false;

View File

@@ -13,13 +13,12 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.jobs.requirements.NetworkOrServiceRequirement;
import org.thoughtcrime.securesms.jobs.requirements.ServiceRequirement;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.SmsDeliveryListener;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.NumberUtil;
@@ -54,7 +53,7 @@ public class SmsSendJob extends SendJob {
} catch (UndeliverableMessageException ude) {
Log.w(TAG, ude);
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(record.getId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId());
}
}
@@ -66,11 +65,11 @@ public class SmsSendJob extends SendJob {
@Override
public void onCanceled() {
Log.w(TAG, "onCanceled()");
long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
Recipients recipients = DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);
long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
Recipient recipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId);
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
MessageNotifier.notifyMessageDeliveryFailed(context, recipient, threadId);
}
private void deliver(SmsMessageRecord message)

View File

@@ -86,7 +86,7 @@ public class SmsSentJob extends MasterSecretJob {
break;
default:
database.markAsSentFailed(messageId);
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId());
}
} catch (NoSuchMessageException e) {
Log.w(TAG, e);