Skip to content

Commit

Permalink
Display group actions and correctly handle group delivery.
Browse files Browse the repository at this point in the history
  • Loading branch information
moxie0 committed Feb 14, 2014
1 parent 7c46f3c commit 067799b
Show file tree
Hide file tree
Showing 26 changed files with 304 additions and 160 deletions.
5 changes: 3 additions & 2 deletions src/org/thoughtcrime/securesms/ConversationActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -833,11 +833,12 @@ private boolean isExistingConversation() {
}

private boolean isSingleConversation() {
return getRecipients() != null && getRecipients().isSingleRecipient();
return getRecipients() != null && getRecipients().isSingleRecipient() && !getRecipients().isGroupRecipient();
}

private boolean isGroupConversation() {
return getRecipients() != null && !getRecipients().isSingleRecipient();
return getRecipients() != null &&
(!getRecipients().isSingleRecipient() || getRecipients().isGroupRecipient());
}

private Recipients getRecipients() {
Expand Down
25 changes: 23 additions & 2 deletions src/org/thoughtcrime/securesms/ConversationItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import android.graphics.drawable.ColorDrawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
Expand Down Expand Up @@ -60,6 +61,7 @@
import org.thoughtcrime.securesms.service.SendReceiveService;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.Emoji;
import org.whispersystems.textsecure.push.PushMessageProtos;
import org.whispersystems.textsecure.util.FutureTaskListener;
import org.whispersystems.textsecure.util.ListenableFutureTask;

Expand All @@ -69,6 +71,8 @@
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.
Expand Down Expand Up @@ -175,8 +179,25 @@ public void setHandler(Handler failedIconHandler) {
/// MessageRecord Attribute Parsers

private void setBodyText(MessageRecord messageRecord) {
bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(), Emoji.EMOJI_LARGE),
TextView.BufferType.SPANNABLE);
switch (messageRecord.getGroupAction()) {
case GroupContext.Type.QUIT_VALUE:
bodyText.setText(messageRecord.getIndividualRecipient().toShortString() + " has left the group.");
return;
case GroupContext.Type.ADD_VALUE:
case GroupContext.Type.CREATE_VALUE:
bodyText.setText(messageRecord.getGroupActionArguments() + " have joined the group.");
return;
case GroupContext.Type.MODIFY_VALUE:
bodyText.setText(messageRecord.getIndividualRecipient() + " has updated the group.");
return;
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(), Emoji.EMOJI_LARGE),
TextView.BufferType.SPANNABLE);
} else {
bodyText.setText(messageRecord.getDisplayBody());
}
}

private void setContactPhoto(MessageRecord messageRecord) {
Expand Down
12 changes: 9 additions & 3 deletions src/org/thoughtcrime/securesms/ConversationListItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.provider.Contacts.Intents;
import android.provider.ContactsContract.QuickContact;
Expand Down Expand Up @@ -102,9 +103,14 @@ public void set(ThreadRecord thread, Set<Long> selectedThreads, boolean batchMod

this.recipients.addListener(this);
this.fromView.setText(formatFrom(recipients, count, read));
this.subjectView.setText(Emoji.getInstance(context).emojify(thread.getDisplayBody(),
Emoji.EMOJI_SMALL),
TextView.BufferType.SPANNABLE);

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
this.subjectView.setText(Emoji.getInstance(context).emojify(thread.getDisplayBody(),
Emoji.EMOJI_SMALL),
TextView.BufferType.SPANNABLE);
} else {
this.subjectView.setText(thread.getDisplayBody());
}

if (thread.getDate() > 0)
this.dateView.setText(DateUtils.getBetterRelativeTimeSpanString(getContext(), thread.getDate()));
Expand Down
21 changes: 19 additions & 2 deletions src/org/thoughtcrime/securesms/GroupCreateActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
import org.thoughtcrime.securesms.transport.PushTransport;
import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.DynamicLanguage;
Expand Down Expand Up @@ -366,6 +367,8 @@ private Pair<Long, List<Recipient>> handleCreatePushGroup(String groupName,
byte[] groupId = groupDatabase.allocateGroupId();
AttachmentPointer avatarPointer = null;

memberE164Numbers.add(TextSecurePreferences.getLocalNumber(this));

GroupContext.Builder builder = GroupContext.newBuilder()
.setId(ByteString.copyFrom(groupId))
.setType(GroupContext.Type.CREATE)
Expand All @@ -389,9 +392,23 @@ private Pair<Long, List<Recipient>> handleCreatePushGroup(String groupName,
groupDatabase.updateAvatar(groupId, avatar);
}

long threadId = threadDatabase.getThreadIdForGroup(GroupUtil.getEncodedId(groupId));
try {
String groupRecipientId = GroupUtil.getEncodedId(groupId);
Recipient groupRecipient = RecipientFactory.getRecipientsFromString(this, groupRecipientId, false).getPrimaryRecipient();
OutgoingTextMessage outgoing = new OutgoingTextMessage(groupRecipient, GroupContext.Type.ADD_VALUE, org.whispersystems.textsecure.util.Util.join(memberE164Numbers, ","));
long threadId = threadDatabase.getThreadIdFor(new Recipients(groupRecipient));
List<Long> messageIds = DatabaseFactory.getEncryptingSmsDatabase(this)
.insertMessageOutbox(masterSecret, threadId, outgoing);

for (long messageId : messageIds) {
DatabaseFactory.getEncryptingSmsDatabase(this).markAsSent(messageId);
}

return new Pair<Long, List<Recipient>>(threadId, failures);

return new Pair<Long, List<Recipient>>(threadId, failures);
} catch (RecipientFormattingException e) {
throw new AssertionError(e);
}
}

private long handleCreateMmsGroup(Set<Recipient> members) {
Expand Down
4 changes: 4 additions & 0 deletions src/org/thoughtcrime/securesms/database/DatabaseFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,10 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
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 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();
Expand Down
19 changes: 15 additions & 4 deletions src/org/thoughtcrime/securesms/database/GroupDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.util.Hex;
import org.whispersystems.textsecure.util.Util;

Expand Down Expand Up @@ -90,11 +91,20 @@ public void create(byte[] groupId, String owner, String title,
List<String> members, AttachmentPointer avatar,
String relay)
{
List<String> filteredMembers = new LinkedList<String>();
String localNumber = TextSecurePreferences.getLocalNumber(context);

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);
contentValues.put(TITLE, title);
contentValues.put(MEMBERS, Util.join(members, ","));
contentValues.put(MEMBERS, Util.join(filteredMembers, ","));

if (avatar != null) {
contentValues.put(AVATAR_ID, avatar.getId());
Expand Down Expand Up @@ -147,7 +157,7 @@ public void add(byte[] id, String source, List<String> members) {
contents.put(MEMBERS, Util.join(concatenatedMembers, ","));

databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[] {Hex.toString(id)});
new String[] {GroupUtil.getEncodedId(id)});
}
}
}
Expand All @@ -160,15 +170,16 @@ public void remove(byte[] id, String source) {
contents.put(MEMBERS, Util.join(currentMembers, ","));

databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[]{Hex.toString(id)});
new String[]{GroupUtil.getEncodedId(id)});
}

