use of org.thoughtcrime.securesms.database.GroupDatabase in project Signal-Android by WhisperSystems.
the class GroupMessageProcessor method process.
@Nullable
public static Long process(@NonNull Context context, @NonNull MasterSecretUnion masterSecret, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceDataMessage message, boolean outgoing) {
if (!message.getGroupInfo().isPresent() || message.getGroupInfo().get().getGroupId() == null) {
Log.w(TAG, "Received group message with no id! Ignoring...");
return null;
}
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
SignalServiceGroup group = message.getGroupInfo().get();
byte[] id = group.getGroupId();
GroupRecord record = database.getGroup(id);
if (record != null && group.getType() == Type.UPDATE) {
return handleGroupUpdate(context, masterSecret, envelope, group, record, outgoing);
} else if (record == null && group.getType() == Type.UPDATE) {
return handleGroupCreate(context, masterSecret, envelope, group, outgoing);
} else if (record != null && group.getType() == Type.QUIT) {
return handleGroupLeave(context, masterSecret, envelope, group, record, outgoing);
} else if (record != null && group.getType() == Type.REQUEST_INFO) {
return handleGroupInfoRequest(context, envelope, group, record);
} else {
Log.w(TAG, "Received unknown type, ignoring...");
return null;
}
}
use of org.thoughtcrime.securesms.database.GroupDatabase in project Signal-Android by WhisperSystems.
the class GroupMessageProcessor method handleGroupLeave.
private static Long handleGroupLeave(@NonNull Context context, @NonNull MasterSecretUnion masterSecret, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceGroup group, @NonNull GroupRecord record, boolean outgoing) {
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
byte[] id = group.getGroupId();
List<String> members = record.getMembers();
GroupContext.Builder builder = createGroupContext(group);
builder.setType(GroupContext.Type.QUIT);
if (members.contains(envelope.getSource())) {
database.remove(id, envelope.getSource());
if (outgoing)
database.setActive(id, false);
return storeMessage(context, masterSecret, envelope, group, builder.build(), outgoing);
}
return null;
}
use of org.thoughtcrime.securesms.database.GroupDatabase in project Signal-Android by WhisperSystems.
the class GroupMessageProcessor method handleGroupUpdate.
@Nullable
private static Long handleGroupUpdate(@NonNull Context context, @NonNull MasterSecretUnion masterSecret, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceGroup group, @NonNull GroupRecord groupRecord, boolean outgoing) {
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
byte[] id = group.getGroupId();
Set<String> recordMembers = new HashSet<>(groupRecord.getMembers());
Set<String> messageMembers = new HashSet<>(group.getMembers().get());
Set<String> addedMembers = new HashSet<>(messageMembers);
addedMembers.removeAll(recordMembers);
Set<String> missingMembers = new HashSet<>(recordMembers);
missingMembers.removeAll(messageMembers);
GroupContext.Builder builder = createGroupContext(group);
builder.setType(GroupContext.Type.UPDATE);
if (addedMembers.size() > 0) {
Set<String> unionMembers = new HashSet<>(recordMembers);
unionMembers.addAll(messageMembers);
database.updateMembers(id, new LinkedList<>(unionMembers));
builder.clearMembers().addAllMembers(addedMembers);
} else {
builder.clearMembers();
}
if (missingMembers.size() > 0) {
// TODO We should tell added and missing about each-other.
}
if (group.getName().isPresent() || group.getAvatar().isPresent()) {
SignalServiceAttachment avatar = group.getAvatar().orNull();
database.update(id, group.getName().orNull(), avatar != null ? avatar.asPointer() : null);
}
if (group.getName().isPresent() && group.getName().get().equals(groupRecord.getTitle())) {
builder.clearName();
}
if (!groupRecord.isActive())
database.setActive(id, true);
return storeMessage(context, masterSecret, envelope, group, builder.build(), outgoing);
}
use of org.thoughtcrime.securesms.database.GroupDatabase in project Signal-Android by WhisperSystems.
the class GroupManager method createGroup.
@NonNull
public static GroupActionResult createGroup(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull Set<Recipient> members, @Nullable Bitmap avatar, @Nullable String name) throws InvalidNumberException {
final byte[] avatarBytes = BitmapUtil.toByteArray(avatar);
final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
final byte[] groupId = groupDatabase.allocateGroupId();
final Set<String> memberE164Numbers = getE164Numbers(context, members);
memberE164Numbers.add(TextSecurePreferences.getLocalNumber(context));
groupDatabase.create(groupId, name, new LinkedList<>(memberE164Numbers), null, null);
groupDatabase.updateAvatar(groupId, avatarBytes);
return sendGroupUpdate(context, masterSecret, groupId, memberE164Numbers, name, avatarBytes);
}
use of org.thoughtcrime.securesms.database.GroupDatabase in project Signal-Android by WhisperSystems.
the class PushDecryptJob method handleMessage.
private void handleMessage(MasterSecretUnion masterSecret, SignalServiceEnvelope envelope, Optional<Long> smsMessageId) {
try {
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context));
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore);
SignalServiceContent content = cipher.decrypt(envelope);
if (content.getDataMessage().isPresent()) {
SignalServiceDataMessage message = content.getDataMessage().get();
if (message.isEndSession())
handleEndSessionMessage(masterSecret, envelope, message, smsMessageId);
else if (message.isGroupUpdate())
handleGroupMessage(masterSecret, envelope, message, smsMessageId);
else if (message.isExpirationUpdate())
handleExpirationUpdate(masterSecret, envelope, message, smsMessageId);
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())) {
handleUnknownGroupMessage(envelope, message.getGroupInfo().get());
}
} else if (content.getSyncMessage().isPresent()) {
SignalServiceSyncMessage syncMessage = content.getSyncMessage().get();
if (syncMessage.getSent().isPresent())
handleSynchronizeSentMessage(masterSecret, envelope, syncMessage.getSent().get(), smsMessageId);
else if (syncMessage.getRequest().isPresent())
handleSynchronizeRequestMessage(masterSecret, syncMessage.getRequest().get());
else if (syncMessage.getRead().isPresent())
handleSynchronizeReadMessage(masterSecret, syncMessage.getRead().get(), envelope.getTimestamp());
else
Log.w(TAG, "Contains no known sync types...");
} else if (content.getCallMessage().isPresent()) {
Log.w(TAG, "Got call message...");
SignalServiceCallMessage message = content.getCallMessage().get();
if (message.getOfferMessage().isPresent())
handleCallOfferMessage(envelope, message.getOfferMessage().get(), smsMessageId);
else if (message.getAnswerMessage().isPresent())
handleCallAnswerMessage(envelope, message.getAnswerMessage().get());
else if (message.getIceUpdateMessages().isPresent())
handleCallIceUpdateMessage(envelope, message.getIceUpdateMessages().get());
else if (message.getHangupMessage().isPresent())
handleCallHangupMessage(envelope, message.getHangupMessage().get(), smsMessageId);
} else {
Log.w(TAG, "Got unrecognized message...");
}
if (envelope.isPreKeySignalMessage()) {
ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob(context));
}
} catch (InvalidVersionException e) {
Log.w(TAG, e);
handleInvalidVersionMessage(masterSecret, envelope, smsMessageId);
} catch (InvalidMessageException | InvalidKeyIdException | InvalidKeyException | MmsException e) {
Log.w(TAG, e);
handleCorruptMessage(masterSecret, envelope, smsMessageId);
} catch (NoSessionException e) {
Log.w(TAG, e);
handleNoSessionMessage(masterSecret, envelope, smsMessageId);
} catch (LegacyMessageException e) {
Log.w(TAG, e);
handleLegacyMessage(masterSecret, envelope, smsMessageId);
} catch (DuplicateMessageException e) {
Log.w(TAG, e);
handleDuplicateMessage(masterSecret, envelope, smsMessageId);
} catch (UntrustedIdentityException e) {
Log.w(TAG, e);
handleUntrustedIdentityMessage(masterSecret, envelope, smsMessageId);
}
}
Aggregations