diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index 37b38e4033..47abdd4151 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -81,6 +81,8 @@ import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage; +import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; +import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.util.ActionBarUtil; import org.thoughtcrime.securesms.util.BitmapDecodingException; @@ -922,20 +924,26 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi if (recipients == null) throw new RecipientFormattingException("Badly formatted"); - String body = getMessage(); + String body = getMessage(); long allocatedThreadId; if ((!recipients.isSingleRecipient() || recipients.isEmailRecipient()) && !isMmsEnabled) { handleManualMmsRequired(); return; - } else if (attachmentManager.isAttachmentPresent()) { - allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients, - threadId, attachmentManager.getSlideDeck(), body, - distributionType, isEncryptedConversation && !forcePlaintext); - } else if (recipients.isEmailRecipient() || !recipients.isSingleRecipient() || recipients.isGroupRecipient()) { - allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients, - threadId, new SlideDeck(), body, distributionType, - isEncryptedConversation && !forcePlaintext); + } else if (attachmentManager.isAttachmentPresent() || !recipients.isSingleRecipient() || recipients.isGroupRecipient()) { + SlideDeck slideDeck; + + if (attachmentManager.isAttachmentPresent()) slideDeck = attachmentManager.getSlideDeck(); + else slideDeck = new SlideDeck(); + + OutgoingMediaMessage outgoingMessage = new OutgoingMediaMessage(this, recipients, slideDeck, + body, distributionType); + + if (isEncryptedConversation && !forcePlaintext) { + outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessage); + } + + allocatedThreadId = MessageSender.send(this, masterSecret, outgoingMessage, threadId); } else { OutgoingTextMessage message; @@ -949,6 +957,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi allocatedThreadId = MessageSender.send(ConversationActivity.this, masterSecret, message, threadId); } + sendComplete(recipients, allocatedThreadId, allocatedThreadId != this.threadId); } catch (RecipientFormattingException ex) { Toast.makeText(ConversationActivity.this, diff --git a/src/org/thoughtcrime/securesms/ConversationAdapter.java b/src/org/thoughtcrime/securesms/ConversationAdapter.java index 4320adc495..3cd7cd6af9 100644 --- a/src/org/thoughtcrime/securesms/ConversationAdapter.java +++ b/src/org/thoughtcrime/securesms/ConversationAdapter.java @@ -123,8 +123,9 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.ID)); String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT)); MessageRecord messageRecord = getMessageRecord(id, cursor, type); - if (GroupUtil.isMetaGroupAction(messageRecord.getGroupAction())) return MESSAGE_TYPE_GROUP_ACTION; - if (messageRecord.isOutgoing()) return MESSAGE_TYPE_OUTGOING; + + if (messageRecord.isGroupAction()) return MESSAGE_TYPE_GROUP_ACTION; + else if (messageRecord.isOutgoing()) return MESSAGE_TYPE_OUTGOING; else return MESSAGE_TYPE_INCOMING; } diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index ba3e6f2a70..3173eb38d5 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -31,19 +31,16 @@ import android.os.Handler; import android.os.Message; import android.provider.Contacts.Intents; import android.provider.ContactsContract.QuickContact; -import org.thoughtcrime.securesms.util.DateUtils; import android.util.AttributeSet; import android.util.Log; import android.view.View; +import android.webkit.MimeTypeMap; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; -import android.webkit.MimeTypeMap; -import org.thoughtcrime.securesms.util.GroupUtil; -import org.whispersystems.textsecure.crypto.MasterSecret; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; @@ -53,10 +50,11 @@ import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.SendReceiveService; import org.thoughtcrime.securesms.util.BitmapUtil; +import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.Emoji; +import org.whispersystems.textsecure.crypto.MasterSecret; import org.whispersystems.textsecure.util.FutureTaskListener; import org.whispersystems.textsecure.util.ListenableFutureTask; -import org.whispersystems.textsecure.util.Util; import java.io.File; import java.io.FileOutputStream; @@ -64,8 +62,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext; - /** * A view that displays an individual conversation item within a conversation * thread. Used by ComposeMessageActivity's ListActivity via a ConversationAdapter. @@ -145,7 +141,7 @@ public class ConversationItem extends LinearLayout { setBodyText(messageRecord); - if (!GroupUtil.isMetaGroupAction(messageRecord.getGroupAction())) { + if (!messageRecord.isGroupAction()) { setStatusIcons(messageRecord); setContactPhoto(messageRecord); setGroupMessageStatus(messageRecord); @@ -175,22 +171,6 @@ public class ConversationItem extends LinearLayout { /// MessageRecord Attribute Parsers private void setBodyText(MessageRecord messageRecord) { - switch (messageRecord.getGroupAction()) { - case GroupContext.Type.QUIT_VALUE: - bodyText.setText(context.getString(R.string.ConversationItem_group_action_left, - messageRecord.getIndividualRecipient().toShortString())); - return; - case GroupContext.Type.ADD_VALUE: - case GroupContext.Type.CREATE_VALUE: - bodyText.setText(context.getString(R.string.ConversationItem_group_action_joined, - Util.join(GroupUtil.getSerializedArgumentMembers(messageRecord.getGroupActionArguments()), ", "))); - return; - case GroupContext.Type.MODIFY_VALUE: - bodyText.setText(context.getString(R.string.ConversationItem_group_action_modify, - messageRecord.getIndividualRecipient())); - return; - } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(), Emoji.EMOJI_LARGE), TextView.BufferType.SPANNABLE); diff --git a/src/org/thoughtcrime/securesms/GroupCreateActivity.java b/src/org/thoughtcrime/securesms/GroupCreateActivity.java index 82d2a15723..4aed1b6033 100644 --- a/src/org/thoughtcrime/securesms/GroupCreateActivity.java +++ b/src/org/thoughtcrime/securesms/GroupCreateActivity.java @@ -17,15 +17,14 @@ import android.util.Pair; import android.view.View; import android.widget.EditText; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ListView; -import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; +import com.google.protobuf.ByteString; import org.thoughtcrime.securesms.components.PushRecipientsPanel; import org.thoughtcrime.securesms.contacts.ContactAccessor; @@ -37,6 +36,7 @@ import org.thoughtcrime.securesms.recipients.RecipientFactory; import org.thoughtcrime.securesms.recipients.RecipientFormattingException; import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.sms.MessageSender; +import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; import org.thoughtcrime.securesms.util.ActionBarUtil; import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.DynamicLanguage; @@ -367,8 +367,8 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv } private Pair handleCreatePushGroup(String groupName, - byte[] avatar, - Set members) + byte[] avatar, + Set members) throws InvalidNumberException, MmsException { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(this); @@ -378,17 +378,23 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv List memberE164Numbers = getE164Numbers(members); String groupRecipientId = GroupUtil.getEncodedId(groupId); - String groupActionArguments = GroupUtil.serializeArguments(groupId, groupName, memberE164Numbers); - groupDatabase.create(groupId, TextSecurePreferences.getLocalNumber(this), groupName, memberE164Numbers, null, null); groupDatabase.updateAvatar(groupId, avatar); Recipients groupRecipient = RecipientFactory.getRecipientsFromString(this, groupRecipientId, false); - return new Pair(MessageSender.sendGroupAction(this, masterSecret, groupRecipient, -1, - GroupContext.Type.CREATE_VALUE, - groupActionArguments, avatar), groupRecipient); + GroupContext context = GroupContext.newBuilder() + .setId(ByteString.copyFrom(groupId)) + .setType(GroupContext.Type.CREATE) + .setName(groupName) + .addAllMembers(memberE164Numbers) + .build(); + + OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(this, groupRecipient, context, avatar); + long threadId = MessageSender.send(this, masterSecret, outgoingMessage, -1); + + return new Pair(threadId, groupRecipient); } catch (RecipientFormattingException e) { throw new AssertionError(e); } catch (MmsException e) { diff --git a/src/org/thoughtcrime/securesms/database/DatabaseFactory.java b/src/org/thoughtcrime/securesms/database/DatabaseFactory.java index 03e05337dc..9f1b014bb7 100644 --- a/src/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/src/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -647,12 +647,6 @@ public class DatabaseFactory { db.execSQL("ALTER TABLE push ADD COLUMN device_id INTEGER DEFAULT 1;"); db.execSQL("ALTER TABLE sms ADD COLUMN address_device_id INTEGER DEFAULT 1;"); db.execSQL("ALTER TABLE mms ADD COLUMN address_device_id INTEGER DEFAULT 1;"); - db.execSQL("ALTER TABLE sms ADD COLUMN group_action INTEGER DEFAULT -1;"); - db.execSQL("ALTER TABLE sms ADD COLUMN group_action_arguments TEXT;"); - db.execSQL("ALTER TABLE mms ADD COLuMN group_action INTEGER DEFAULT -1;"); - db.execSQL("ALTER TABLE mms ADD COLUMN group_action_arguments TEXT;"); - db.execSQL("ALTER TABLE thread ADD COLUMN group_action INTEGER DEFAULT -1;"); - db.execSQL("ALTER TABLE thread ADD COLUMN group_action_arguments TEXT;"); } db.setTransactionSuccessful(); diff --git a/src/org/thoughtcrime/securesms/database/GroupDatabase.java b/src/org/thoughtcrime/securesms/database/GroupDatabase.java index ca208a2f77..858c0ab557 100644 --- a/src/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/src/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -72,7 +72,7 @@ public class GroupDatabase extends Database { } public Recipients getGroupMembers(byte[] groupId) { - List members = getCurrentMembers(groupId); + List members = getCurrentMembers(groupId); List recipients = new LinkedList(); for (String member : members) { @@ -94,12 +94,17 @@ public class GroupDatabase extends Database { List filteredMembers = new LinkedList(); String localNumber = TextSecurePreferences.getLocalNumber(context); + if (!localNumber.equals(owner)) { + filteredMembers.add(owner); + } + for (String member : members) { if (!member.equals(localNumber)) { filteredMembers.add(member); } } + ContentValues contentValues = new ContentValues(); contentValues.put(GROUP_ID, GroupUtil.getEncodedId(groupId)); contentValues.put(OWNER, owner); diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 87f50a2653..322186fcdc 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -26,7 +26,8 @@ import android.util.Log; import android.util.Pair; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.contacts.ContactPhotoFactory; +import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; +import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.whispersystems.textsecure.crypto.InvalidMessageException; import org.whispersystems.textsecure.crypto.MasterCipher; import org.whispersystems.textsecure.crypto.MasterSecret; @@ -57,6 +58,7 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; +import ws.com.google.android.mms.ContentType; import ws.com.google.android.mms.InvalidHeaderValueException; import ws.com.google.android.mms.MmsException; import ws.com.google.android.mms.pdu.CharacterSets; @@ -116,7 +118,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns { STATUS + " INTEGER, " + TRANSACTION_ID + " TEXT, " + RETRIEVE_STATUS + " INTEGER, " + RETRIEVE_TEXT + " TEXT, " + RETRIEVE_TEXT_CS + " INTEGER, " + READ_STATUS + " INTEGER, " + CONTENT_CLASS + " INTEGER, " + RESPONSE_TEXT + " TEXT, " + DELIVERY_TIME + " INTEGER, " + - DELIVERY_REPORT + " INTEGER, " + GROUP_ACTION + " INTEGER DEFAULT -1, " + GROUP_ACTION_ARGUMENTS + " TEXT);"; + DELIVERY_REPORT + " INTEGER);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", @@ -133,7 +135,6 @@ public class MmsDatabase extends Database implements MmsSmsColumns { MESSAGE_SIZE, PRIORITY, REPORT_ALLOWED, STATUS, TRANSACTION_ID, RETRIEVE_STATUS, RETRIEVE_TEXT, RETRIEVE_TEXT_CS, READ_STATUS, CONTENT_CLASS, RESPONSE_TEXT, DELIVERY_TIME, DELIVERY_REPORT, BODY, PART_COUNT, ADDRESS, ADDRESS_DEVICE_ID, - GROUP_ACTION, GROUP_ACTION_ARGUMENTS }; public static final ExecutorService slideResolver = org.thoughtcrime.securesms.util.Util.newSingleThreadedLifoExecutor(); @@ -346,11 +347,9 @@ public class MmsDatabase extends Database implements MmsSmsColumns { while (cursor.moveToNext()) { messageId = cursor.getLong(cursor.getColumnIndexOrThrow(ID)); - long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)); - String messageText = cursor.getString(cursor.getColumnIndexOrThrow(BODY)); - int groupAction = cursor.getInt(cursor.getColumnIndexOrThrow(GROUP_ACTION)); - String groupActionArguments = cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ACTION_ARGUMENTS)); - PduHeaders headers = getHeadersFromCursor(cursor); + long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)); + String messageText = cursor.getString(cursor.getColumnIndexOrThrow(BODY)); + PduHeaders headers = getHeadersFromCursor(cursor); addr.getAddressesForId(messageId, headers); PduBody body = getPartsAsBody(partDatabase.getParts(messageId, true)); @@ -365,7 +364,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns { Log.w("MmsDatabase", e); } - requests[i++] = new SendReq(headers, body, messageId, outboxType, groupAction, groupActionArguments); + requests[i++] = new SendReq(headers, body, messageId, outboxType); } return requests; @@ -409,8 +408,6 @@ public class MmsDatabase extends Database implements MmsSmsColumns { contentValues.put(STATUS, Status.DOWNLOAD_INITIALIZED); contentValues.put(DATE_RECEIVED, System.currentTimeMillis() / 1000); contentValues.put(READ, unread ? 0 : 1); - contentValues.put(GROUP_ACTION, retrieved.getGroupAction()); - contentValues.put(GROUP_ACTION_ARGUMENTS, retrieved.getGroupActionArguments()); if (!contentValues.containsKey(DATE_SENT)) { contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED)); @@ -502,24 +499,46 @@ public class MmsDatabase extends Database implements MmsSmsColumns { Trimmer.trimThread(context, threadId); } - public long insertMessageOutbox(MasterSecret masterSecret, SendReq sendRequest, - long threadId, boolean isSecure) + public long insertMessageOutbox(MasterSecret masterSecret, OutgoingMediaMessage message, long threadId) throws MmsException { - long type = Types.BASE_OUTBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT; - PduHeaders headers = sendRequest.getPduHeaders(); - ContentValues contentValues = getContentValuesFromHeader(headers); + long type = Types.BASE_OUTBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT; - if (isSecure) { + if (message.isSecure()) { type |= Types.SECURE_MESSAGE_BIT; } + if (message.isGroup()) { + if (((OutgoingGroupMediaMessage)message).isGroupAdd()) type |= Types.GROUP_ADD_MEMBERS_BIT; + else if (((OutgoingGroupMediaMessage)message).isGroupQuit()) type |= Types.GROUP_QUIT_BIT; + else if (((OutgoingGroupMediaMessage)message).isGroupModify()) type |= Types.GROUP_MODIFY_BIT; + } + + SendReq sendRequest = new SendReq(); + sendRequest.setDate(System.currentTimeMillis() / 1000L); + sendRequest.setBody(message.getPduBody()); + sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes()); + + String[] recipientsArray = message.getRecipients().toNumberStringArray(true); + EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(recipientsArray); + + if (message.getRecipients().isSingleRecipient()) { + sendRequest.setTo(encodedNumbers); + } else if (message.getDistributionType() == ThreadDatabase.DistributionTypes.BROADCAST) { + sendRequest.setBcc(encodedNumbers); + } else if (message.getDistributionType() == ThreadDatabase.DistributionTypes.CONVERSATION || + message.getDistributionType() == 0) + { + sendRequest.setTo(encodedNumbers); + } + + PduHeaders headers = sendRequest.getPduHeaders(); + ContentValues contentValues = getContentValuesFromHeader(headers); + contentValues.put(MESSAGE_BOX, type); contentValues.put(THREAD_ID, threadId); contentValues.put(READ, 1); contentValues.put(DATE_RECEIVED, contentValues.getAsLong(DATE_SENT)); - contentValues.put(GROUP_ACTION, sendRequest.getGroupAction()); - contentValues.put(GROUP_ACTION_ARGUMENTS, sendRequest.getGroupActionArguments()); contentValues.remove(ADDRESS); long messageId = insertMediaMessage(masterSecret, sendRequest.getPduHeaders(), @@ -811,8 +830,6 @@ public class MmsDatabase extends Database implements MmsSmsColumns { long messageSize = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_SIZE)); long expiry = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.EXPIRY)); int status = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.STATUS)); - int groupAction = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.GROUP_ACTION)); - String groupActionArgs = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.GROUP_ACTION_ARGUMENTS)); byte[]contentLocationBytes = null; byte[]transactionIdBytes = null; @@ -827,7 +844,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns { return new NotificationMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(), addressDeviceId, dateSent, dateReceived, threadId, contentLocationBytes, messageSize, expiry, status, - transactionIdBytes, mailbox, groupAction, groupActionArgs); + transactionIdBytes, mailbox); } private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) { @@ -838,8 +855,6 @@ public class MmsDatabase extends Database implements MmsSmsColumns { long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID)); String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID)); - int groupAction = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.GROUP_ACTION)); - String groupActionArgs = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.GROUP_ACTION_ARGUMENTS)); DisplayRecord.Body body = getBody(cursor); int partCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.PART_COUNT)); Recipients recipients = getRecipientsFor(address); @@ -848,7 +863,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns { return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(), addressDeviceId, dateSent, dateReceived, threadId, body, - slideDeck, partCount, box, groupAction, groupActionArgs); + slideDeck, partCount, box); } private Recipients getRecipientsFor(String address) { diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java index a687cd145d..3eeff0709b 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java @@ -10,8 +10,6 @@ public interface MmsSmsColumns { public static final String BODY = "body"; public static final String ADDRESS = "address"; public static final String ADDRESS_DEVICE_ID = "address_device_id"; - public static final String GROUP_ACTION = "group_action"; - public static final String GROUP_ACTION_ARGUMENTS = "group_action_arguments"; public static class Types { protected static final long TOTAL_MASK = 0xFFFFFFFF; @@ -41,6 +39,11 @@ public interface MmsSmsColumns { protected static final long SECURE_MESSAGE_BIT = 0x800000; protected static final long END_SESSION_BIT = 0x400000; + // Group Message Information + protected static final long GROUP_ADD_MEMBERS_BIT = 0x10000; + protected static final long GROUP_QUIT_BIT = 0x20000; + protected static final long GROUP_MODIFY_BIT = 0x40000; + // Encrypted Storage Information protected static final long ENCRYPTION_MASK = 0xFF000000; protected static final long ENCRYPTION_SYMMETRIC_BIT = 0x80000000; @@ -108,6 +111,18 @@ public interface MmsSmsColumns { return (type & KEY_EXCHANGE_IDENTITY_UPDATE_BIT) != 0; } + public static boolean isGroupAdd(long type) { + return (type & GROUP_ADD_MEMBERS_BIT) != 0; + } + + public static boolean isGroupModify(long type) { + return (type & GROUP_MODIFY_BIT) != 0; + } + + public static boolean isGroupQuit(long type) { + return (type & GROUP_QUIT_BIT) != 0; + } + public static boolean isSymmetricEncryption(long type) { return (type & ENCRYPTION_SYMMETRIC_BIT) != 0; } diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 16abce63ba..2e1e40723f 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -49,8 +49,7 @@ public class MmsSmsDatabase extends Database { SmsDatabase.STATUS, MmsDatabase.PART_COUNT, MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, - MmsDatabase.STATUS, MmsSmsColumns.GROUP_ACTION, - MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT}; + MmsDatabase.STATUS, TRANSPORT}; String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC"; @@ -72,8 +71,7 @@ public class MmsSmsDatabase extends Database { SmsDatabase.STATUS, MmsDatabase.PART_COUNT, MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, - MmsDatabase.STATUS, MmsSmsColumns.GROUP_ACTION, - MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT}; + MmsDatabase.STATUS, TRANSPORT}; String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC"; String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; @@ -91,8 +89,7 @@ public class MmsSmsDatabase extends Database { MmsDatabase.PART_COUNT, MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, - MmsDatabase.STATUS, MmsSmsColumns.GROUP_ACTION, - MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT}; + MmsDatabase.STATUS, TRANSPORT}; String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC"; String selection = MmsSmsColumns.READ + " = 0"; @@ -115,7 +112,6 @@ public class MmsSmsDatabase extends Database { MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT, MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS, - MmsSmsColumns.GROUP_ACTION, MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT}; String[] smsProjection = {SmsDatabase.DATE_SENT + " * 1 AS " + MmsSmsColumns.NORMALIZED_DATE_SENT, @@ -125,7 +121,6 @@ public class MmsSmsDatabase extends Database { MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT, MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS, - MmsSmsColumns.GROUP_ACTION, MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT}; @@ -154,8 +149,6 @@ public class MmsSmsDatabase extends Database { mmsColumnsPresent.add(MmsDatabase.TRANSACTION_ID); mmsColumnsPresent.add(MmsDatabase.MESSAGE_SIZE); mmsColumnsPresent.add(MmsDatabase.EXPIRY); - mmsColumnsPresent.add(MmsSmsColumns.GROUP_ACTION); - mmsColumnsPresent.add(MmsSmsColumns.GROUP_ACTION_ARGUMENTS); mmsColumnsPresent.add(MmsDatabase.STATUS); Set smsColumnsPresent = new HashSet(); @@ -169,8 +162,6 @@ public class MmsSmsDatabase extends Database { smsColumnsPresent.add(SmsDatabase.SUBJECT); smsColumnsPresent.add(SmsDatabase.DATE_SENT); smsColumnsPresent.add(SmsDatabase.DATE_RECEIVED); - smsColumnsPresent.add(MmsSmsColumns.GROUP_ACTION); - smsColumnsPresent.add(MmsSmsColumns.GROUP_ACTION_ARGUMENTS); smsColumnsPresent.add(SmsDatabase.STATUS); String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 2, MMS_TRANSPORT, selection, null, null, null); @@ -225,7 +216,7 @@ public class MmsSmsDatabase extends Database { public MessageRecord getCurrent() { String type = cursor.getString(cursor.getColumnIndexOrThrow(TRANSPORT)); - if (type.equals(MmsSmsDatabase.MMS_TRANSPORT)) { + if (MmsSmsDatabase.MMS_TRANSPORT.equals(type)) { return mmsReader.getCurrent(); } else { return smsReader.getCurrent(); diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index e1777ab41e..27b9c45b17 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientFactory; import org.thoughtcrime.securesms.recipients.RecipientFormattingException; import org.thoughtcrime.securesms.recipients.Recipients; +import org.thoughtcrime.securesms.sms.IncomingGroupMessage; import org.thoughtcrime.securesms.sms.IncomingKeyExchangeMessage; import org.thoughtcrime.securesms.sms.IncomingTextMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; @@ -65,8 +66,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns { THREAD_ID + " INTEGER, " + ADDRESS + " TEXT, " + ADDRESS_DEVICE_ID + " INTEGER DEFAULT 1, " + PERSON + " INTEGER, " + DATE_RECEIVED + " INTEGER, " + DATE_SENT + " INTEGER, " + PROTOCOL + " INTEGER, " + READ + " INTEGER DEFAULT 0, " + STATUS + " INTEGER DEFAULT -1," + TYPE + " INTEGER, " + REPLY_PATH_PRESENT + " INTEGER, " + - SUBJECT + " TEXT, " + BODY + " TEXT, " + SERVICE_CENTER + " TEXT, " + - GROUP_ACTION + " INTEGER DEFAULT -1, " + GROUP_ACTION_ARGUMENTS + " TEXT);"; + SUBJECT + " TEXT, " + BODY + " TEXT, " + SERVICE_CENTER + " TEXT);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS sms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", @@ -80,7 +80,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns { DATE_RECEIVED + " AS " + NORMALIZED_DATE_RECEIVED, DATE_SENT + " AS " + NORMALIZED_DATE_SENT, PROTOCOL, READ, STATUS, TYPE, - REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER, GROUP_ACTION, GROUP_ACTION_ARGUMENTS + REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER }; public SmsDatabase(Context context, SQLiteOpenHelper databaseHelper) { @@ -256,9 +256,14 @@ public class SmsDatabase extends Database implements MmsSmsColumns { } else if (message.isSecureMessage()) { type |= Types.SECURE_MESSAGE_BIT; type |= Types.ENCRYPTION_REMOTE_BIT; - } else if (message.isEndSession()) { - type |= Types.END_SESSION_BIT; + } else if (message.isGroup()) { type |= Types.SECURE_MESSAGE_BIT; + if (((IncomingGroupMessage)message).isAdd()) type |= Types.GROUP_ADD_MEMBERS_BIT; + else if (((IncomingGroupMessage)message).isQuit()) type |= Types.GROUP_QUIT_BIT; + else if (((IncomingGroupMessage)message).isModify()) type |= Types.GROUP_MODIFY_BIT; + } else if (message.isEndSession()) { + type |= Types.SECURE_MESSAGE_BIT; + type |= Types.END_SESSION_BIT; type |= Types.ENCRYPTION_REMOTE_BIT; } @@ -308,8 +313,6 @@ public class SmsDatabase extends Database implements MmsSmsColumns { values.put(BODY, message.getMessageBody()); values.put(TYPE, type); values.put(THREAD_ID, threadId); - values.put(GROUP_ACTION, message.getGroupAction()); - values.put(GROUP_ACTION_ARGUMENTS, message.getGroupActionArgument()); SQLiteDatabase db = databaseHelper.getWritableDatabase(); long messageId = db.insert(TABLE_NAME, null, values); @@ -346,8 +349,6 @@ public class SmsDatabase extends Database implements MmsSmsColumns { contentValues.put(DATE_SENT, date); contentValues.put(READ, 1); contentValues.put(TYPE, type); - contentValues.put(GROUP_ACTION, message.getGroupAction()); - contentValues.put(GROUP_ACTION_ARGUMENTS, message.getGroupActionArguments()); SQLiteDatabase db = databaseHelper.getWritableDatabase(); messageIds.add(db.insert(TABLE_NAME, ADDRESS, contentValues)); @@ -504,8 +505,6 @@ public class SmsDatabase extends Database implements MmsSmsColumns { long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.NORMALIZED_DATE_SENT)); long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.THREAD_ID)); int status = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.STATUS)); - int groupAction = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.GROUP_ACTION)); - String groupActionArgs = cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.GROUP_ACTION_ARGUMENTS)); Recipients recipients = getRecipientsFor(address); DisplayRecord.Body body = getBody(cursor); @@ -513,7 +512,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns { recipients.getPrimaryRecipient(), addressDeviceId, dateSent, dateReceived, type, - threadId, status, groupAction, groupActionArgs); + threadId, status); } private Recipients getRecipientsFor(String address) { diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index 228179bb4d..72fe0ed03d 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -53,15 +53,12 @@ public class ThreadDatabase extends Database { private static final String ERROR = "error"; private static final String HAS_ATTACHMENT = "has_attachment"; public static final String SNIPPET_TYPE = "snippet_type"; - private static final String GROUP_ACTION = "group_action"; - private static final String GROUP_ACTION_ARG = "group_action_arguments"; public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " + DATE + " INTEGER DEFAULT 0, " + MESSAGE_COUNT + " INTEGER DEFAULT 0, " + RECIPIENT_IDS + " TEXT, " + SNIPPET + " TEXT, " + SNIPPET_CHARSET + " INTEGER DEFAULT 0, " + READ + " INTEGER DEFAULT 1, " + TYPE + " INTEGER DEFAULT 0, " + ERROR + " INTEGER DEFAULT 0, " + - SNIPPET_TYPE + " INTEGER DEFAULT 0, " + GROUP_ACTION + " INTEGER DEFAULT -1, " + - GROUP_ACTION_ARG + " TEXT, " + HAS_ATTACHMENT + " INTEGER DEFAULT 0);"; + SNIPPET_TYPE + " INTEGER DEFAULT 0);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + RECIPIENT_IDS + ");", @@ -117,16 +114,13 @@ public class ThreadDatabase extends Database { return db.insert(TABLE_NAME, null, contentValues); } - private void updateThread(long threadId, long count, String body, long date, long type, - int groupAction, String groupActionArguments) + private void updateThread(long threadId, long count, String body, long date, long type) { ContentValues contentValues = new ContentValues(3); contentValues.put(DATE, date - date % 1000); contentValues.put(MESSAGE_COUNT, count); contentValues.put(SNIPPET, body); contentValues.put(SNIPPET_TYPE, type); - contentValues.put(GROUP_ACTION, groupAction); - contentValues.put(GROUP_ACTION_ARG, groupActionArguments); SQLiteDatabase db = databaseHelper.getWritableDatabase(); db.update(TABLE_NAME, contentValues, ID + " = ?", new String[] {threadId + ""}); @@ -389,8 +383,7 @@ public class ThreadDatabase extends Database { MessageRecord record = null; if (reader != null && (record = reader.getNext()) != null) { - updateThread(threadId, count, record.getBody().getBody(), record.getDateReceived(), - record.getType(), record.getGroupAction(), record.getGroupActionArguments()); + updateThread(threadId, count, record.getBody().getBody(), record.getDateReceived(), record.getType()); } else { deleteThread(threadId); } @@ -446,12 +439,9 @@ public class ThreadDatabase extends Database { long read = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.READ)); long type = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_TYPE)); int distributionType = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.TYPE)); - int groupAction = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.GROUP_ACTION)); - String groupActionArg = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.GROUP_ACTION_ARG)); return new ThreadRecord(context, body, recipients, date, count, - read == 1, threadId, type, distributionType, - groupAction, groupActionArg); + read == 1, threadId, type, distributionType); } private DisplayRecord.Body getPlaintextBody(Cursor cursor) { diff --git a/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java b/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java index 7f333ceb09..2ed0e51364 100644 --- a/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/DisplayRecord.java @@ -40,12 +40,9 @@ public abstract class DisplayRecord { private final long dateReceived; private final long threadId; private final Body body; - private final int groupAction; - private final String groupActionArguments; public DisplayRecord(Context context, Body body, Recipients recipients, long dateSent, - long dateReceived, long threadId, long type, int groupAction, - String groupActionArguments) + long dateReceived, long threadId, long type) { this.context = context.getApplicationContext(); this.threadId = threadId; @@ -54,8 +51,6 @@ public abstract class DisplayRecord { this.dateReceived = dateReceived; this.type = type; this.body = body; - this.groupAction = groupAction; - this.groupActionArguments = groupActionArguments; } public Body getBody() { @@ -88,12 +83,20 @@ public abstract class DisplayRecord { return SmsDatabase.Types.isEndSessionType(type); } - public int getGroupAction() { - return groupAction; + public boolean isGroupAdd() { + return SmsDatabase.Types.isGroupAdd(type); } - public String getGroupActionArguments() { - return groupActionArguments; + public boolean isGroupModify() { + return SmsDatabase.Types.isGroupModify(type); + } + + public boolean isGroupQuit() { + return SmsDatabase.Types.isGroupQuit(type); + } + + public boolean isGroupAction() { + return isGroupAdd() || isGroupModify() || isGroupQuit(); } public static class Body { diff --git a/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java index cf861437e0..37df2bb36f 100644 --- a/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java @@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.database.model; import android.content.Context; import android.text.SpannableString; +import android.util.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.MmsDatabase; @@ -44,12 +45,10 @@ public class MediaMmsMessageRecord extends MessageRecord { Recipient individualRecipient, int recipientDeviceId, long dateSent, long dateReceived, long threadId, Body body, ListenableFutureTask slideDeck, - int partCount, long mailbox, int groupAction, - String groupActionArguments) + int partCount, long mailbox) { super(context, id, body, recipients, individualRecipient, recipientDeviceId, - dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox, - groupAction, groupActionArguments); + dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox); this.context = context.getApplicationContext(); this.partCount = partCount; diff --git a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java index 7bf7285b13..928db9615b 100644 --- a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -24,10 +24,13 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.style.TextAppearanceSpan; +import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipients; +import org.thoughtcrime.securesms.util.GroupUtil; +import org.whispersystems.textsecure.util.Util; /** * The base class for message record models that are displayed in @@ -52,10 +55,9 @@ public abstract class MessageRecord extends DisplayRecord { MessageRecord(Context context, long id, Body body, Recipients recipients, Recipient individualRecipient, int recipientDeviceId, long dateSent, long dateReceived, - long threadId, int deliveryStatus, - long type, int groupAction, String groupActionArguments) + long threadId, int deliveryStatus, long type) { - super(context, body, recipients, dateSent, dateReceived, threadId, type, groupAction, groupActionArguments); + super(context, body, recipients, dateSent, dateReceived, threadId, type); this.id = id; this.individualRecipient = individualRecipient; this.recipientDeviceId = recipientDeviceId; @@ -84,6 +86,14 @@ public abstract class MessageRecord extends DisplayRecord { @Override public SpannableString getDisplayBody() { + if (isGroupAdd()) { + return emphasisAdded(context.getString(R.string.ConversationItem_group_action_joined, Util.join(GroupUtil.getSerializedArgumentMembers(getBody().getBody()), ", "))); + } else if (isGroupQuit()) { + return emphasisAdded(context.getString(R.string.ConversationItem_group_action_left, getIndividualRecipient().toShortString())); + } else if (isGroupModify()) { + return emphasisAdded(context.getString(R.string.ConversationItem_group_action_modify, getIndividualRecipient().toShortString())); + } + return new SpannableString(getBody().getBody()); } diff --git a/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java index 5d575e024f..7ebf70c75d 100644 --- a/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java @@ -44,11 +44,10 @@ public class NotificationMmsMessageRecord extends MessageRecord { Recipient individualRecipient, int recipientDeviceId, long dateSent, long dateReceived, long threadId, byte[] contentLocation, long messageSize, long expiry, - int status, byte[] transactionId, long mailbox, - int groupAction, String groupActionArguments) + int status, byte[] transactionId, long mailbox) { super(context, id, new Body("", true), recipients, individualRecipient, recipientDeviceId, - dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox, groupAction, groupActionArguments); + dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox); this.contentLocation = contentLocation; this.messageSize = messageSize; diff --git a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java index a7c7b5d2a4..b598000f32 100644 --- a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java @@ -25,6 +25,8 @@ import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.protocol.Tag; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipients; +import org.thoughtcrime.securesms.util.GroupUtil; +import org.whispersystems.textsecure.util.Util; /** * The message record model which represents standard SMS messages. @@ -41,12 +43,10 @@ public class SmsMessageRecord extends MessageRecord { int recipientDeviceId, long dateSent, long dateReceived, long type, long threadId, - int status, int groupAction, - String groupActionArguments) + int status) { super(context, id, body, recipients, individualRecipient, recipientDeviceId, - dateSent, dateReceived, threadId, getGenericDeliveryStatus(status), type, - groupAction, groupActionArguments); + dateSent, dateReceived, threadId, getGenericDeliveryStatus(status), type); } public long getType() { diff --git a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java index b89d764b6c..42ccedc522 100644 --- a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java @@ -20,19 +20,13 @@ import android.content.Context; import android.text.Spannable; import android.text.SpannableString; import android.text.style.StyleSpan; -import android.util.Pair; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.util.GroupUtil; -import org.whispersystems.textsecure.push.PushMessageProtos; import org.whispersystems.textsecure.util.Util; -import java.util.List; - -import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext; - /** * The message record model which represents thread heading messages. * @@ -48,9 +42,9 @@ public class ThreadRecord extends DisplayRecord { public ThreadRecord(Context context, Body body, Recipients recipients, long date, long count, boolean read, long threadId, long snippetType, - int distributionType, int groupAction, String groupActionArg) + int distributionType) { - super(context, body, recipients, date, date, threadId, snippetType, groupAction, groupActionArg); + super(context, body, recipients, date, date, threadId, snippetType); this.context = context.getApplicationContext(); this.count = count; this.read = read; @@ -62,13 +56,11 @@ public class ThreadRecord extends DisplayRecord { // TODO jake is going to fill these in if (SmsDatabase.Types.isDecryptInProgressType(type)) { return emphasisAdded(context.getString(R.string.MessageDisplayHelper_decrypting_please_wait)); - } else if (getGroupAction() == GroupContext.Type.ADD_VALUE || - getGroupAction() == GroupContext.Type.CREATE_VALUE) - { - return emphasisAdded(Util.join(GroupUtil.getSerializedArgumentMembers(getGroupActionArguments()), ", ") + " have joined the group"); - } else if (getGroupAction() == GroupContext.Type.QUIT_VALUE) { + } else if (isGroupAdd()) { + return emphasisAdded(Util.join(GroupUtil.getSerializedArgumentMembers(getBody().getBody()), ", ") + " have joined the group"); + } else if (isGroupQuit()) { return emphasisAdded(getRecipients().toShortString() + " left the group."); - } else if (getGroupAction() == GroupContext.Type.MODIFY_VALUE) { + } else if (isGroupModify()) { return emphasisAdded(getRecipients().toShortString() + " modified the group."); } else if (isKeyExchange()) { return emphasisAdded(context.getString(R.string.ConversationListItem_key_exchange_message)); diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java b/src/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java new file mode 100644 index 0000000000..e20b5e3813 --- /dev/null +++ b/src/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java @@ -0,0 +1,53 @@ +package org.thoughtcrime.securesms.mms; + +import android.content.Context; + +import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.thoughtcrime.securesms.recipients.Recipients; +import org.whispersystems.textsecure.util.Base64; + +import ws.com.google.android.mms.ContentType; +import ws.com.google.android.mms.pdu.PduBody; +import ws.com.google.android.mms.pdu.PduPart; + +import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext; + +public class OutgoingGroupMediaMessage extends OutgoingSecureMediaMessage { + + private final GroupContext group; + + public OutgoingGroupMediaMessage(Context context, Recipients recipients, + GroupContext group, byte[] avatar) + { + super(context, recipients, new PduBody(), Base64.encodeBytes(group.toByteArray()), + ThreadDatabase.DistributionTypes.CONVERSATION); + + this.group = group; + + PduPart part = new PduPart(); + part.setData(avatar); + part.setContentType(ContentType.IMAGE_PNG.getBytes()); + part.setContentId((System.currentTimeMillis()+"").getBytes()); + part.setName(("Image" + System.currentTimeMillis()).getBytes()); + body.addPart(part); + } + + @Override + public boolean isGroup() { + return true; + } + + public boolean isGroupAdd() { + return + group.getType().getNumber() == GroupContext.Type.ADD_VALUE || + group.getType().getNumber() == GroupContext.Type.CREATE_VALUE; + } + + public boolean isGroupQuit() { + return group.getType().getNumber() == GroupContext.Type.QUIT_VALUE; + } + + public boolean isGroupModify() { + return group.getType().getNumber() == GroupContext.Type.MODIFY_VALUE; + } +} diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java b/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java new file mode 100644 index 0000000000..ecb0fa50b2 --- /dev/null +++ b/src/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java @@ -0,0 +1,60 @@ +package org.thoughtcrime.securesms.mms; + +import android.content.Context; + +import org.thoughtcrime.securesms.recipients.Recipients; +import org.whispersystems.textsecure.util.Util; + +import ws.com.google.android.mms.pdu.PduBody; + +public class OutgoingMediaMessage { + + private final Recipients recipients; + protected final PduBody body; + private final int distributionType; + + public OutgoingMediaMessage(Context context, Recipients recipients, PduBody body, + String message, int distributionType) + { + this.recipients = recipients; + this.body = body; + this.distributionType = distributionType; + + if (!Util.isEmpty(message)) { + this.body.addPart(new TextSlide(context, message).getPart()); + } + } + + public OutgoingMediaMessage(Context context, Recipients recipients, SlideDeck slideDeck, + String message, int distributionType) + { + this(context, recipients, slideDeck.toPduBody(), message, distributionType); + } + + public OutgoingMediaMessage(OutgoingMediaMessage that) { + this.recipients = that.getRecipients(); + this.body = that.body; + this.distributionType = that.distributionType; + } + + public Recipients getRecipients() { + return recipients; + } + + public PduBody getPduBody() { + return body; + } + + public int getDistributionType() { + return distributionType; + } + + public boolean isSecure() { + return false; + } + + public boolean isGroup() { + return false; + } + +} diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java b/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java new file mode 100644 index 0000000000..cfa01db42b --- /dev/null +++ b/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java @@ -0,0 +1,25 @@ +package org.thoughtcrime.securesms.mms; + +import android.content.Context; + +import org.thoughtcrime.securesms.recipients.Recipients; + +import ws.com.google.android.mms.pdu.PduBody; + +public class OutgoingSecureMediaMessage extends OutgoingMediaMessage { + + public OutgoingSecureMediaMessage(Context context, Recipients recipients, PduBody body, + String message, int distributionType) + { + super(context, recipients, body, message, distributionType); + } + + public OutgoingSecureMediaMessage(OutgoingMediaMessage base) { + super(base); + } + + @Override + public boolean isSecure() { + return true; + } +} diff --git a/src/org/thoughtcrime/securesms/service/PushReceiver.java b/src/org/thoughtcrime/securesms/service/PushReceiver.java index d3d4cb1480..deab385b9d 100644 --- a/src/org/thoughtcrime/securesms/service/PushReceiver.java +++ b/src/org/thoughtcrime/securesms/service/PushReceiver.java @@ -22,6 +22,7 @@ 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; @@ -37,6 +38,7 @@ 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; @@ -156,7 +158,7 @@ public class PushReceiver { if (secure && (messageContent.getFlags() & PushMessageContent.Flags.END_SESSION_VALUE) != 0) { Log.w("PushReceiver", "Received end session message..."); handleEndSessionMessage(masterSecret, message, messageContent); - } else if (messageContent.hasGroup()) { + } else if (messageContent.hasGroup() && messageContent.getGroup().getType().getNumber() != Type.DELIVER_VALUE) { Log.w("PushReceiver", "Received push group message..."); handleReceivedGroupMessage(masterSecret, message, messageContent, secure); } else if (messageContent.getAttachmentsCount() > 0) { @@ -177,14 +179,13 @@ public class PushReceiver { PushMessageContent messageContent, boolean secure) { - if (messageContent.getGroup().getType().equals(Type.UNKNOWN)) { - Log.w("PushReceiver", "Received group message of unknown type: " + - messageContent.getGroup().getType().getNumber()); + if (!messageContent.getGroup().hasId()) { + Log.w("PushReceiver", "Received group message with no id!"); return; } - if (!messageContent.getGroup().hasId()) { - Log.w("PushReceiver", "Received group message with no id!"); + if (!secure) { + Log.w("PushReceiver", "Received insecure group push action!"); return; } @@ -193,25 +194,17 @@ public class PushReceiver { byte[] id = group.getId().toByteArray(); int type = group.getType().getNumber(); - switch (type) { - case Type.CREATE_VALUE: - database.create(id, message.getSource(), group.getName(), group.getMembersList(), group.getAvatar(), message.getRelay()); - break; - case Type.ADD_VALUE: - database.add(id, message.getSource(), group.getMembersList()); - break; - case Type.QUIT_VALUE: - database.remove(id, message.getSource()); - break; - case Type.MODIFY_VALUE: - database.update(id, message.getSource(), group.getName(), group.getAvatar()); - break; - case Type.DELIVER_VALUE: - break; - case Type.UNKNOWN_VALUE: - default: - Log.w("PushReceiver", "Received group message of unknown type: " + type); - return; + 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()) { @@ -221,11 +214,15 @@ public class PushReceiver { context.startService(intent); } - if (messageContent.getAttachmentsCount() > 0) { - handleReceivedMediaMessage(masterSecret, message, messageContent, secure); - } else { - handleReceivedTextMessage(masterSecret, message, messageContent, secure); - } + 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 messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, groupMessage); + smsDatabase.updateMessageBody(masterSecret, messageAndThreadId.first, body); + + MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); } private void handleEndSessionMessage(MasterSecret masterSecret, diff --git a/src/org/thoughtcrime/securesms/sms/IncomingGroupMessage.java b/src/org/thoughtcrime/securesms/sms/IncomingGroupMessage.java new file mode 100644 index 0000000000..376c494b3f --- /dev/null +++ b/src/org/thoughtcrime/securesms/sms/IncomingGroupMessage.java @@ -0,0 +1,55 @@ +package org.thoughtcrime.securesms.sms; + +import com.google.protobuf.ByteString; + +import org.thoughtcrime.securesms.util.GroupUtil; +import org.whispersystems.textsecure.push.PushMessageProtos; + +import java.io.IOException; + +import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext; + +public class IncomingGroupMessage extends IncomingTextMessage { + + private final GroupContext groupContext; + + public IncomingGroupMessage(IncomingTextMessage base, GroupContext groupContext, String body) { + super(base, body); + this.groupContext = groupContext; + } + + @Override + public IncomingGroupMessage withMessageBody(String body) { + return new IncomingGroupMessage(this, groupContext, body); + } + + @Override + public boolean isGroup() { + return true; + } + + public boolean isAdd() { + return + groupContext.getType().getNumber() == GroupContext.Type.ADD_VALUE || + groupContext.getType().getNumber() == GroupContext.Type.CREATE_VALUE; + } + + public boolean isQuit() { + return groupContext.getType().getNumber() == GroupContext.Type.QUIT_VALUE; + } + + public boolean isModify() { + return groupContext.getType().getNumber() == GroupContext.Type.MODIFY_VALUE; + } + + public static IncomingGroupMessage createForQuit(String groupId, String user) throws IOException { + IncomingTextMessage base = new IncomingTextMessage(user, groupId); + GroupContext context = GroupContext.newBuilder() + .setType(GroupContext.Type.QUIT) + .setId(ByteString.copyFrom(GroupUtil.getDecodedId(groupId))) + .build(); + + return new IncomingGroupMessage(base, context, ""); + } + +} diff --git a/src/org/thoughtcrime/securesms/sms/IncomingIdentityUpdateMessage.java b/src/org/thoughtcrime/securesms/sms/IncomingIdentityUpdateMessage.java index bec307b224..36cdb5729b 100644 --- a/src/org/thoughtcrime/securesms/sms/IncomingIdentityUpdateMessage.java +++ b/src/org/thoughtcrime/securesms/sms/IncomingIdentityUpdateMessage.java @@ -24,7 +24,7 @@ public class IncomingIdentityUpdateMessage extends IncomingKeyExchangeMessage { } public static IncomingIdentityUpdateMessage createFor(String sender, IdentityKey identityKey, String groupId) { - IncomingTextMessage base = new IncomingTextMessage(sender, groupId, -1, null); + IncomingTextMessage base = new IncomingTextMessage(sender, groupId); return new IncomingIdentityUpdateMessage(base, Base64.encodeBytesWithoutPadding(identityKey.serialize())); } } diff --git a/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java b/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java index 33e7ae6a6f..3fe0ebff47 100644 --- a/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java +++ b/src/org/thoughtcrime/securesms/sms/IncomingTextMessage.java @@ -38,8 +38,6 @@ public class IncomingTextMessage implements Parcelable { private final String pseudoSubject; private final long sentTimestampMillis; private final String groupId; - private final int groupAction; - private final String groupActionArgument; public IncomingTextMessage(SmsMessage message) { this.message = message.getDisplayMessageBody(); @@ -51,8 +49,6 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = message.getPseudoSubject(); this.sentTimestampMillis = message.getTimestampMillis(); this.groupId = null; - this.groupAction = -1; - this.groupActionArgument = null; } public IncomingTextMessage(IncomingPushMessage message, String encodedBody, GroupContext group) { @@ -65,14 +61,10 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = ""; this.sentTimestampMillis = message.getTimestampMillis(); - if (group != null) { - this.groupId = GroupUtil.getEncodedId(group.getId().toByteArray()); - this.groupAction = group.getType().getNumber(); - this.groupActionArgument = GroupUtil.serializeArguments(group); + if (group.hasId()) { + this.groupId = GroupUtil.getEncodedId(group.getId().toByteArray()); } else { - this.groupId = null; - this.groupAction = -1; - this.groupActionArgument = null; + this.groupId = null; } } @@ -86,8 +78,6 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = in.readString(); this.sentTimestampMillis = in.readLong(); this.groupId = in.readString(); - this.groupAction = in.readInt(); - this.groupActionArgument = in.readString(); } public IncomingTextMessage(IncomingTextMessage base, String newBody) { @@ -100,8 +90,6 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = base.getPseudoSubject(); this.sentTimestampMillis = base.getSentTimestampMillis(); this.groupId = base.getGroupId(); - this.groupAction = base.getGroupAction(); - this.groupActionArgument = base.getGroupActionArgument(); } public IncomingTextMessage(List fragments) { @@ -120,8 +108,6 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = fragments.get(0).getPseudoSubject(); this.sentTimestampMillis = fragments.get(0).getSentTimestampMillis(); this.groupId = fragments.get(0).getGroupId(); - this.groupAction = fragments.get(0).getGroupAction(); - this.groupActionArgument = fragments.get(0).getGroupActionArgument(); } public IncomingTextMessage(SendReq record) { @@ -134,8 +120,6 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = ""; this.sentTimestampMillis = System.currentTimeMillis(); this.groupId = null; - this.groupAction = -1; - this.groupActionArgument = null; } public IncomingTextMessage(SmsMessageRecord record) { @@ -148,12 +132,9 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = ""; this.sentTimestampMillis = System.currentTimeMillis(); this.groupId = null; - this.groupAction = -1; - this.groupActionArgument = null; } - protected IncomingTextMessage(String sender, String groupId, - int groupAction, String groupActionArgument) + protected IncomingTextMessage(String sender, String groupId) { this.message = ""; this.sender = sender; @@ -164,8 +145,6 @@ public class IncomingTextMessage implements Parcelable { this.pseudoSubject = ""; this.sentTimestampMillis = System.currentTimeMillis(); this.groupId = groupId; - this.groupAction = groupAction; - this.groupActionArgument = groupActionArgument; } public long getSentTimestampMillis() { @@ -228,12 +207,8 @@ public class IncomingTextMessage implements Parcelable { return groupId; } - public int getGroupAction() { - return groupAction; - } - - public String getGroupActionArgument() { - return groupActionArgument; + public boolean isGroup() { + return false; } @Override @@ -252,11 +227,5 @@ public class IncomingTextMessage implements Parcelable { out.writeString(pseudoSubject); out.writeLong(sentTimestampMillis); out.writeString(groupId); - out.writeInt(groupAction); - out.writeString(groupActionArgument); - } - - public static IncomingTextMessage createForLeavingGroup(String groupId, String user) { - return new IncomingTextMessage(user, groupId, GroupContext.Type.QUIT_VALUE, null); } } diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 9e1c834b98..09b89147e8 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -20,93 +20,17 @@ import android.content.Context; import android.content.Intent; import android.util.Log; -import org.thoughtcrime.securesms.mms.ImageSlide; +import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.whispersystems.textsecure.crypto.MasterSecret; import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.mms.SlideDeck; -import org.thoughtcrime.securesms.mms.TextSlide; -import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.service.SendReceiveService; import java.util.List; -import ws.com.google.android.mms.ContentType; import ws.com.google.android.mms.MmsException; -import ws.com.google.android.mms.pdu.EncodedStringValue; -import ws.com.google.android.mms.pdu.PduBody; -import ws.com.google.android.mms.pdu.PduPart; -import ws.com.google.android.mms.pdu.SendReq; public class MessageSender { - public static long sendGroupAction(Context context, MasterSecret masterSecret, Recipients recipients, - long threadId, int groupAction, String groupActionArguments, byte[] avatar) - throws MmsException - { - if (threadId == -1) { - threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients); - } - - PduBody body = new PduBody(); - - if (avatar != null) { - PduPart part = new PduPart(); - part.setData(avatar); - part.setContentType(ContentType.IMAGE_PNG.getBytes()); - part.setContentId((System.currentTimeMillis()+"").getBytes()); - part.setName(("Image" + System.currentTimeMillis()).getBytes()); - body.addPart(part); - } - - SendReq sendRequest = new SendReq(); - sendRequest.setDate(System.currentTimeMillis() / 1000L); - sendRequest.setBody(body); - sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes()); - sendRequest.setGroupAction(groupAction); - sendRequest.setGroupActionArguments(groupActionArguments); - - sendMms(context, recipients, masterSecret, sendRequest, threadId, - ThreadDatabase.DistributionTypes.CONVERSATION, true); - - return threadId; - } - - public static long sendMms(Context context, MasterSecret masterSecret, Recipients recipients, - long threadId, SlideDeck slideDeck, String message, int distributionType, - boolean secure) - throws MmsException - { - if (threadId == -1) - threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients, distributionType); - - if (message.trim().length() > 0) - slideDeck.addSlide(new TextSlide(context, message)); - - SendReq sendRequest = new SendReq(); - PduBody body = slideDeck.toPduBody(); - - sendRequest.setDate(System.currentTimeMillis() / 1000L); - sendRequest.setBody(body); - sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes()); - -// Recipients secureRecipients = recipients.getSecureSessionRecipients(context); -// Recipients insecureRecipients = recipients.getInsecureSessionRecipients(context); - -// for (Recipient secureRecipient : secureRecipients.getRecipientsList()) { -// sendMms(context, new Recipients(secureRecipient), masterSecret, -// sendRequest, threadId, !forcePlaintext); -// } -// -// if (!insecureRecipients.isEmpty()) { -// sendMms(context, insecureRecipients, masterSecret, sendRequest, threadId, false); -// } - - sendMms(context, recipients, masterSecret, sendRequest, threadId, distributionType, secure); - - return threadId; - } - public static long send(Context context, MasterSecret masterSecret, OutgoingTextMessage message, long threadId) { @@ -129,6 +53,25 @@ public class MessageSender { return threadId; } + public static long send(Context context, MasterSecret masterSecret, OutgoingMediaMessage message, long threadId) + throws MmsException + { + if (threadId == -1) + threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(message.getRecipients(), message.getDistributionType()); + + long messageId = DatabaseFactory.getMmsDatabase(context) + .insertMessageOutbox(masterSecret, message, threadId); + + Intent intent = new Intent(SendReceiveService.SEND_MMS_ACTION, null, + context, SendReceiveService.class); + intent.putExtra("message_id", messageId); + intent.putExtra("thread_id", threadId); + + context.startService(intent); + + return threadId; + } + public static void resend(Context context, long messageId, boolean isMms) { @@ -146,34 +89,4 @@ public class MessageSender { context.startService(intent); } - private static void sendMms(Context context, Recipients recipients, MasterSecret masterSecret, - SendReq sendRequest, long threadId, int distributionType, boolean secure) - throws MmsException - { - Log.w("MessageSender", "Distribution type: " + distributionType); - - String[] recipientsArray = recipients.toNumberStringArray(true); - EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(recipientsArray); - - if (recipients.isSingleRecipient()) { - Log.w("MessageSender", "Single recipient!?"); - sendRequest.setTo(encodedNumbers); - } else if (distributionType == ThreadDatabase.DistributionTypes.BROADCAST) { - Log.w("MessageSender", "Broadcast..."); - sendRequest.setBcc(encodedNumbers); - } else if (distributionType == ThreadDatabase.DistributionTypes.CONVERSATION || distributionType == 0) { - Log.w("MessageSender", "Conversation..."); - sendRequest.setTo(encodedNumbers); - } - - long messageId = DatabaseFactory.getMmsDatabase(context) - .insertMessageOutbox(masterSecret, sendRequest, threadId, secure); - - Intent intent = new Intent(SendReceiveService.SEND_MMS_ACTION, null, - context, SendReceiveService.class); - intent.putExtra("message_id", messageId); - intent.putExtra("thread_id", threadId); - - context.startService(intent); - } } diff --git a/src/org/thoughtcrime/securesms/transport/PushTransport.java b/src/org/thoughtcrime/securesms/transport/PushTransport.java index bbe7ba938f..2e5d8079f4 100644 --- a/src/org/thoughtcrime/securesms/transport/PushTransport.java +++ b/src/org/thoughtcrime/securesms/transport/PushTransport.java @@ -25,6 +25,7 @@ import com.google.protobuf.ByteString; import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor; import org.thoughtcrime.securesms.crypto.KeyExchangeProcessorV2; import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.mms.PartParser; import org.thoughtcrime.securesms.push.PushServiceSocketFactory; @@ -243,41 +244,32 @@ public class PushTransport extends BaseTransport { PushMessageContent.Builder builder = PushMessageContent.newBuilder(); if (GroupUtil.isEncodedGroup(message.getTo()[0].getString())) { - byte[] groupId = GroupUtil.getDecodedId(message.getTo()[0].getString()); GroupContext.Builder groupBuilder = GroupContext.newBuilder(); + byte[] groupId = GroupUtil.getDecodedId(message.getTo()[0].getString()); groupBuilder.setId(ByteString.copyFrom(groupId)); + groupBuilder.setType(GroupContext.Type.DELIVER); - switch (message.getGroupAction()) { - case GroupContext.Type.ADD_VALUE: groupBuilder.setType(GroupContext.Type.ADD); break; - case GroupContext.Type.CREATE_VALUE: groupBuilder.setType(GroupContext.Type.CREATE); break; - case GroupContext.Type.QUIT_VALUE: groupBuilder.setType(GroupContext.Type.QUIT); break; - default: groupBuilder.setType(GroupContext.Type.DELIVER); break; - } - - if (message.getGroupAction() == GroupContext.Type.ADD_VALUE || - message.getGroupAction() == GroupContext.Type.CREATE_VALUE) + if (MmsSmsColumns.Types.isGroupAdd(message.getDatabaseMessageBox()) || + MmsSmsColumns.Types.isGroupModify(message.getDatabaseMessageBox()) || + MmsSmsColumns.Types.isGroupQuit(message.getDatabaseMessageBox())) { - GroupContext serialized = GroupContext.parseFrom(Base64.decode(message.getGroupActionArguments())); - groupBuilder.addAllMembers(serialized.getMembersList()); + if (messageBody != null && messageBody.trim().length() > 0) { + groupBuilder = GroupContext.parseFrom(Base64.decode(messageBody)).toBuilder(); + messageBody = null; - if (serialized.hasName()) { - groupBuilder.setName(serialized.getName()); + if (attachments != null && !attachments.isEmpty()) { + groupBuilder.setAvatar(AttachmentPointer.newBuilder() + .setId(attachments.get(0).getId()) + .setContentType(attachments.get(0).getContentType()) + .setKey(ByteString.copyFrom(attachments.get(0).getKey())) + .build()); + + attachments.remove(0); + } } } - if (message.getGroupAction() == GroupContext.Type.CREATE_VALUE && !attachments.isEmpty()) { - Log.w("PushTransport", "Adding avatar..."); - groupBuilder.setAvatar(AttachmentPointer.newBuilder() - .setId(attachments.get(0).getId()) - .setContentType(attachments.get(0).getContentType()) - .setKey(ByteString.copyFrom(attachments.get(0).getKey())) - .build()); - attachments.remove(0); - } else { - Log.w("PushTransport", "Not adding avatar: " + message.getGroupAction() + " , " + attachments.isEmpty()); - } - builder.setGroup(groupBuilder.build()); } diff --git a/src/org/thoughtcrime/securesms/transport/UniversalTransport.java b/src/org/thoughtcrime/securesms/transport/UniversalTransport.java index 587ac3a92f..d7f18746da 100644 --- a/src/org/thoughtcrime/securesms/transport/UniversalTransport.java +++ b/src/org/thoughtcrime/securesms/transport/UniversalTransport.java @@ -25,8 +25,8 @@ import org.thoughtcrime.securesms.mms.MmsSendResult; import org.thoughtcrime.securesms.push.PushServiceSocketFactory; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientFormattingException; +import org.thoughtcrime.securesms.sms.IncomingGroupMessage; import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage; -import org.thoughtcrime.securesms.sms.IncomingTextMessage; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; @@ -173,7 +173,7 @@ public class UniversalTransport { Log.w("UniversalTransport", ee); try { for (UnregisteredUserException unregistered : ee.getUnregisteredUserExceptions()) { - IncomingTextMessage quitMessage = IncomingTextMessage.createForLeavingGroup(mediaMessage.getTo()[0].getString(), unregistered.getE164Number()); + IncomingGroupMessage quitMessage = IncomingGroupMessage.createForQuit(mediaMessage.getTo()[0].getString(), unregistered.getE164Number()); DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageInbox(masterSecret, quitMessage); DatabaseFactory.getGroupDatabase(context).remove(GroupUtil.getDecodedId(mediaMessage.getTo()[0].getString()), unregistered.getE164Number()); } diff --git a/src/ws/com/google/android/mms/pdu/SendReq.java b/src/ws/com/google/android/mms/pdu/SendReq.java index 23022e1ccf..d4f824e29e 100644 --- a/src/ws/com/google/android/mms/pdu/SendReq.java +++ b/src/ws/com/google/android/mms/pdu/SendReq.java @@ -25,9 +25,7 @@ public class SendReq extends MultimediaMessagePdu { private static final String TAG = "SendReq"; private long databaseMessageId; private long messageBox; - private int groupAction; - private String groupActionArguments; - + public SendReq() { super(); @@ -92,14 +90,11 @@ public class SendReq extends MultimediaMessagePdu { super(headers, body); } - public SendReq(PduHeaders headers, PduBody body, long messageId, long messageBox, - int groupAction, String groupActionArguments) + public SendReq(PduHeaders headers, PduBody body, long messageId, long messageBox) { super(headers, body); this.databaseMessageId = messageId; this.messageBox = messageBox; - this.groupAction = groupAction; - this.groupActionArguments = groupActionArguments; } public long getDatabaseMessageBox() { @@ -110,22 +105,6 @@ public class SendReq extends MultimediaMessagePdu { return databaseMessageId; } - public int getGroupAction() { - return this.groupAction; - } - - public String getGroupActionArguments() { - return this.groupActionArguments; - } - - public void setGroupAction(int groupAction) { - this.groupAction = groupAction; - } - - public void setGroupActionArguments(String groupActionArguments) { - this.groupActionArguments = groupActionArguments; - } - /** * Get Bcc value. *