Refactor group database model and flow.
1) Use existing DB types instead of adding new columns. 2) Store group attributes in message body, like everything else.master
parent
0cdc6fd87d
commit
9614dc9055
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Long, Recipients> handleCreatePushGroup(String groupName,
|
||||
byte[] avatar,
|
||||
Set<Recipient> members)
|
||||
byte[] avatar,
|
||||
Set<Recipient> members)
|
||||
throws InvalidNumberException, MmsException
|
||||
{
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(this);
|
||||
|
@ -378,17 +378,23 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
|||
List<String> 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<Long, Recipients>(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<Long, Recipients>(threadId, groupRecipient);
|
||||
} catch (RecipientFormattingException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (MmsException e) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -72,7 +72,7 @@ public class GroupDatabase extends Database {
|
|||
}
|
||||
|
||||
public Recipients getGroupMembers(byte[] groupId) {
|
||||
List<String> members = getCurrentMembers(groupId);
|
||||
List<String> members = getCurrentMembers(groupId);
|
||||
List<Recipient> recipients = new LinkedList<Recipient>();
|
||||
|
||||
for (String member : members) {
|
||||
|
@ -94,12 +94,17 @@ public class GroupDatabase extends Database {
|
|||
List<String> filteredMembers = new LinkedList<String>();
|
||||
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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<String> smsColumnsPresent = new HashSet<String>();
|
||||
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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> 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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<Long, Long> messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, groupMessage);
|
||||
smsDatabase.updateMessageBody(masterSecret, messageAndThreadId.first, body);
|
||||
|
||||
MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
}
|
||||
|
||||
private void handleEndSessionMessage(MasterSecret masterSecret,
|
||||
|
|
|
@ -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, "");
|
||||
}
|
||||
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IncomingTextMessage> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue