kopia lustrzana https://github.com/ryukoposting/Signal-Android
				
				
				
			Display group actions and correctly handle group delivery.
							rodzic
							
								
									7c46f3cbf8
								
							
						
					
					
						commit
						067799be06
					
				| 
						 | 
				
			
			@ -833,11 +833,12 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,7 @@ import android.graphics.Rect;
 | 
			
		|||
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;
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +61,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
 | 
			
		|||
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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +71,8 @@ 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -175,8 +179,25 @@ public class ConversationItem extends LinearLayout {
 | 
			
		|||
  /// 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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ import android.content.Intent;
 | 
			
		|||
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;
 | 
			
		||||
| 
						 | 
				
			
			@ -102,9 +103,14 @@ public class ConversationListItem extends RelativeLayout
 | 
			
		|||
 | 
			
		||||
    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()));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,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.OutgoingTextMessage;
 | 
			
		||||
import org.thoughtcrime.securesms.transport.PushTransport;
 | 
			
		||||
import org.thoughtcrime.securesms.util.ActionBarUtil;
 | 
			
		||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
 | 
			
		||||
| 
						 | 
				
			
			@ -366,6 +367,8 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
 | 
			
		|||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -389,9 +392,23 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
 | 
			
		|||
      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);
 | 
			
		||||
 | 
			
		||||
    return new Pair<Long, List<Recipient>>(threadId, failures);
 | 
			
		||||
      for (long messageId : messageIds) {
 | 
			
		||||
        DatabaseFactory.getEncryptingSmsDatabase(this).markAsSent(messageId);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      return new Pair<Long, List<Recipient>>(threadId, failures);
 | 
			
		||||
    } catch (RecipientFormattingException e) {
 | 
			
		||||
      throw new AssertionError(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private long handleCreateMmsGroup(Set<Recipient> members) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -647,6 +647,10 @@ 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 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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
 | 
			
		|||
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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,11 +91,20 @@ public class GroupDatabase extends Database {
 | 
			
		|||
                     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());
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +157,7 @@ public class GroupDatabase extends Database {
 | 
			
		|||
        contents.put(MEMBERS, Util.join(concatenatedMembers, ","));
 | 
			
		||||
 | 
			
		||||
        databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
 | 
			
		||||
                                                    new String[] {Hex.toString(id)});
 | 
			
		||||
                                                    new String[] {GroupUtil.getEncodedId(id)});
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +170,7 @@ public class GroupDatabase extends Database {
 | 
			
		|||
    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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +178,8 @@ public class GroupDatabase extends Database {
 | 
			
		|||
 | 
			
		||||
    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()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 + ");",
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +181,8 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
 | 
			
		|||
 | 
			
		||||
  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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -399,6 +400,8 @@ 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));
 | 
			
		||||
| 
						 | 
				
			
			@ -797,6 +800,8 @@ 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -811,7 +816,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);
 | 
			
		||||
                                              transactionIdBytes, mailbox, groupAction, groupActionArgs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private MediaMmsMessageRecord getMediaMmsMessageRecord(Cursor cursor) {
 | 
			
		||||
| 
						 | 
				
			
			@ -822,6 +827,8 @@ 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -830,7 +837,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
 | 
			
		|||
 | 
			
		||||
      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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,8 @@ public class MmsSmsDatabase extends Database {
 | 
			
		|||
                              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";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +72,8 @@ public class MmsSmsDatabase extends Database {
 | 
			
		|||
                              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;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +91,8 @@ public class MmsSmsDatabase extends Database {
 | 
			
		|||
                              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";
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +115,7 @@ 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,
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +125,7 @@ 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};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,6 +154,8 @@ 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>();
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +169,8 @@ 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,6 @@ import android.telephony.PhoneNumberUtils;
 | 
			
		|||
import android.util.Log;
 | 
			
		||||
import android.util.Pair;
 | 
			
		||||
 | 
			
		||||
import org.thoughtcrime.securesms.contacts.ContactPhotoFactory;
 | 
			
		||||
import org.thoughtcrime.securesms.database.model.DisplayRecord;
 | 
			
		||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.Recipient;
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +65,8 @@ 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);";
 | 
			
		||||
    SUBJECT + " TEXT, " + BODY + " TEXT, " + SERVICE_CENTER + " TEXT, " +
 | 
			
		||||
    GROUP_ACTION + " INTEGER DEFAULT -1, " + GROUP_ACTION_ARGUMENTS + " 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
 | 
			
		||||
      REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER, GROUP_ACTION, GROUP_ACTION_ARGUMENTS
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  public SmsDatabase(Context context, SQLiteOpenHelper databaseHelper) {
 | 
			
		||||
| 
						 | 
				
			
			@ -303,6 +303,8 @@ 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +340,8 @@ 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));
 | 
			
		||||