private List<String> getCurrentMembers(byte[] id) {
Cursor cursor = null;

try {
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {MEMBERS},
GROUP_ID + " = ?", new String[] {Hex.toString(id)},
GROUP_ID + " = ?",
new String[] {GroupUtil.getEncodedId(id)},
null, null, null);

if (cursor != null && cursor.moveToFirst()) {
Expand Down
15 changes: 11 additions & 4 deletions src/org/thoughtcrime/securesms/database/MmsDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,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);";
DELIVERY_REPORT + " INTEGER, " + GROUP_ACTION + " INTEGER DEFAULT -1, " + GROUP_ACTION_ARGUMENTS + " TEXT);";

public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
Expand Down Expand Up @@ -181,7 +181,8 @@ public long getThreadIdForMessage(long id) {

private long getThreadIdFor(IncomingMediaMessage retrieved) throws RecipientFormattingException {
if (retrieved.getGroupId() != null) {
return DatabaseFactory.getThreadDatabase(context).getThreadIdForGroup(retrieved.getGroupId());
Recipients groupRecipients = RecipientFactory.getRecipientsFromString(context, retrieved.getGroupId(), true);
return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipients);
}

try {
Expand Down Expand Up @@ -399,6 +400,8 @@ private Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret, IncomingM
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));
Expand Down Expand Up @@ -797,6 +800,8 @@ private NotificationMmsMessageRecord getNotificationMmsMessageRecord(Cursor curs
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;
Expand All @@ -811,7 +816,7 @@ private NotificationMmsMessageRecord getNotificationMmsMessageRecord(Cursor curs
return new NotificationMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
addressDeviceId, dateSent, dateReceived, threadId,
contentLocationBytes, messageSize, expiry, status,
transactionIdBytes, mailbox);
transactionIdBytes, mailbox, groupAction, groupActionArgs);
}

private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
Expand All @@ -822,6 +827,8 @@ private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
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);
Expand All @@ -830,7 +837,7 @@ private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {

return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
addressDeviceId, dateSent, dateReceived, threadId, body,
slideDeck, partCount, box);
slideDeck, partCount, box, groupAction, groupActionArgs);
}

private Recipients getRecipientsFor(String address) {
Expand Down
3 changes: 2 additions & 1 deletion src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ 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;
Expand Down
15 changes: 12 additions & 3 deletions src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public Cursor getConversation(long threadId) {
SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY,
MmsDatabase.STATUS, TRANSPORT};
MmsDatabase.STATUS, MmsSmsColumns.GROUP_ACTION,
MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT};

String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";

Expand All @@ -71,7 +72,8 @@ public Cursor getConversationSnippet(long threadId) {
SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY,
MmsDatabase.STATUS, TRANSPORT};
MmsDatabase.STATUS, MmsSmsColumns.GROUP_ACTION,
MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT};

String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
Expand All @@ -89,7 +91,8 @@ public Cursor getUnread() {
MmsDatabase.PART_COUNT,
MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID,
MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY,
MmsDatabase.STATUS, TRANSPORT};
MmsDatabase.STATUS, MmsSmsColumns.GROUP_ACTION,
MmsSmsColumns.GROUP_ACTION_ARGUMENTS, TRANSPORT};

String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
String selection = MmsSmsColumns.READ + " = 0";
Expand All @@ -112,6 +115,7 @@ private Cursor queryTables(String[] projection, String selection, String order,
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,
Expand All @@ -121,6 +125,7 @@ private Cursor queryTables(String[] projection, String selection, String order,
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};


Expand Down Expand Up @@ -149,6 +154,8 @@ private Cursor queryTables(String[] projection, String selection, String order,
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>();
Expand All @@ -162,6 +169,8 @@ private Cursor queryTables(String[] projection, String selection, String order,
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);
Expand Down

0 comments on commit 067799b

Please sign in to comment.