mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-05 06:01:53 +00:00
Refactor group messaging protocol.
// FREEBIE
This commit is contained in:
@@ -37,19 +37,17 @@ public class AvatarDownloader {
|
||||
if (!SendReceiveService.DOWNLOAD_AVATAR_ACTION.equals(intent.getAction()))
|
||||
return;
|
||||
|
||||
byte[] groupId = intent.getByteArrayExtra("group_id");
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
GroupDatabase.Reader reader = database.getGroup(groupId);
|
||||
byte[] groupId = intent.getByteArrayExtra("group_id");
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
GroupDatabase.GroupRecord record = database.getGroup(groupId);
|
||||
|
||||
GroupDatabase.GroupRecord record;
|
||||
|
||||
while ((record = reader.getNext()) != null) {
|
||||
if (record != null) {
|
||||
long avatarId = record.getAvatarId();
|
||||
byte[] key = record.getAvatarKey();
|
||||
String relay = record.getRelay();
|
||||
|
||||
if (avatarId == -1 || key == null) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
File attachment = downloadAttachment(relay, avatarId);
|
||||
|
||||
159
src/org/thoughtcrime/securesms/service/GroupReceiver.java
Normal file
159
src/org/thoughtcrime/securesms/service/GroupReceiver.java
Normal file
@@ -0,0 +1,159 @@
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent;
|
||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext;
|
||||
|
||||
public class GroupReceiver {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public GroupReceiver(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret,
|
||||
IncomingPushMessage message,
|
||||
PushMessageContent messageContent,
|
||||
boolean secure)
|
||||
{
|
||||
if (!messageContent.getGroup().hasId()) {
|
||||
Log.w("GroupReceiver", "Received group message with no id! Ignoring...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!secure) {
|
||||
Log.w("GroupReceiver", "Received insecure group push action! Ignoring...");
|
||||
return;
|
||||
}
|
||||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
GroupContext group = messageContent.getGroup();
|
||||
byte[] id = group.getId().toByteArray();
|
||||
int type = group.getType().getNumber();
|
||||
GroupRecord record = database.getGroup(id);
|
||||
|
||||
if (record != null && type == GroupContext.Type.UPDATE_VALUE) {
|
||||
handleGroupUpdate(masterSecret, message, group, record);
|
||||
} else if (record == null && type == GroupContext.Type.UPDATE_VALUE) {
|
||||
handleGroupCreate(masterSecret, message, group);
|
||||
} else if (type == GroupContext.Type.QUIT_VALUE) {
|
||||
handleGroupLeave(masterSecret, message, group, record);
|
||||
} else if (type == GroupContext.Type.UNKNOWN_VALUE) {
|
||||
Log.w("GroupReceiver", "Received unknown type, ignoring...");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGroupCreate(MasterSecret masterSecret,
|
||||
IncomingPushMessage message,
|
||||
GroupContext group)
|
||||
{
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
byte[] id = group.getId().toByteArray();
|
||||
|
||||
database.create(id, message.getSource(), group.getName(), group.getMembersList(),
|
||||
group.getAvatar(), message.getRelay());
|
||||
|
||||
storeMessage(masterSecret, message, group);
|
||||
}
|
||||
|
||||
private void handleGroupUpdate(MasterSecret masterSecret,
|
||||
IncomingPushMessage message,
|
||||
GroupContext group,
|
||||
GroupRecord groupRecord)
|
||||
{
|
||||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
byte[] id = group.getId().toByteArray();
|
||||
|
||||
Set<String> recordMembers = new HashSet<String>(groupRecord.getMembers());
|
||||
Set<String> messageMembers = new HashSet<String>(group.getMembersList());
|
||||
|
||||
Set<String> addedMembers = new HashSet<String>(messageMembers);
|
||||
addedMembers.removeAll(recordMembers);
|
||||
|
||||
Set<String> missingMembers = new HashSet<String>(recordMembers);
|
||||
missingMembers.removeAll(messageMembers);
|
||||
|
||||
if (addedMembers.size() > 0) {
|
||||
Set<String> unionMembers = new HashSet<String>(recordMembers);
|
||||
unionMembers.addAll(messageMembers);
|
||||
database.add(id, message.getSource(), new LinkedList<String>(unionMembers));
|
||||
|
||||
group = group.toBuilder().clearMembers().addAllMembers(addedMembers).build();
|
||||
} else {
|
||||
group = group.toBuilder().clearMembers().build();
|
||||
}
|
||||
|
||||
if (missingMembers.size() > 0) {
|
||||
// TODO We should tell added and missing about each-other.
|
||||
}
|
||||
|
||||
if (group.hasName() || group.hasAvatar()) {
|
||||
database.update(id, message.getSource(), group.getName(), group.getAvatar());
|
||||
}
|
||||
|
||||
if (group.hasName() && group.getName() != null && group.getName().equals(groupRecord.getTitle())) {
|
||||
group = group.toBuilder().clearName().build();
|
||||
}
|
||||
|
||||
storeMessage(masterSecret, message, group);
|
||||
}
|
||||
|
||||
private void handleGroupLeave(MasterSecret masterSecret,
|
||||
IncomingPushMessage message,
|
||||
GroupContext group,
|
||||
GroupRecord record)
|
||||
{
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
byte[] id = group.getId().toByteArray();
|
||||
List<String> members = record.getMembers();
|
||||
|
||||
if (members.contains(message.getSource())) {
|
||||
database.remove(id, message.getSource());
|
||||
|
||||
storeMessage(masterSecret, message, group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void storeMessage(MasterSecret masterSecret, IncomingPushMessage message, GroupContext group) {
|
||||
if (group.hasAvatar()) {
|
||||
Intent intent = new Intent(context, SendReceiveService.class);
|
||||
intent.setAction(SendReceiveService.DOWNLOAD_AVATAR_ACTION);
|
||||
intent.putExtra("group_id", group.getId().toByteArray());
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
String body = Base64.encodeBytes(group.toByteArray());
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(message, body, group);
|
||||
IncomingGroupMessage groupMessage = new IncomingGroupMessage(incoming, group, body);
|
||||
|
||||
Pair<Long, Long> messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, groupMessage);
|
||||
smsDatabase.updateMessageBody(masterSecret, messageAndThreadId.first, body);
|
||||
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor;
|
||||
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessorV2;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
@@ -22,7 +21,6 @@ import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingKeyExchangeMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
@@ -38,11 +36,9 @@ import org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent;
|
||||
import org.whispersystems.textsecure.storage.InvalidKeyIdException;
|
||||
import org.whispersystems.textsecure.storage.RecipientDevice;
|
||||
import org.whispersystems.textsecure.storage.Session;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
|
||||
import ws.com.google.android.mms.MmsException;
|
||||
|
||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext;
|
||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext.Type;
|
||||
|
||||
public class PushReceiver {
|
||||
@@ -51,10 +47,12 @@ public class PushReceiver {
|
||||
public static final int RESULT_NO_SESSION = 1;
|
||||
public static final int RESULT_DECRYPT_FAILED = 2;
|
||||
|
||||
private final Context context;
|
||||
private final Context context;
|
||||
private final GroupReceiver groupReceiver;
|
||||
|
||||
public PushReceiver(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.context = context.getApplicationContext();
|
||||
this.groupReceiver = new GroupReceiver(context);
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
@@ -160,7 +158,7 @@ public class PushReceiver {
|
||||
handleEndSessionMessage(masterSecret, message, messageContent);
|
||||
} else if (messageContent.hasGroup() && messageContent.getGroup().getType().getNumber() != Type.DELIVER_VALUE) {
|
||||
Log.w("PushReceiver", "Received push group message...");
|
||||
handleReceivedGroupMessage(masterSecret, message, messageContent, secure);
|
||||
groupReceiver.process(masterSecret, message, messageContent, secure);
|
||||
} else if (messageContent.getAttachmentsCount() > 0) {
|
||||
Log.w("PushReceiver", "Received push media message...");
|
||||
handleReceivedMediaMessage(masterSecret, message, messageContent, secure);
|
||||
@@ -174,57 +172,6 @@ public class PushReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleReceivedGroupMessage(MasterSecret masterSecret,
|
||||
IncomingPushMessage message,
|
||||
PushMessageContent messageContent,
|
||||
boolean secure)
|
||||
{
|
||||
if (!messageContent.getGroup().hasId()) {
|
||||
Log.w("PushReceiver", "Received group message with no id!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!secure) {
|
||||
Log.w("PushReceiver", "Received insecure group push action!");
|
||||
return;
|
||||
}
|
||||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
GroupContext group = messageContent.getGroup();
|
||||
byte[] id = group.getId().toByteArray();
|
||||
int type = group.getType().getNumber();
|
||||
|
||||
if (type == Type.CREATE_VALUE) {
|
||||
database.create(id, message.getSource(), group.getName(), group.getMembersList(), group.getAvatar(), message.getRelay());
|
||||
} else if (type == Type.ADD_VALUE) {
|
||||
database.add(id, message.getSource(), group.getMembersList());
|
||||
} else if (type == Type.QUIT_VALUE) {
|
||||
database.remove(id, message.getSource());
|
||||
} else if (type == Type.MODIFY_VALUE) {
|
||||
database.update(id, message.getSource(), group.getName(), group.getAvatar());
|
||||
} else if (type == Type.UNKNOWN_VALUE) {
|
||||
Log.w("PushReceiver", "Receied group message from unknown type: " + type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (group.hasAvatar()) {
|
||||
Intent intent = new Intent(context, SendReceiveService.class);
|
||||
intent.setAction(SendReceiveService.DOWNLOAD_AVATAR_ACTION);
|
||||
intent.putExtra("group_id", group.getId().toByteArray());
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
String body = Base64.encodeBytes(group.toByteArray());
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(message, body, group);
|
||||
IncomingGroupMessage groupMessage = new IncomingGroupMessage(incoming, group, body);
|
||||
|
||||
Pair<Long, Long> messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, groupMessage);
|
||||
smsDatabase.updateMessageBody(masterSecret, messageAndThreadId.first, body);
|
||||
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
}
|
||||
|
||||
private void handleEndSessionMessage(MasterSecret masterSecret,
|
||||
IncomingPushMessage message,
|
||||
PushMessageContent messageContent)
|
||||
|
||||
Reference in New Issue
Block a user