| 
						 | 
				
			
			@ -494,6 +498,8 @@ 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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -501,7 +507,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
 | 
			
		|||
                                   recipients.getPrimaryRecipient(),
 | 
			
		||||
                                   addressDeviceId,
 | 
			
		||||
                                   dateSent, dateReceived, type,
 | 
			
		||||
                                   threadId, status);
 | 
			
		||||
                                   threadId, status, groupAction, groupActionArgs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Recipients getRecipientsFor(String address) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,13 +53,15 @@ 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, " +
 | 
			
		||||
    HAS_ATTACHMENT + " INTEGER DEFAULT 0);";
 | 
			
		||||
    SNIPPET_TYPE + " INTEGER DEFAULT 0, " + GROUP_ACTION + " INTEGER DEFAULT -1, " +
 | 
			
		||||
    GROUP_ACTION_ARG + " TEXT, " + HAS_ATTACHMENT + " INTEGER DEFAULT 0);";
 | 
			
		||||
 | 
			
		||||
  public static final String[] CREATE_INDEXS = {
 | 
			
		||||
    "CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + RECIPIENT_IDS + ");",
 | 
			
		||||
| 
						 | 
				
			
			@ -99,17 +101,6 @@ public class ThreadDatabase extends Database {
 | 
			
		|||
    return sb.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private long createThreadForGroup(String group) {
 | 
			
		||||
    long date = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
    ContentValues values = new ContentValues();
 | 
			
		||||
    values.put(DATE, date - date % 1000);
 | 
			
		||||
    values.put(RECIPIENT_IDS, group);
 | 
			
		||||
    values.put(MESSAGE_COUNT, 0);
 | 
			
		||||
 | 
			
		||||
    return databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, values);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private long createThreadForRecipients(String recipients, int recipientCount, int distributionType) {
 | 
			
		||||
    ContentValues contentValues = new ContentValues(4);
 | 
			
		||||
    long date                   = System.currentTimeMillis();
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +117,16 @@ 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) {
 | 
			
		||||
  private void updateThread(long threadId, long count, String body, long date, long type,
 | 
			
		||||
                            int groupAction, String groupActionArguments)
 | 
			
		||||
  {
 | 
			
		||||
    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 + ""});
 | 
			
		||||
| 
						 | 
				
			
			@ -358,26 +353,6 @@ public class ThreadDatabase extends Database {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public long getThreadIdForGroup(String groupId) {
 | 
			
		||||
    SQLiteDatabase db      = databaseHelper.getReadableDatabase();
 | 
			
		||||
    String where           = RECIPIENT_IDS + " = ?";
 | 
			
		||||
    String[] recipientsArg = new String[] {groupId};
 | 
			
		||||
    Cursor cursor          = null;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      cursor = db.query(TABLE_NAME, new String[]{ID}, where, recipientsArg, null, null, null);
 | 
			
		||||
 | 
			
		||||
      if (cursor != null && cursor.moveToFirst()) {
 | 
			
		||||
        return cursor.getLong(cursor.getColumnIndexOrThrow(ID));
 | 
			
		||||
      } else {
 | 
			
		||||
        return createThreadForGroup(groupId);
 | 
			
		||||
      }
 | 
			
		||||
    } finally {
 | 
			
		||||
      if (cursor != null)
 | 
			
		||||
        cursor.close();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public Recipients getRecipientsForThreadId(long threadId) {
 | 
			
		||||
    SQLiteDatabase db = databaseHelper.getReadableDatabase();
 | 
			
		||||
    Cursor cursor     = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -414,7 +389,8 @@ 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());
 | 
			
		||||
        updateThread(threadId, count, record.getBody().getBody(), record.getDateReceived(),
 | 
			
		||||
                     record.getType(), record.getGroupAction(), record.getGroupActionArguments());
 | 
			
		||||
      } else {
 | 
			
		||||
        deleteThread(threadId);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -470,9 +446,12 @@ 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);
 | 
			
		||||
                              read == 1, threadId, type, distributionType,
 | 
			
		||||
                              groupAction, groupActionArg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private DisplayRecord.Body getPlaintextBody(Cursor cursor) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,22 +36,26 @@ public abstract class DisplayRecord {
 | 
			
		|||
  protected final long type;
 | 
			
		||||
 | 
			
		||||
  private final Recipients recipients;
 | 
			
		||||
  private final long dateSent;
 | 
			
		||||
  private final long dateReceived;
 | 
			
		||||
  private final long threadId;
 | 
			
		||||
  private final Body body;
 | 
			
		||||
//  private final String body;
 | 
			
		||||
  private final long       dateSent;
 | 
			
		||||
  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)
 | 
			
		||||
                       long dateReceived, long threadId, long type, int groupAction,
 | 
			
		||||
                       String groupActionArguments)
 | 
			
		||||
  {
 | 
			
		||||
    this.context      = context.getApplicationContext();
 | 
			
		||||
    this.threadId     = threadId;
 | 
			
		||||
    this.recipients   = recipients;
 | 
			
		||||
    this.dateSent     = dateSent;
 | 
			
		||||
    this.dateReceived = dateReceived;
 | 
			
		||||
    this.type         = type;
 | 
			
		||||
    this.body         = body;
 | 
			
		||||
    this.context              = context.getApplicationContext();
 | 
			
		||||
    this.threadId             = threadId;
 | 
			
		||||
    this.recipients           = recipients;
 | 
			
		||||
    this.dateSent             = dateSent;
 | 
			
		||||
    this.dateReceived         = dateReceived;
 | 
			
		||||
    this.type                 = type;
 | 
			
		||||
    this.body                 = body;
 | 
			
		||||
    this.groupAction          = groupAction;
 | 
			
		||||
    this.groupActionArguments = groupActionArguments;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public Body getBody() {
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +84,14 @@ public abstract class DisplayRecord {
 | 
			
		|||
    return SmsDatabase.Types.isKeyExchangeType(type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int getGroupAction() {
 | 
			
		||||
    return groupAction;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getGroupActionArguments() {
 | 
			
		||||
    return groupActionArguments;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static class Body {
 | 
			
		||||
    private final String body;
 | 
			
		||||
    private final boolean plaintext;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,10 +44,12 @@ 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 partCount, long mailbox, int groupAction,
 | 
			
		||||
                               String groupActionArguments)
 | 
			
		||||
  {
 | 
			
		||||
    super(context, id, body, recipients, individualRecipient, recipientDeviceId,
 | 
			
		||||
          dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox);
 | 
			
		||||
          dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox,
 | 
			
		||||
          groupAction, groupActionArguments);
 | 
			
		||||
 | 
			
		||||
    this.context   = context.getApplicationContext();
 | 
			
		||||
    this.partCount = partCount;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,9 +53,9 @@ public abstract class MessageRecord extends DisplayRecord {
 | 
			
		|||
                Recipient individualRecipient, int recipientDeviceId,
 | 
			
		||||
                long dateSent, long dateReceived,
 | 
			
		||||
                long threadId, int deliveryStatus,
 | 
			
		||||
                long type)
 | 
			
		||||
                long type, int groupAction, String groupActionArguments)
 | 
			
		||||
  {
 | 
			
		||||
    super(context, body, recipients, dateSent, dateReceived, threadId, type);
 | 
			
		||||
    super(context, body, recipients, dateSent, dateReceived, threadId, type, groupAction, groupActionArguments);
 | 
			
		||||
    this.id                  = id;
 | 
			
		||||
    this.individualRecipient = individualRecipient;
 | 
			
		||||
    this.recipientDeviceId   = recipientDeviceId;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,10 +44,11 @@ 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 status, byte[] transactionId, long mailbox,
 | 
			
		||||
                                      int groupAction, String groupActionArguments)
 | 
			
		||||
  {
 | 
			
		||||
    super(context, id, new Body("", true), recipients, individualRecipient, recipientDeviceId,
 | 
			
		||||
          dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox);
 | 
			
		||||
          dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox, groupAction, groupActionArguments);
 | 
			
		||||
 | 
			
		||||
    this.contentLocation = contentLocation;
 | 
			
		||||
    this.messageSize     = messageSize;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,10 +41,12 @@ public class SmsMessageRecord extends MessageRecord {
 | 
			
		|||
                          int recipientDeviceId,
 | 
			
		||||
                          long dateSent, long dateReceived,
 | 
			
		||||
                          long type, long threadId,
 | 
			
		||||
                          int status)
 | 
			
		||||
                          int status, int groupAction,
 | 
			
		||||
                          String groupActionArguments)
 | 
			
		||||
  {
 | 
			
		||||
    super(context, id, body, recipients, individualRecipient, recipientDeviceId,
 | 
			
		||||
          dateSent, dateReceived, threadId, getGenericDeliveryStatus(status), type);
 | 
			
		||||
          dateSent, dateReceived, threadId, getGenericDeliveryStatus(status), type,
 | 
			
		||||
          groupAction, groupActionArguments);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public long getType() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,11 @@ import android.text.style.StyleSpan;
 | 
			
		|||
import org.thoughtcrime.securesms.R;
 | 
			
		||||
import org.thoughtcrime.securesms.database.SmsDatabase;
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.Recipients;
 | 
			
		||||
import org.whispersystems.textsecure.push.PushMessageProtos;
 | 
			
		||||
import org.whispersystems.textsecure.util.Util;
 | 
			
		||||
 | 
			
		||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The message record model which represents thread heading messages.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -41,9 +44,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 distributionType, int groupAction, String groupActionArg)
 | 
			
		||||
  {
 | 
			
		||||
    super(context, body, recipients, date, date, threadId, snippetType);
 | 
			
		||||
    super(context, body, recipients, date, date, threadId, snippetType, groupAction, groupActionArg);
 | 
			
		||||
    this.context          = context.getApplicationContext();
 | 
			
		||||
    this.count            = count;
 | 
			
		||||
    this.read             = read;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +57,14 @@ public class ThreadRecord extends DisplayRecord {
 | 
			
		|||
  public SpannableString getDisplayBody() {
 | 
			
		||||
    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("Added " + getGroupActionArguments());
 | 
			
		||||
    } else if (getGroupAction() == GroupContext.Type.QUIT_VALUE) {
 | 
			
		||||
      return emphasisAdded(getRecipients().toShortString() + " left the group.");
 | 
			
		||||
    } else if (getGroupAction() == GroupContext.Type.MODIFY_VALUE) {
 | 
			
		||||
      return emphasisAdded(getRecipients().toShortString() + " modified the group.");
 | 
			
		||||
    } else if (isKeyExchange()) {
 | 
			
		||||
      return emphasisAdded(context.getString(R.string.ConversationListItem_key_exchange_message));
 | 
			
		||||
    } else if (SmsDatabase.Types.isFailedDecryptType(type)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,11 +20,15 @@ public class IncomingMediaMessage {
 | 
			
		|||
  private final PduHeaders headers;
 | 
			
		||||
  private final PduBody    body;
 | 
			
		||||
  private final String     groupId;
 | 
			
		||||
  private final int        groupAction;
 | 
			
		||||
  private final String     groupActionArguments;
 | 
			
		||||
 | 
			
		||||
  public IncomingMediaMessage(RetrieveConf retreived) {
 | 
			
		||||
    this.headers = retreived.getPduHeaders();
 | 
			
		||||
    this.body    = retreived.getBody();
 | 
			
		||||
    this.groupId = null;
 | 
			
		||||
    this.headers              = retreived.getPduHeaders();
 | 
			
		||||
    this.body                 = retreived.getBody();
 | 
			
		||||
    this.groupId              = null;
 | 
			
		||||
    this.groupAction          = -1;
 | 
			
		||||
    this.groupActionArguments = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public IncomingMediaMessage(MasterSecret masterSecret, String localNumber,
 | 
			
		||||
| 
						 | 
				
			
			@ -35,9 +39,13 @@ public class IncomingMediaMessage {
 | 
			
		|||
    this.body    = new PduBody();
 | 
			
		||||
 | 
			
		||||
    if (messageContent.hasGroup()) {
 | 
			
		||||
      this.groupId = GroupUtil.getEncodedId(messageContent.getGroup().getId().toByteArray());
 | 
			
		||||
      this.groupId              = GroupUtil.getEncodedId(messageContent.getGroup().getId().toByteArray());
 | 
			
		||||
      this.groupAction          = messageContent.getGroup().getType().getNumber();
 | 
			
		||||
      this.groupActionArguments = GroupUtil.getActionArgument(messageContent.getGroup());
 | 
			
		||||
    } else {
 | 
			
		||||
      this.groupId = null;
 | 
			
		||||
      this.groupId              = null;
 | 
			
		||||
      this.groupAction          = -1;
 | 
			
		||||
      this.groupActionArguments = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.headers.setEncodedStringValue(new EncodedStringValue(message.getSource()), PduHeaders.FROM);
 | 
			
		||||
| 
						 | 
				
			
			@ -90,4 +98,11 @@ public class IncomingMediaMessage {
 | 
			
		|||
         headers.getEncodedStringValues(PduHeaders.TO).length > 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int getGroupAction() {
 | 
			
		||||
    return groupAction;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getGroupActionArguments() {
 | 
			
		||||
    return groupActionArguments;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,57 +0,0 @@
 | 
			
		|||
package org.thoughtcrime.securesms.push;
 | 
			
		||||
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.Recipient;
 | 
			
		||||
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class GroupActionRecord {
 | 
			
		||||
 | 
			
		||||
  private static final int CREATE_GROUP_TYPE = 1;
 | 
			
		||||
  private static final int ADD_USERS_TYPE    = 2;
 | 
			
		||||
  private static final int LEAVE_GROUP_TYPE  = 3;
 | 
			
		||||
 | 
			
		||||
  private final int            type;
 | 
			
		||||
  private final Set<Recipient> recipients;
 | 
			
		||||
  private final byte[]         groupId;
 | 
			
		||||
  private final String         groupName;
 | 
			
		||||
  private final byte[]         avatar;
 | 
			
		||||
 | 
			
		||||
  public GroupActionRecord(int type, byte[] groupId, String groupName,
 | 
			
		||||
                           byte[] avatar, Set<Recipient> recipients)
 | 
			
		||||
  {
 | 
			
		||||
    this.type       = type;
 | 
			
		||||
    this.groupId    = groupId;
 | 
			
		||||
    this.groupName  = groupName;
 | 
			
		||||
    this.avatar     = avatar;
 | 
			
		||||
    this.recipients = recipients;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isCreateAction() {
 | 
			
		||||
    return type== CREATE_GROUP_TYPE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isAddUsersAction() {
 | 
			
		||||
    return type == ADD_USERS_TYPE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isLeaveAction() {
 | 
			
		||||
    return type == LEAVE_GROUP_TYPE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  public Set<Recipient> getRecipients() {
 | 
			
		||||
    return recipients;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public byte[] getGroupId() {
 | 
			
		||||
    return groupId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getGroupName() {
 | 
			
		||||
    return groupName;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public byte[] getAvatar() {
 | 
			
		||||
    return avatar;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,10 @@ public class Recipient implements Parcelable, CanonicalRecipient {
 | 
			
		|||
    return this.contactUri;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void setContactPhoto(Bitmap bitmap) {
 | 
			
		||||
    this.contactPhoto = bitmap;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized String getName() {
 | 
			
		||||
    return this.name;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -149,6 +153,18 @@ public class Recipient implements Parcelable, CanonicalRecipient {
 | 
			
		|||
    listeners.remove(listener);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void notifyListeners() {
 | 
			
		||||
    HashSet<RecipientModifiedListener> localListeners;
 | 
			
		||||
 | 
			
		||||
    synchronized (this) {
 | 
			
		||||
      localListeners = (HashSet<RecipientModifiedListener>)listeners.clone();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (RecipientModifiedListener listener : localListeners) {
 | 
			
		||||
      listener.onModified(this);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void writeToParcel(Parcel dest, int flags) {
 | 
			
		||||
    dest.writeString(number);
 | 
			
		||||
    dest.writeString(name);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.recipients;
 | 
			
		|||
 | 
			
		||||
import android.os.Parcel;
 | 
			
		||||
import android.os.Parcelable;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.util.Patterns;
 | 
			
		||||
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.Recipient.RecipientModifiedListener;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +146,10 @@ public class Recipients implements Parcelable {
 | 
			
		|||
    while (iterator.hasNext()) {
 | 
			
		||||
      String number = iterator.next().getNumber();
 | 
			
		||||
 | 
			
		||||
      if (scrub && number != null && !Patterns.EMAIL_ADDRESS.matcher(number).matches()) {
 | 
			
		||||
      if (scrub && number != null &&
 | 
			
		||||
          !Patterns.EMAIL_ADDRESS.matcher(number).matches() &&
 | 
			
		||||
          !GroupUtil.isEncodedGroup(number))
 | 
			
		||||
      {
 | 
			
		||||
        number = number.replaceAll("[^0-9+]", "");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,12 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
 | 
			
		|||
import org.thoughtcrime.securesms.database.GroupDatabase;
 | 
			
		||||
import org.thoughtcrime.securesms.database.PartDatabase;
 | 
			
		||||
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.Recipient;
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
 | 
			
		||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
 | 
			
		||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
 | 
			
		||||
import org.thoughtcrime.securesms.util.BitmapUtil;
 | 
			
		||||
import org.thoughtcrime.securesms.util.GroupUtil;
 | 
			
		||||
import org.whispersystems.textsecure.crypto.AttachmentCipherInputStream;
 | 
			
		||||
import org.whispersystems.textsecure.crypto.InvalidMessageException;
 | 
			
		||||
import org.whispersystems.textsecure.crypto.MasterSecret;
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +59,16 @@ public class AvatarDownloader {
 | 
			
		|||
 | 
			
		||||
        database.updateAvatar(groupId, avatar);
 | 
			
		||||
 | 
			
		||||
        avatar.recycle();
 | 
			
		||||
        try {
 | 
			
		||||
          Recipient groupRecipient = RecipientFactory.getRecipientsFromString(context, GroupUtil.getEncodedId(groupId), true)
 | 
			
		||||
                                                     .getPrimaryRecipient();
 | 
			
		||||
          groupRecipient.setContactPhoto(avatar);
 | 
			
		||||
          groupRecipient.notifyListeners();
 | 
			
		||||
        } catch (RecipientFormattingException e) {
 | 
			
		||||
          Log.w("AvatarDownloader", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
//        avatar.recycle();
 | 
			
		||||
        attachment.delete();
 | 
			
		||||
      }
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.sms.IncomingKeyExchangeMessage;
 | 
			
		|||
import org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage;
 | 
			
		||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
 | 
			
		||||
import org.thoughtcrime.securesms.sms.SmsTransportDetails;
 | 
			
		||||
import org.thoughtcrime.securesms.util.GroupUtil;
 | 
			
		||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
 | 
			
		||||
import org.whispersystems.textsecure.crypto.InvalidKeyException;
 | 
			
		||||
import org.whispersystems.textsecure.crypto.InvalidMessageException;
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +34,6 @@ import org.whispersystems.textsecure.push.IncomingPushMessage;
 | 
			
		|||
import org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent;
 | 
			
		||||
import org.whispersystems.textsecure.storage.InvalidKeyIdException;
 | 
			
		||||
import org.whispersystems.textsecure.storage.RecipientDevice;
 | 
			
		||||
import org.whispersystems.textsecure.util.Hex;
 | 
			
		||||
 | 
			
		||||
import ws.com.google.android.mms.MmsException;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +218,7 @@ public class PushReceiver {
 | 
			
		|||
 | 
			
		||||
    if (messageContent.getAttachmentsCount() > 0) {
 | 
			
		||||
      handleReceivedMediaMessage(masterSecret, message, messageContent, secure);
 | 
			
		||||
    } else if (messageContent.hasBody()) {
 | 
			
		||||
    } else {
 | 
			
		||||
      handleReceivedTextMessage(masterSecret, message, messageContent, secure);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -263,8 +261,7 @@ public class PushReceiver {
 | 
			
		|||
                                         boolean secure)
 | 
			
		||||
  {
 | 
			
		||||
    EncryptingSmsDatabase database    = DatabaseFactory.getEncryptingSmsDatabase(context);
 | 
			
		||||
    String                groupId     = messageContent.hasGroup() ? GroupUtil.getEncodedId(messageContent.getGroup().getId().toByteArray()) : null;
 | 
			
		||||
    IncomingTextMessage   textMessage = new IncomingTextMessage(message, "", groupId);
 | 
			
		||||
    IncomingTextMessage   textMessage = new IncomingTextMessage(message, "", messageContent.getGroup());
 | 
			
		||||
 | 
			
		||||
    if (secure) {
 | 
			
		||||
      textMessage = new IncomingEncryptedMessage(textMessage, "");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,11 +4,14 @@ import android.os.Parcel;
 | 
			
		|||
import android.os.Parcelable;
 | 
			
		||||
import android.telephony.SmsMessage;
 | 
			
		||||
 | 
			
		||||
import org.thoughtcrime.securesms.util.GroupUtil;
 | 
			
		||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
 | 
			
		||||
import org.whispersystems.textsecure.storage.RecipientDevice;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext;
 | 
			
		||||
 | 
			
		||||
public class IncomingTextMessage implements Parcelable {
 | 
			
		||||
 | 
			
		||||
  public static final Parcelable.Creator<IncomingTextMessage> CREATOR = new Parcelable.Creator<IncomingTextMessage>() {
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +35,8 @@ 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();
 | 
			
		||||
| 
						 | 
				
			
			@ -43,9 +48,11 @@ 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, String groupId) {
 | 
			
		||||
  public IncomingTextMessage(IncomingPushMessage message, String encodedBody, GroupContext group) {
 | 
			
		||||
    this.message              = encodedBody;
 | 
			
		||||
    this.sender               = message.getSource();
 | 
			
		||||
    this.senderDeviceId       = message.getSourceDevice();
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +61,16 @@ public class IncomingTextMessage implements Parcelable {
 | 
			
		|||
    this.replyPathPresent     = true;
 | 
			
		||||
    this.pseudoSubject        = "";
 | 
			
		||||
    this.sentTimestampMillis  = message.getTimestampMillis();
 | 
			
		||||
    this.groupId              = groupId;
 | 
			
		||||
 | 
			
		||||
    if (group != null) {
 | 
			
		||||
      this.groupId             = GroupUtil.getEncodedId(group.getId().toByteArray());
 | 
			
		||||
      this.groupAction         = group.getType().getNumber();
 | 
			
		||||
      this.groupActionArgument = GroupUtil.getActionArgument(group);
 | 
			
		||||
    } else {
 | 
			
		||||
      this.groupId             = null;
 | 
			
		||||
      this.groupAction         = -1;
 | 
			
		||||
      this.groupActionArgument = null;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public IncomingTextMessage(Parcel in) {
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +83,8 @@ 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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +97,8 @@ 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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +117,8 @@ 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 long getSentTimestampMillis() {
 | 
			
		||||
| 
						 | 
				
			
			@ -151,6 +173,14 @@ public class IncomingTextMessage implements Parcelable {
 | 
			
		|||
    return groupId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int getGroupAction() {
 | 
			
		||||
    return groupAction;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getGroupActionArgument() {
 | 
			
		||||
    return groupActionArgument;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int describeContents() {
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -167,5 +197,7 @@ public class IncomingTextMessage implements Parcelable {
 | 
			
		|||
    out.writeString(pseudoSubject);
 | 
			
		||||
    out.writeLong(sentTimestampMillis);
 | 
			
		||||
    out.writeString(groupId);
 | 
			
		||||
    out.writeInt(groupAction);
 | 
			
		||||
    out.writeString(groupActionArgument);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,20 +7,33 @@ import org.thoughtcrime.securesms.recipients.Recipients;
 | 
			
		|||
public class OutgoingTextMessage {
 | 
			
		||||
 | 
			
		||||
  private final Recipients recipients;
 | 
			
		||||
  private       String     message;
 | 
			
		||||
  private final String     message;
 | 
			
		||||
  private final int        groupAction;
 | 
			
		||||
  private final String     groupActionArguments;
 | 
			
		||||
 | 
			
		||||
  public OutgoingTextMessage(Recipient recipient, String message) {
 | 
			
		||||
    this(new Recipients(recipient), message);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public OutgoingTextMessage(Recipients recipients, String message) {
 | 
			
		||||
    this.recipients = recipients;
 | 
			
		||||
    this.message    = message;
 | 
			
		||||
    this.recipients           = recipients;
 | 
			
		||||
    this.message              = message;
 | 
			
		||||
    this.groupAction          = -1;
 | 
			
		||||
    this.groupActionArguments = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public OutgoingTextMessage(Recipient recipient, int groupAction, String groupActionArguments) {
 | 
			
		||||
    this.recipients           = new Recipients(recipient);
 | 
			
		||||
    this.groupAction          = groupAction;
 | 
			
		||||
    this.groupActionArguments = groupActionArguments;
 | 
			
		||||
    this.message              = "";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected OutgoingTextMessage(OutgoingTextMessage base, String body) {
 | 
			
		||||
    this.recipients     = base.getRecipients();
 | 
			
		||||
    this.message        = body;
 | 
			
		||||
    this.recipients           = base.getRecipients();
 | 
			
		||||
    this.groupAction          = base.getGroupAction();
 | 
			
		||||
    this.groupActionArguments = base.getGroupActionArguments();
 | 
			
		||||
    this.message              = body;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getMessageBody() {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,4 +69,12 @@ public class OutgoingTextMessage {
 | 
			
		|||
  public OutgoingTextMessage withBody(String body) {
 | 
			
		||||
    return new OutgoingTextMessage(this, body);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int getGroupAction() {
 | 
			
		||||
    return groupAction;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getGroupActionArguments() {
 | 
			
		||||
    return groupActionArguments;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,8 @@ import org.whispersystems.textsecure.util.Hex;
 | 
			
		|||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext;
 | 
			
		||||
 | 
			
		||||
public class GroupUtil {
 | 
			
		||||
 | 
			
		||||
  private static final String ENCODED_GROUP_PREFIX = "__textsecure_group__!";
 | 
			
		||||
| 
						 | 
				
			
			@ -24,4 +26,15 @@ public class GroupUtil {
 | 
			
		|||
    return groupId.startsWith(ENCODED_GROUP_PREFIX);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static String getActionArgument(GroupContext group) {
 | 
			
		||||
    if (group.getType().equals(GroupContext.Type.CREATE) ||
 | 
			
		||||
        group.getType().equals(GroupContext.Type.ADD))
 | 
			
		||||
    {
 | 
			
		||||
      return org.whispersystems.textsecure.util.Util.join(group.getMembersList(), ",");
 | 
			
		||||
    } else if (group.getType().equals(GroupContext.Type.MODIFY)) {
 | 
			
		||||
      return group.getName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue