Search in sources :

Example 1 with GroupDatabase

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;
    }
}
Also used : GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) Nullable(android.support.annotation.Nullable)

Example 2 with GroupDatabase

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;
}
Also used : GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) ByteString(com.google.protobuf.ByteString) GroupContext(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext)

Example 3 with GroupDatabase

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);
}
Also used : SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) ByteString(com.google.protobuf.ByteString) GroupContext(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext) HashSet(java.util.HashSet) Nullable(android.support.annotation.Nullable)

Example 4 with GroupDatabase

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);
}
Also used : GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) ByteString(com.google.protobuf.ByteString) NonNull(android.support.annotation.NonNull)

Example 5 with GroupDatabase

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);
    }
}
Also used : InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) UntrustedIdentityException(org.whispersystems.libsignal.UntrustedIdentityException) SignalServiceCipher(org.whispersystems.signalservice.api.crypto.SignalServiceCipher) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SignalServiceSyncMessage(org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage) SignalServiceContent(org.whispersystems.signalservice.api.messages.SignalServiceContent) NoSessionException(org.whispersystems.libsignal.NoSessionException) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SignalProtocolStore(org.whispersystems.libsignal.state.SignalProtocolStore) MmsException(ws.com.google.android.mms.MmsException) DuplicateMessageException(org.whispersystems.libsignal.DuplicateMessageException) SignalProtocolStoreImpl(org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) SignalServiceCallMessage(org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) LegacyMessageException(org.whispersystems.libsignal.LegacyMessageException)

Aggregations

GroupDatabase (org.thoughtcrime.securesms.database.GroupDatabase)11 ByteString (com.google.protobuf.ByteString)4 Nullable (android.support.annotation.Nullable)3 SignalServiceAttachment (org.whispersystems.signalservice.api.messages.SignalServiceAttachment)3 SignalServiceGroup (org.whispersystems.signalservice.api.messages.SignalServiceGroup)3 GroupContext (org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext)3 GroupRecord (org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord)2 InvalidMessageException (org.whispersystems.libsignal.InvalidMessageException)2 SignalServiceDataMessage (org.whispersystems.signalservice.api.messages.SignalServiceDataMessage)2 SignalServiceAddress (org.whispersystems.signalservice.api.push.SignalServiceAddress)2 Bitmap (android.graphics.Bitmap)1 NonNull (android.support.annotation.NonNull)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 File (java.io.File)1 InputStream (java.io.InputStream)1 HashSet (java.util.HashSet)1 SignalProtocolStoreImpl (org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl)1 SmsDatabase (org.thoughtcrime.securesms.database.SmsDatabase)1 ThreadDatabase (org.thoughtcrime.securesms.database.ThreadDatabase)1 AttachmentModel (org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel)1