Listen for group updates, fix group updates, and Recipient marshing

This commit is contained in:
Moxie Marlinspike 2014-02-24 00:19:54 -08:00
parent 86b3de2a93
commit 5000957b99
13 changed files with 119 additions and 116 deletions

View File

@ -73,6 +73,8 @@ import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
import org.thoughtcrime.securesms.mms.MediaTooLargeException;
import org.thoughtcrime.securesms.mms.MmsSendHelper;
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
@ -85,8 +87,6 @@ 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;
@ -116,6 +116,7 @@ import java.util.List;
import ws.com.google.android.mms.MmsException;
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import static org.thoughtcrime.securesms.recipients.Recipient.RecipientModifiedListener;
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.GroupContext;
/**
@ -155,6 +156,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private AttachmentTypeSelectorAdapter attachmentAdapter;
private AttachmentManager attachmentManager;
private BroadcastReceiver securityUpdateReceiver;
private BroadcastReceiver groupUpdateReceiver;
private EmojiDrawer emojiDrawer;
private EmojiToggle emojiToggle;
@ -218,6 +220,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
@Override
protected void onDestroy() {
unregisterReceiver(securityUpdateReceiver);
unregisterReceiver(groupUpdateReceiver);
saveDraft();
MemoryCleaner.clean(masterSecret);
super.onDestroy();
@ -456,10 +459,10 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
initializeEnabledCheck();
} catch (IOException e) {
Log.w(TAG, e);
Toast.makeText(ConversationActivity.this, "Error leaving group....", Toast.LENGTH_LONG);
Toast.makeText(ConversationActivity.this, "Error leaving group....", Toast.LENGTH_LONG).show();
} catch (MmsException e) {
Log.w(TAG, e);
Toast.makeText(ConversationActivity.this, "Error leaving group...", Toast.LENGTH_LONG);
Toast.makeText(ConversationActivity.this, "Error leaving group...", Toast.LENGTH_LONG).show();
}
}
});
@ -706,7 +709,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private void initializeResources() {
recipientsPanel = (RecipientsPanel)findViewById(R.id.recipients);
recipients = getIntent().getParcelableExtra(RECIPIENTS_EXTRA);
recipients = RecipientFactory.getRecipientsForIds(this, getIntent().getStringExtra(RECIPIENTS_EXTRA), true);
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA,
ThreadDatabase.DistributionTypes.DEFAULT);
@ -739,6 +742,13 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
emojiDrawer.setComposeEditText(composeText);
emojiToggle.setOnClickListener(new EmojiToggleListener());
recipients.addListener(new RecipientModifiedListener() {
@Override
public void onModified(Recipient recipient) {
initializeTitleBar();
}
});
registerForContextMenu(sendButton);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
@ -777,9 +787,30 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
}
};
groupUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.w("ConversationActivity", "Group update received...");
if (recipients != null) {
String ids = recipients.toIdString();
Log.w("ConversationActivity", "Looking up new recipients...");
recipients = RecipientFactory.getRecipientsForIds(context, ids, true);
recipients.addListener(new RecipientModifiedListener() {
@Override
public void onModified(Recipient recipient) {
initializeTitleBar();
}
});
}
}
};
registerReceiver(securityUpdateReceiver,
new IntentFilter(KeyExchangeProcessor.SECURITY_UPDATE_EVENT),
KeyCachingService.KEY_PERMISSION, null);
registerReceiver(groupUpdateReceiver,
new IntentFilter(GroupDatabase.DATABASE_UPDATE_ACTION));
}
@ -959,7 +990,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
}
private boolean isPushGroupConversation() {
return getRecipients().isGroupRecipient();
return getRecipients() != null && getRecipients().isGroupRecipient();
}
private boolean isPushDestination() {
@ -967,6 +998,9 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
if (!TextSecurePreferences.isPushRegistered(this))
return false;
if (getRecipients() == null)
return false;
if (isPushGroupConversation())
return true;

View File

@ -20,6 +20,7 @@ import android.widget.CursorAdapter;
import com.actionbarsherlock.app.SherlockListFragment;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
@ -183,9 +184,11 @@ public class ConversationFragment extends SherlockListFragment
}
private void initializeResources() {
String recipientIds = this.getActivity().getIntent().getStringExtra("recipients");
this.masterSecret = (MasterSecret)this.getActivity().getIntent()
.getParcelableExtra("master_secret");
this.recipients = this.getActivity().getIntent().getParcelableExtra("recipients");
this.recipients = RecipientFactory.getRecipientsForIds(getActivity(), recipientIds, true);
this.threadId = this.getActivity().getIntent().getLongExtra("thread_id", -1);
}

View File

@ -177,7 +177,7 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
private void createConversation(long threadId, Recipients recipients, int distributionType) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.toIdString());
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, distributionType);

View File

@ -34,12 +34,12 @@ import org.thoughtcrime.securesms.contacts.RecipientsEditor;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
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.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;
@ -341,18 +341,6 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
new UpdateWhisperGroupAsyncTask().execute();
}
private static List<String> recipientsToNormalizedStrings(Collection<Recipient> recipients, String localNumber) {
final List<String> e164numbers = new ArrayList<String>(recipients.size());
for (Recipient contact : recipients) {
try {
e164numbers.add(PhoneNumberFormatter.formatNumber(contact.getNumber(), localNumber));
} catch (InvalidNumberException ine) {
Log.w(TAG, "Failed to format number for added group member.", ine);
}
}
return e164numbers;
}
private void enableWhisperGroupCreatingUi() {
findViewById(R.id.group_details_layout).setVisibility(View.GONE);
findViewById(R.id.creating_group_layout).setVisibility(View.VISIBLE);
@ -428,10 +416,11 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
{
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(this);
byte[] groupId = groupDatabase.allocateGroupId();
List<String> memberE164Numbers = getE164Numbers(members);
Set<String> memberE164Numbers = getE164Numbers(members);
groupDatabase.create(groupId, TextSecurePreferences.getLocalNumber(this), groupName,
memberE164Numbers, null, null);
memberE164Numbers.add(TextSecurePreferences.getLocalNumber(this));
groupDatabase.create(groupId, groupName, new LinkedList<String>(memberE164Numbers), null, null);
groupDatabase.updateAvatar(groupId, avatar);
return handlePushOperation(groupId, groupName, avatar, memberE164Numbers);
@ -442,24 +431,21 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
throws InvalidNumberException, MmsException
{
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(this);
List<String> memberE164Numbers = getE164Numbers(members);
Set<String> memberE164Numbers = getE164Numbers(members);
memberE164Numbers.add(TextSecurePreferences.getLocalNumber(this));
GroupDatabase.GroupRecord record = groupDatabase.getGroup(groupId);
Set<String> newMembers = new HashSet<String>(memberE164Numbers);
newMembers.removeAll(record.getMembers());
groupDatabase.add(groupId, TextSecurePreferences.getLocalNumber(this),
new LinkedList<String>(newMembers));
for (String number : memberE164Numbers)
Log.w(TAG, "Updating: " + number);
groupDatabase.updateMembers(groupId, new LinkedList<String>(memberE164Numbers));
groupDatabase.updateTitle(groupId, groupName);
groupDatabase.updateAvatar(groupId, avatar);
return handlePushOperation(groupId, groupName, avatar, memberE164Numbers);
}
private Pair<Long, Recipients> handlePushOperation(byte[] groupId, String groupName, byte[] avatar,
List<String> e164numbers)
Set<String> e164numbers)
throws MmsException, InvalidNumberException
{
@ -501,10 +487,10 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
return arrayList;
}
private List<String> getE164Numbers(Set<Recipient> recipients)
private Set<String> getE164Numbers(Set<Recipient> recipients)
throws InvalidNumberException
{
List<String> results = new LinkedList<String>();
Set<String> results = new HashSet<String>();
for (Recipient recipient : recipients) {
results.add(Util.canonicalizeNumber(this, recipient.getNumber()));
@ -545,7 +531,7 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
ArrayList<Recipient> selectedContactsList = setToArrayList(selectedContacts);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, new Recipients(selectedContactsList));
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, new Recipients(selectedContactsList).toIdString());
startActivity(intent);
finish();
} else {
@ -573,7 +559,9 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
}
final String name = (groupName.getText() != null) ? groupName.getText().toString() : null;
try {
return handleUpdatePushGroup(groupId, name, avatarBytes, selectedContacts);
Set<Recipient> unionContacts = new HashSet<Recipient>(selectedContacts);
unionContacts.addAll(existingContacts);
return handleUpdatePushGroup(groupId, name, avatarBytes, unionContacts);
} catch (MmsException e) {
Log.w(TAG, e);
return new Pair<Long,Recipients>(RES_MMS_EXCEPTION, null);
@ -638,7 +626,7 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.toIdString());
startActivity(intent);
finish();
} else if (threadId == RES_BAD_NUMBER) {
@ -671,7 +659,7 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
@Override
protected Boolean doInBackground(Void... voids) {
final GroupDatabase db = DatabaseFactory.getGroupDatabase(GroupCreateActivity.this);
final Recipients recipients = db.getGroupMembers(groupId);
final Recipients recipients = db.getGroupMembers(groupId, false);
if (recipients != null) {
final List<Recipient> recipientList = recipients.getRecipientsList();
if (recipientList != null) {

View File

@ -37,7 +37,7 @@ public class GroupMembersDialog extends AsyncTask<Void, Void, Recipients> {
try {
String groupId = recipients.getPrimaryRecipient().getNumber();
return DatabaseFactory.getGroupDatabase(context)
.getGroupMembers(GroupUtil.getDecodedId(groupId));
.getGroupMembers(GroupUtil.getDecodedId(groupId), true);
} catch (IOException e) {
Log.w("ConverstionActivity", e);
return new Recipients(new LinkedList<Recipient>());

View File

@ -135,7 +135,7 @@ public class RoutingActivity extends PassphraseRequiredSherlockActivity {
private Intent getConversationIntent(ConversationParameters parameters) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, parameters.recipients);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, parameters.recipients != null ? parameters.recipients.toIdString() : "");
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, parameters.thread);
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, parameters.draftText);

View File

@ -113,7 +113,7 @@ public class SingleContactSelectionActivity extends PassphraseRequiredSherlockFr
private void openNewConversation(Recipients recipients) {
if (recipients != null) {
Intent intent = new Intent(SingleContactSelectionActivity.this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.toIdString());
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
long existingThread = DatabaseFactory.getThreadDatabase(SingleContactSelectionActivity.this).getThreadIdIfExistsFor(recipients);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, existingThread);

View File

@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.database;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
@ -24,10 +25,14 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import static org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent.AttachmentPointer;
public class GroupDatabase extends Database {
public static final String DATABASE_UPDATE_ACTION = "org.thoughtcrime.securesms.database.GroupDatabase.UPDATE";
private static final String TAG = GroupDatabase.class.getSimpleName();
private static final String TABLE_NAME = "groups";
@ -77,11 +82,15 @@ public class GroupDatabase extends Database {
return record;
}
public Recipients getGroupMembers(byte[] groupId) {
List<String> members = getCurrentMembers(groupId);
List<Recipient> recipients = new LinkedList<Recipient>();
public Recipients getGroupMembers(byte[] groupId, boolean includeSelf) {
String localNumber = TextSecurePreferences.getLocalNumber(context);
List<String> members = getCurrentMembers(groupId);
List<Recipient> recipients = new LinkedList<Recipient>();
for (String member : members) {
if (!includeSelf && member.equals(localNumber))
continue;
try {
recipients.addAll(RecipientFactory.getRecipientsFromString(context, member, false)
.getRecipientsList());
@ -93,27 +102,13 @@ public class GroupDatabase extends Database {
return new Recipients(recipients);
}
public void create(byte[] groupId, String owner, String title,
List<String> members, AttachmentPointer avatar,
String relay)
public void create(byte[] groupId, String title, List<String> members,
AttachmentPointer avatar, String relay)
{
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(TITLE, title);
contentValues.put(MEMBERS, Util.join(filteredMembers, ","));
contentValues.put(MEMBERS, Util.join(members, ","));
if (avatar != null) {
contentValues.put(AVATAR_ID, avatar.getId());
@ -142,7 +137,8 @@ public class GroupDatabase extends Database {
GROUP_ID + " = ?",
new String[] {GroupUtil.getEncodedId(groupId)});
if (title != null) updateGroupRecipientTitle(groupId, title);
RecipientFactory.clearCache();
notifyDatabaseListeners();
}
public void updateTitle(byte[] groupId, String title) {
@ -151,43 +147,32 @@ public class GroupDatabase extends Database {
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?",
new String[] {GroupUtil.getEncodedId(groupId)});
if (title != null) updateGroupRecipientTitle(groupId, title);
RecipientFactory.clearCache();
notifyDatabaseListeners();
}
public void updateAvatar(byte[] groupId, Bitmap avatar) {
updateAvatarInDatabase(groupId, BitmapUtil.toByteArray(avatar));
updateGroupRecipientAvatar(groupId, avatar);
updateAvatar(groupId, BitmapUtil.toByteArray(avatar));
}
public void updateAvatar(byte[] groupId, byte[] avatar) {
updateAvatarInDatabase(groupId, avatar);
updateGroupRecipientAvatar(groupId, BitmapFactory.decodeByteArray(avatar, 0, avatar.length));
}
private void updateAvatarInDatabase(byte[] groupId, byte[] avatar) {
ContentValues contentValues = new ContentValues();
contentValues.put(AVATAR, avatar);
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?",
new String[] {GroupUtil.getEncodedId(groupId)});
RecipientFactory.clearCache();
notifyDatabaseListeners();
}
public void add(byte[] id, String source, List<String> members) {
List<String> currentMembers = getCurrentMembers(id);
public void updateMembers(byte[] id, List<String> members) {
ContentValues contents = new ContentValues();
contents.put(MEMBERS, Util.join(members, ","));
contents.put(ACTIVE, 1);
for (String currentMember : currentMembers) {
if (currentMember.equals(source)) {
List<String> concatenatedMembers = new LinkedList<String>(currentMembers);
concatenatedMembers.addAll(members);
ContentValues contents = new ContentValues();
contents.put(MEMBERS, Util.join(concatenatedMembers, ","));
contents.put(ACTIVE, 1);
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[] {GroupUtil.getEncodedId(id)});
}
}
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[] {GroupUtil.getEncodedId(id)});
}
public void remove(byte[] id, String source) {
@ -198,7 +183,7 @@ public class GroupDatabase extends Database {
contents.put(MEMBERS, Util.join(currentMembers, ","));
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[]{GroupUtil.getEncodedId(id)});
new String[] {GroupUtil.getEncodedId(id)});
}
private List<String> getCurrentMembers(byte[] id) {
@ -244,6 +229,10 @@ public class GroupDatabase extends Database {
}
}
private void notifyDatabaseListeners() {
Intent intent = new Intent(DATABASE_UPDATE_ACTION);
context.sendBroadcast(intent);
}
public static class Reader {
@ -342,28 +331,4 @@ public class GroupDatabase extends Database {
return active;
}
}
private Recipient getGroupRecipient(byte[] groupId) {
try {
return RecipientFactory.getRecipientsFromString(context, GroupUtil.getEncodedId(groupId), true)
.getPrimaryRecipient();
} catch (RecipientFormattingException e) {
Log.w(TAG, e);
return null;
}
}
private void updateGroupRecipientTitle(byte[] groupId, String title) {
Recipient groupRecipient = getGroupRecipient(groupId);
Log.i(TAG, "updating group recipient title for recipient " + System.identityHashCode(groupRecipient));
if (groupRecipient != null) groupRecipient.setName(title);
else Log.w(TAG, "Couldn't update group title because recipient couldn't be found.");
}
private void updateGroupRecipientAvatar(byte[] groupId, Bitmap photo) {
Recipient groupRecipient = getGroupRecipient(groupId);
if (groupRecipient != null) groupRecipient.setContactPhoto(photo);
else Log.w(TAG, "Couldn't update group title because recipient couldn't be found.");
}
}

View File

@ -84,7 +84,9 @@ public abstract class MessageRecord extends DisplayRecord {
@Override
public SpannableString getDisplayBody() {
if (isGroupUpdate()) {
if (isGroupUpdate() && isOutgoing()) {
return emphasisAdded("Updated the group.");
} else if (isGroupUpdate()) {
return emphasisAdded(GroupUtil.getDescription(getBody().getBody()));
} else if (isGroupQuit() && isOutgoing()) {
return emphasisAdded("You have left the group.");

View File

@ -23,6 +23,7 @@ import android.util.Patterns;
import org.thoughtcrime.securesms.recipients.Recipient.RecipientModifiedListener;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.NumberUtil;
import org.whispersystems.textsecure.util.Util;
import java.util.ArrayList;
import java.util.Iterator;
@ -137,6 +138,16 @@ public class Recipients implements Parcelable {
return this.recipients;
}
public String toIdString() {
List<String> ids = new LinkedList<String>();
for (Recipient recipient : recipients) {
ids.add(String.valueOf(recipient.getRecipientId()));
}
return Util.join(ids, " ");
}
public String[] toNumberStringArray(boolean scrub) {
String[] recipientsArray = new String[recipients.size()];
Iterator<Recipient> iterator = recipients.iterator();

View File

@ -71,7 +71,7 @@ public class GroupReceiver {
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
byte[] id = group.getId().toByteArray();
database.create(id, message.getSource(), group.getName(), group.getMembersList(),
database.create(id, group.getName(), group.getMembersList(),
group.getAvatar(), message.getRelay());
storeMessage(masterSecret, message, group);
@ -98,7 +98,7 @@ public class GroupReceiver {
if (addedMembers.size() > 0) {
Set<String> unionMembers = new HashSet<String>(recordMembers);
unionMembers.addAll(messageMembers);
database.add(id, message.getSource(), new LinkedList<String>(unionMembers));
database.updateMembers(id, new LinkedList<String>(unionMembers));
group = group.toBuilder().clearMembers().addAllMembers(addedMembers).build();
} else {

View File

@ -115,7 +115,7 @@ public class PushTransport extends BaseTransport {
if (GroupUtil.isEncodedGroup(destination)) {
recipients = DatabaseFactory.getGroupDatabase(context)
.getGroupMembers(GroupUtil.getDecodedId(destination));
.getGroupMembers(GroupUtil.getDecodedId(destination), false);
} else {
recipients = RecipientFactory.getRecipientsFromString(context, destination, false);
}

View File

@ -50,7 +50,7 @@ public class GroupUtil {
}
if (title != null && !title.trim().isEmpty()) {
description += " Updated title to '" + title + "'.";
description += " Title is now '" + title + "'.";
}
return description;