mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-26 11:21:55 +00:00
First cut at group messaging refactor.
This commit is contained in:
@@ -57,6 +57,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.DraftDatabase;
|
||||
import org.thoughtcrime.securesms.database.DraftDatabase.Draft;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
|
||||
import org.thoughtcrime.securesms.mms.MediaTooLargeException;
|
||||
@@ -93,14 +94,15 @@ import ws.com.google.android.mms.MmsException;
|
||||
*/
|
||||
public class ConversationActivity extends PassphraseRequiredSherlockFragmentActivity
|
||||
implements ConversationFragment.ConversationFragmentListener
|
||||
{
|
||||
{
|
||||
|
||||
public static final String RECIPIENTS_EXTRA = "recipients";
|
||||
public static final String THREAD_ID_EXTRA = "thread_id";
|
||||
public static final String MASTER_SECRET_EXTRA = "master_secret";
|
||||
public static final String DRAFT_TEXT_EXTRA = "draft_text";
|
||||
public static final String DRAFT_IMAGE_EXTRA = "draft_image";
|
||||
public static final String DRAFT_AUDIO_EXTRA = "draft_audio";
|
||||
public static final String RECIPIENTS_EXTRA = "recipients";
|
||||
public static final String THREAD_ID_EXTRA = "thread_id";
|
||||
public static final String MASTER_SECRET_EXTRA = "master_secret";
|
||||
public static final String DRAFT_TEXT_EXTRA = "draft_text";
|
||||
public static final String DRAFT_IMAGE_EXTRA = "draft_image";
|
||||
public static final String DRAFT_AUDIO_EXTRA = "draft_audio";
|
||||
public static final String DISTRIBUTION_TYPE_EXTRA = "distribution_type";
|
||||
|
||||
private static final int PICK_CONTACT = 1;
|
||||
private static final int PICK_IMAGE = 2;
|
||||
@@ -120,6 +122,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
|
||||
private Recipients recipients;
|
||||
private long threadId;
|
||||
private int distributionType;
|
||||
private boolean isEncryptedConversation;
|
||||
private boolean isMmsEnabled = true;
|
||||
|
||||
@@ -182,7 +185,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
|
||||
switch (reqCode) {
|
||||
case PICK_CONTACT:
|
||||
Recipients recipients = (Recipients)data.getParcelableExtra("recipients");
|
||||
Recipients recipients = data.getParcelableExtra("recipients");
|
||||
|
||||
if (recipients != null)
|
||||
recipientsPanel.addRecipients(recipients);
|
||||
@@ -220,6 +223,13 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
inflater.inflate(R.menu.conversation_callable, menu);
|
||||
} else if (isGroupConversation()) {
|
||||
inflater.inflate(R.menu.conversation_group_options, menu);
|
||||
|
||||
if (distributionType == ThreadDatabase.DistributionTypes.BROADCAST)
|
||||
{
|
||||
menu.findItem(R.id.menu_distribution_broadcast).setChecked(true);
|
||||
} else {
|
||||
menu.findItem(R.id.menu_distribution_conversation).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
inflater.inflate(R.menu.conversation, menu);
|
||||
@@ -231,15 +241,17 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_call: handleDial(getRecipients().getPrimaryRecipient()); return true;
|
||||
case R.id.menu_delete_thread: handleDeleteThread(); return true;
|
||||
case R.id.menu_add_attachment: handleAddAttachment(); return true;
|
||||
case R.id.menu_start_secure_session: handleStartSecureSession(); return true;
|
||||
case R.id.menu_abort_session: handleAbortSecureSession(); return true;
|
||||
case R.id.menu_verify_recipient: handleVerifyRecipient(); return true;
|
||||
case R.id.menu_verify_session: handleVerifySession(); return true;
|
||||
case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
||||
case android.R.id.home: handleReturnToConversationList(); return true;
|
||||
case R.id.menu_call: handleDial(getRecipients().getPrimaryRecipient()); return true;
|
||||
case R.id.menu_delete_thread: handleDeleteThread(); return true;
|
||||
case R.id.menu_add_attachment: handleAddAttachment(); return true;
|
||||
case R.id.menu_start_secure_session: handleStartSecureSession(); return true;
|
||||
case R.id.menu_abort_session: handleAbortSecureSession(); return true;
|
||||
case R.id.menu_verify_recipient: handleVerifyRecipient(); return true;
|
||||
case R.id.menu_verify_session: handleVerifySession(); return true;
|
||||
case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
||||
case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
|
||||
case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
|
||||
case android.R.id.home: handleReturnToConversationList(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -327,6 +339,38 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void handleDistributionBroadcastEnabled(MenuItem item) {
|
||||
distributionType = ThreadDatabase.DistributionTypes.BROADCAST;
|
||||
item.setChecked(true);
|
||||
|
||||
if (threadId != -1) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
DatabaseFactory.getThreadDatabase(ConversationActivity.this)
|
||||
.setDistributionType(threadId, ThreadDatabase.DistributionTypes.BROADCAST);
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDistributionConversationEnabled(MenuItem item) {
|
||||
distributionType = ThreadDatabase.DistributionTypes.CONVERSATION;
|
||||
item.setChecked(true);
|
||||
|
||||
if (threadId != -1) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
DatabaseFactory.getThreadDatabase(ConversationActivity.this)
|
||||
.setDistributionType(threadId, ThreadDatabase.DistributionTypes.CONVERSATION);
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDial(Recipient recipient) {
|
||||
if (recipient == null) return;
|
||||
|
||||
@@ -494,12 +538,14 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
|
||||
private void initializeResources() {
|
||||
recipientsPanel = (RecipientsPanel)findViewById(R.id.recipients);
|
||||
recipients = getIntent().getParcelableExtra("recipients");
|
||||
threadId = getIntent().getLongExtra("thread_id", -1);
|
||||
recipients = getIntent().getParcelableExtra(RECIPIENTS_EXTRA);
|
||||
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
||||
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA,
|
||||
ThreadDatabase.DistributionTypes.DEFAULT);
|
||||
addContactButton = (ImageButton)findViewById(R.id.contacts_button);
|
||||
sendButton = (ImageButton)findViewById(R.id.send_button);
|
||||
composeText = (EditText)findViewById(R.id.embedded_text_editor);
|
||||
masterSecret = (MasterSecret)getIntent().getParcelableExtra("master_secret");
|
||||
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
|
||||
charactersLeft = (TextView)findViewById(R.id.space_left);
|
||||
|
||||
attachmentAdapter = new AttachmentTypeSelectorAdapter(this);
|
||||
@@ -749,10 +795,11 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
if (attachmentManager.isAttachmentPresent()) {
|
||||
allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients,
|
||||
threadId, attachmentManager.getSlideDeck(), body,
|
||||
forcePlaintext);
|
||||
} else if (recipients.isEmailRecipient()) {
|
||||
distributionType, forcePlaintext);
|
||||
} else if (recipients.isEmailRecipient() || !recipients.isSingleRecipient()) {
|
||||
allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients,
|
||||
threadId, new SlideDeck(), body, forcePlaintext);
|
||||
threadId, new SlideDeck(), body, distributionType,
|
||||
forcePlaintext);
|
||||
} else {
|
||||
OutgoingTextMessage message;
|
||||
|
||||
@@ -790,7 +837,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
Intent intent = new Intent(ConversationActivity.this, ContactSelectionActivity.class);
|
||||
startActivityForResult(intent, PICK_CONTACT);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class AttachmentTypeListener implements DialogInterface.OnClickListener {
|
||||
@Override
|
||||
@@ -823,7 +870,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class OnTextChangedListener implements TextWatcher {
|
||||
@Override
|
||||
|
||||
@@ -123,7 +123,7 @@ public class ConversationFragment extends SherlockListFragment
|
||||
}
|
||||
|
||||
private void handleDisplayDetails(MessageRecord message) {
|
||||
String sender = message.getRecipients().getPrimaryRecipient().getNumber();
|
||||
String sender = message.getIndividualRecipient().getNumber();
|
||||
String transport = message.isMms() ? "mms" : "sms";
|
||||
long dateReceived = message.getDateReceived();
|
||||
long dateSent = message.getDateSent();
|
||||
@@ -175,8 +175,7 @@ public class ConversationFragment extends SherlockListFragment
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
|
||||
return new ConversationLoader(getActivity(), threadId,
|
||||
(recipients != null && !recipients.isSingleRecipient()));
|
||||
return new ConversationLoader(getActivity(), threadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -193,19 +193,19 @@ public class ConversationItem extends LinearLayout {
|
||||
}
|
||||
|
||||
private void setGroupMessageStatus(MessageRecord messageRecord) {
|
||||
GroupData groupData = messageRecord.getGroupData();
|
||||
|
||||
if (groupData != null) {
|
||||
String status = String.format("Sent (%d/%d)", groupData.groupSentCount, groupData.groupSize);
|
||||
|
||||
if (groupData.groupSendFailedCount != 0)
|
||||
status = status + String.format(", Failed (%d/%d)", groupData.groupSendFailedCount, groupData.groupSize);
|
||||
|
||||
this.groupStatusText.setText(status);
|
||||
this.groupStatusText.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
// GroupData groupData = messageRecord.getGroupData();
|
||||
//
|
||||
// if (groupData != null) {
|
||||
// String status = String.format("Sent (%d/%d)", groupData.groupSentCount, groupData.groupSize);
|
||||
//
|
||||
// if (groupData.groupSendFailedCount != 0)
|
||||
// status = status + String.format(", Failed (%d/%d)", groupData.groupSendFailedCount, groupData.groupSize);
|
||||
//
|
||||
// this.groupStatusText.setText(status);
|
||||
// this.groupStatusText.setVisibility(View.VISIBLE);
|
||||
// } else {
|
||||
this.groupStatusText.setVisibility(View.GONE);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private void setNotificationMmsAttributes(NotificationMmsMessageRecord messageRecord) {
|
||||
@@ -298,7 +298,7 @@ public class ConversationItem extends LinearLayout {
|
||||
|
||||
private void handleKeyExchangeClicked() {
|
||||
Intent intent = new Intent(context, ReceiveKeyActivity.class);
|
||||
intent.putExtra("recipient", messageRecord.getRecipients().getPrimaryRecipient());
|
||||
intent.putExtra("recipient", messageRecord.getIndividualRecipient());
|
||||
intent.putExtra("body", messageRecord.getBody());
|
||||
intent.putExtra("thread_id", messageRecord.getThreadId());
|
||||
intent.putExtra("master_secret", masterSecret);
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.view.WindowManager;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationExportManager.ApplicationExportListener;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
@@ -67,27 +68,30 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
|
||||
int defaultType = ThreadDatabase.DistributionTypes.DEFAULT;
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_new_message: createConversation(-1, null); return true;
|
||||
case R.id.menu_settings: handleDisplaySettings(); return true;
|
||||
case R.id.menu_export: handleExportDatabase(); return true;
|
||||
case R.id.menu_import: handleImportDatabase(); return true;
|
||||
case R.id.menu_clear_passphrase: handleClearPassphrase(); return true;
|
||||
case R.id.menu_new_message: createConversation(-1, null, defaultType); return true;
|
||||
case R.id.menu_settings: handleDisplaySettings(); return true;
|
||||
case R.id.menu_export: handleExportDatabase(); return true;
|
||||
case R.id.menu_import: handleImportDatabase(); return true;
|
||||
case R.id.menu_clear_passphrase: handleClearPassphrase(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateConversation(long threadId, Recipients recipients) {
|
||||
createConversation(threadId, recipients);
|
||||
public void onCreateConversation(long threadId, Recipients recipients, int distributionType) {
|
||||
createConversation(threadId, recipients, distributionType);
|
||||
}
|
||||
|
||||
private void createConversation(long threadId, Recipients recipients) {
|
||||
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.THREAD_ID_EXTRA, threadId);
|
||||
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
|
||||
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, distributionType);
|
||||
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,8 @@ public class ConversationListFragment extends SherlockListFragment
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if (v instanceof ConversationListItem) {
|
||||
ConversationListItem headerView = (ConversationListItem) v;
|
||||
handleCreateConversation(headerView.getThreadId(), headerView.getRecipients());
|
||||
handleCreateConversation(headerView.getThreadId(), headerView.getRecipients(),
|
||||
headerView.getDistributionType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,8 +198,8 @@ public class ConversationListFragment extends SherlockListFragment
|
||||
((ConversationListAdapter)this.getListAdapter()).selectAllThreads();
|
||||
}
|
||||
|
||||
private void handleCreateConversation(long threadId, Recipients recipients) {
|
||||
listener.onCreateConversation(threadId, recipients);
|
||||
private void handleCreateConversation(long threadId, Recipients recipients, int distributionType) {
|
||||
listener.onCreateConversation(threadId, recipients, distributionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,7 +218,7 @@ public class ConversationListFragment extends SherlockListFragment
|
||||
}
|
||||
|
||||
public interface ConversationSelectedListener {
|
||||
public void onCreateConversation(long threadId, Recipients recipients);
|
||||
public void onCreateConversation(long threadId, Recipients recipients, int distributionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,6 +71,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
private QuickContactBadge contactPhotoBadge;
|
||||
|
||||
private final Handler handler = new Handler();
|
||||
private int distributionType;
|
||||
|
||||
public ConversationListItem(Context context) {
|
||||
super(context);
|
||||
@@ -97,11 +98,12 @@ public class ConversationListItem extends RelativeLayout
|
||||
}
|
||||
|
||||
public void set(ThreadRecord thread, Set<Long> selectedThreads, boolean batchMode) {
|
||||
this.selectedThreads = selectedThreads;
|
||||
this.recipients = thread.getRecipients();
|
||||
this.threadId = thread.getThreadId();
|
||||
this.count = thread.getCount();
|
||||
this.read = thread.isRead();
|
||||
this.selectedThreads = selectedThreads;
|
||||
this.recipients = thread.getRecipients();
|
||||
this.threadId = thread.getThreadId();
|
||||
this.count = thread.getCount();
|
||||
this.read = thread.isRead();
|
||||
this.distributionType = thread.getDistributionType();
|
||||
|
||||
this.recipients.addListener(this);
|
||||
this.fromView.setText(formatFrom(recipients, count, read));
|
||||
@@ -201,6 +203,10 @@ public class ConversationListItem extends RelativeLayout
|
||||
return threadId;
|
||||
}
|
||||
|
||||
public int getDistributionType() {
|
||||
return distributionType;
|
||||
}
|
||||
|
||||
private class CheckedChangedListener implements CompoundButton.OnCheckedChangeListener {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
|
||||
@@ -43,6 +43,7 @@ import ws.com.google.android.mms.ContentType;
|
||||
import ws.com.google.android.mms.MmsException;
|
||||
import ws.com.google.android.mms.pdu.MultimediaMessagePdu;
|
||||
import ws.com.google.android.mms.pdu.PduParser;
|
||||
import ws.com.google.android.mms.pdu.RetrieveConf;
|
||||
|
||||
/**
|
||||
* A work queue for processing a number of encryption operations.
|
||||
@@ -186,7 +187,7 @@ public class DecryptingQueue {
|
||||
plaintextPduBytes = cipher.decryptMessage(ciphertextPduBytes);
|
||||
}
|
||||
|
||||
MultimediaMessagePdu plaintextPdu = (MultimediaMessagePdu)new PduParser(plaintextPduBytes).parse();
|
||||
RetrieveConf plaintextPdu = (RetrieveConf)new PduParser(plaintextPduBytes).parse();
|
||||
Log.w("DecryptingQueue", "Successfully decrypted MMS!");
|
||||
database.insertSecureDecryptedMessageInbox(masterSecret, plaintextPdu, threadId);
|
||||
database.delete(messageId);
|
||||
|
||||
@@ -158,9 +158,36 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
}
|
||||
}
|
||||
|
||||
private long getThreadIdForHeaders(PduHeaders headers) throws RecipientFormattingException {
|
||||
private long getThreadIdFor(RetrieveConf retrieved) throws RecipientFormattingException {
|
||||
try {
|
||||
EncodedStringValue encodedString = headers.getEncodedStringValue(PduHeaders.FROM);
|
||||
Set<String> group = new HashSet<String>();
|
||||
|
||||
EncodedStringValue encodedFrom = retrieved.getFrom();
|
||||
group.add(new String(encodedFrom.getTextString(), CharacterSets.MIMENAME_ISO_8859_1));
|
||||
|
||||
EncodedStringValue[] encodedCcList = retrieved.getCc();
|
||||
if (encodedCcList != null) {
|
||||
for (EncodedStringValue encodedCc : encodedCcList) {
|
||||
group.add(new String(encodedCc.getTextString(), CharacterSets.MIMENAME_ISO_8859_1));
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String recipient : group) {
|
||||
sb.append(recipient);
|
||||
sb.append(",");
|
||||
}
|
||||
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(context, sb.toString(), false);
|
||||
return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private long getThreadIdFor(NotificationInd notification) throws RecipientFormattingException {
|
||||
try {
|
||||
EncodedStringValue encodedString = notification.getFrom();
|
||||
String fromString = new String(encodedString.getTextString(), CharacterSets.MIMENAME_ISO_8859_1);
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(context, fromString, false);
|
||||
return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||
@@ -313,13 +340,21 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
}
|
||||
}
|
||||
|
||||
private long insertMessageInbox(MasterSecret masterSecret, MultimediaMessagePdu retrieved,
|
||||
String contentLocation, long threadId, long mailbox)
|
||||
private long insertMessageInbox(MasterSecret masterSecret, RetrieveConf retrieved,
|
||||
String contentLocation, long threadId, long mailbox)
|
||||
throws MmsException
|
||||
{
|
||||
PduHeaders headers = retrieved.getPduHeaders();
|
||||
ContentValues contentValues = getContentValuesFromHeader(headers);
|
||||
|
||||
if (!Util.isEmpty(retrieved.getCc())) {
|
||||
try {
|
||||
threadId = getThreadIdFor(retrieved);
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("MmsDatabase", e);
|
||||
}
|
||||
}
|
||||
|
||||
contentValues.put(MESSAGE_BOX, mailbox);
|
||||
contentValues.put(THREAD_ID, threadId);
|
||||
contentValues.put(CONTENT_LOCATION, contentLocation);
|
||||
@@ -348,7 +383,8 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT | Types.ENCRYPTION_REMOTE_BIT);
|
||||
}
|
||||
|
||||
public long insertSecureDecryptedMessageInbox(MasterSecret masterSecret, MultimediaMessagePdu retrieved, long threadId)
|
||||
public long insertSecureDecryptedMessageInbox(MasterSecret masterSecret, RetrieveConf retrieved,
|
||||
long threadId)
|
||||
throws MmsException
|
||||
{
|
||||
return insertMessageInbox(masterSecret, retrieved, "", threadId,
|
||||
@@ -360,7 +396,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
PduHeaders headers = notification.getPduHeaders();
|
||||
ContentValues contentValues = getContentValuesFromHeader(headers);
|
||||
long threadId = getThreadIdForHeaders(headers);
|
||||
long threadId = getThreadIdFor(notification);
|
||||
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
|
||||
|
||||
Log.w("MmsDatabse", "Message received type: " + headers.getOctet(PduHeaders.MESSAGE_TYPE));
|
||||
@@ -688,29 +724,12 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
long box = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX));
|
||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID));
|
||||
Recipient recipient = getMessageRecipient(id);
|
||||
MessageRecord.GroupData groupData = null;
|
||||
|
||||
SlideDeck slideDeck;
|
||||
|
||||
try {
|
||||
MultimediaMessagePdu pdu = getMediaMessage(id);
|
||||
slideDeck = getSlideDeck(masterSecret, pdu);
|
||||
|
||||
if (cursor.getColumnIndex(MmsSmsDatabase.GROUP_SIZE) != -1) {
|
||||
int groupSize = pdu.getTo().length;
|
||||
int groupSent = MmsDatabase.Types.isFailedMessageType(box) ? 0 : groupSize;
|
||||
int groupSendFailed = groupSize - groupSent;
|
||||
|
||||
if (groupSize <= 1) {
|
||||
groupSize = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsDatabase.GROUP_SIZE));
|
||||
groupSent = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsDatabase.MMS_GROUP_SENT_COUNT));
|
||||
groupSendFailed = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsDatabase.MMS_GROUP_SEND_FAILED_COUNT));
|
||||
}
|
||||
|
||||
Log.w("ConversationAdapter", "MMS GroupSize: " + groupSize + " , GroupSent: " + groupSent + " , GroupSendFailed: " + groupSendFailed);
|
||||
|
||||
groupData = new MessageRecord.GroupData(groupSize, groupSent, groupSendFailed);
|
||||
}
|
||||
} catch (MmsException me) {
|
||||
Log.w("ConversationAdapter", me);
|
||||
slideDeck = null;
|
||||
@@ -718,7 +737,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
|
||||
return new MediaMmsMessageRecord(context, id, new Recipients(recipient), recipient,
|
||||
dateSent, dateReceived, threadId,
|
||||
slideDeck, box, groupData);
|
||||
slideDeck, box);
|
||||
}
|
||||
|
||||
protected SlideDeck getSlideDeck(MasterSecret masterSecret, MultimediaMessagePdu pdu) {
|
||||
|
||||
@@ -31,13 +31,7 @@ import java.util.Set;
|
||||
|
||||
public class MmsSmsDatabase extends Database {
|
||||
|
||||
public static final String TRANSPORT = "transport_type";
|
||||
public static final String GROUP_SIZE = "group_size";
|
||||
public static final String SMS_GROUP_SENT_COUNT = "sms_group_sent_count";
|
||||
public static final String SMS_GROUP_SEND_FAILED_COUNT = "sms_group_sent_failed_count";
|
||||
public static final String MMS_GROUP_SENT_COUNT = "mms_group_sent_count";
|
||||
public static final String MMS_GROUP_SEND_FAILED_COUNT = "mms_group_sent_failed_count";
|
||||
|
||||
public static final String TRANSPORT = "transport_type";
|
||||
public static final String MMS_TRANSPORT = "mms";
|
||||
public static final String SMS_TRANSPORT = "sms";
|
||||
|
||||
@@ -45,53 +39,53 @@ public class MmsSmsDatabase extends Database {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
public Cursor getCollatedGroupConversation(long threadId) {
|
||||
String smsCaseSecurity = "CASE " + SmsDatabase.TYPE + " & " + SmsDatabase.Types.SECURE_MESSAGE_BIT + " " +
|
||||
"WHEN " + SmsDatabase.Types.SECURE_MESSAGE_BIT + " THEN 1 " +
|
||||
"ELSE 0 END";
|
||||
|
||||
String mmsCaseSecurity = "CASE " + MmsDatabase.MESSAGE_BOX + " & " + SmsDatabase.Types.SECURE_MESSAGE_BIT + " " +
|
||||
"WHEN " + MmsDatabase.Types.SECURE_MESSAGE_BIT + " THEN 'secure' " +
|
||||
"ELSE 'insecure' END";
|
||||
|
||||
String mmsGroupSentCount = "SUM(CASE " + MmsDatabase.MESSAGE_BOX + " & " + MmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
"WHEN " + MmsDatabase.Types.BASE_SENT_TYPE + " THEN 1 " +
|
||||
"ELSE 0 END)";
|
||||
|
||||
|
||||
String smsGroupSentCount = "SUM(CASE " + SmsDatabase.TYPE + " & " + SmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
"WHEN " + SmsDatabase.Types.BASE_SENT_TYPE + " THEN 1 " +
|
||||
"ELSE 0 END)";
|
||||
|
||||
String mmsGroupSentFailedCount = "SUM(CASE " + MmsDatabase.MESSAGE_BOX + " & " + MmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
"WHEN " + MmsDatabase.Types.BASE_SENT_FAILED_TYPE + " THEN 1 " +
|
||||
"ELSE 0 END)";
|
||||
|
||||
String smsGroupSentFailedCount = "SUM(CASE " + SmsDatabase.TYPE + " & " + SmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
"WHEN " + SmsDatabase.Types.BASE_SENT_FAILED_TYPE + " THEN 1 " +
|
||||
"ELSE 0 END)";
|
||||
|
||||
String[] projection = {MmsSmsColumns.ID, SmsDatabase.BODY, SmsDatabase.TYPE,
|
||||
MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.ADDRESS, SmsDatabase.SUBJECT, SmsDatabase.STATUS,
|
||||
MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX, TRANSPORT,
|
||||
"COUNT(" + MmsSmsColumns.ID + ") AS " + GROUP_SIZE,
|
||||
mmsGroupSentCount + " AS " + MMS_GROUP_SENT_COUNT,
|
||||
mmsGroupSentFailedCount + " AS " + MMS_GROUP_SEND_FAILED_COUNT,
|
||||
smsGroupSentCount + " AS " + SMS_GROUP_SENT_COUNT,
|
||||
smsGroupSentFailedCount + " AS " + SMS_GROUP_SEND_FAILED_COUNT,
|
||||
smsCaseSecurity + " AS sms_collate", mmsCaseSecurity + " AS mms_collate"};
|
||||
|
||||
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
|
||||
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||
String groupBy = MmsSmsColumns.NORMALIZED_DATE_SENT + " / 1000, sms_collate, mms_collate";
|
||||
|
||||
Cursor cursor = queryTables(projection, selection, order, groupBy, null);
|
||||
setNotifyConverationListeners(cursor, threadId);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
// public Cursor getCollatedGroupConversation(long threadId) {
|
||||
// String smsCaseSecurity = "CASE " + SmsDatabase.TYPE + " & " + SmsDatabase.Types.SECURE_MESSAGE_BIT + " " +
|
||||
// "WHEN " + SmsDatabase.Types.SECURE_MESSAGE_BIT + " THEN 1 " +
|
||||
// "ELSE 0 END";
|
||||
//
|
||||
// String mmsCaseSecurity = "CASE " + MmsDatabase.MESSAGE_BOX + " & " + SmsDatabase.Types.SECURE_MESSAGE_BIT + " " +
|
||||
// "WHEN " + MmsDatabase.Types.SECURE_MESSAGE_BIT + " THEN 'secure' " +
|
||||
// "ELSE 'insecure' END";
|
||||
//
|
||||
// String mmsGroupSentCount = "SUM(CASE " + MmsDatabase.MESSAGE_BOX + " & " + MmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
// "WHEN " + MmsDatabase.Types.BASE_SENT_TYPE + " THEN 1 " +
|
||||
// "ELSE 0 END)";
|
||||
//
|
||||
//
|
||||
// String smsGroupSentCount = "SUM(CASE " + SmsDatabase.TYPE + " & " + SmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
// "WHEN " + SmsDatabase.Types.BASE_SENT_TYPE + " THEN 1 " +
|
||||
// "ELSE 0 END)";
|
||||
//
|
||||
// String mmsGroupSentFailedCount = "SUM(CASE " + MmsDatabase.MESSAGE_BOX + " & " + MmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
// "WHEN " + MmsDatabase.Types.BASE_SENT_FAILED_TYPE + " THEN 1 " +
|
||||
// "ELSE 0 END)";
|
||||
//
|
||||
// String smsGroupSentFailedCount = "SUM(CASE " + SmsDatabase.TYPE + " & " + SmsDatabase.Types.BASE_TYPE_MASK + " " +
|
||||
// "WHEN " + SmsDatabase.Types.BASE_SENT_FAILED_TYPE + " THEN 1 " +
|
||||
// "ELSE 0 END)";
|
||||
//
|
||||
// String[] projection = {MmsSmsColumns.ID, SmsDatabase.BODY, SmsDatabase.TYPE,
|
||||
// MmsSmsColumns.THREAD_ID,
|
||||
// SmsDatabase.ADDRESS, SmsDatabase.SUBJECT, SmsDatabase.STATUS,
|
||||
// MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
// MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX, TRANSPORT,
|
||||
// "COUNT(" + MmsSmsColumns.ID + ") AS " + GROUP_SIZE,
|
||||
// mmsGroupSentCount + " AS " + MMS_GROUP_SENT_COUNT,
|
||||
// mmsGroupSentFailedCount + " AS " + MMS_GROUP_SEND_FAILED_COUNT,
|
||||
// smsGroupSentCount + " AS " + SMS_GROUP_SENT_COUNT,
|
||||
// smsGroupSentFailedCount + " AS " + SMS_GROUP_SEND_FAILED_COUNT,
|
||||
// smsCaseSecurity + " AS sms_collate", mmsCaseSecurity + " AS mms_collate"};
|
||||
//
|
||||
// String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
|
||||
// String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||
// String groupBy = MmsSmsColumns.NORMALIZED_DATE_SENT + " / 1000, sms_collate, mms_collate";
|
||||
//
|
||||
// Cursor cursor = queryTables(projection, selection, order, groupBy, null);
|
||||
// setNotifyConverationListeners(cursor, threadId);
|
||||
//
|
||||
// return cursor;
|
||||
// }
|
||||
|
||||
public Cursor getConversation(long threadId) {
|
||||
String[] projection = {MmsSmsColumns.ID, SmsDatabase.BODY, SmsDatabase.TYPE,
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
@@ -405,22 +404,11 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
int status = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.STATUS));
|
||||
Recipients recipients = getRecipientsFor(address);
|
||||
String body = getBody(cursor);
|
||||
MessageRecord.GroupData groupData = null;
|
||||
|
||||
if (cursor.getColumnIndex(MmsSmsDatabase.GROUP_SIZE) != -1) {
|
||||
int groupSize = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsDatabase.GROUP_SIZE));
|
||||
int groupSent = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsDatabase.SMS_GROUP_SENT_COUNT));
|
||||
int groupSendFailed = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsDatabase.SMS_GROUP_SEND_FAILED_COUNT));
|
||||
|
||||
Log.w("ConversationAdapter", "GroupSize: " + groupSize + " , GroupSent: " + groupSent + " , GroupSendFailed: " + groupSendFailed);
|
||||
|
||||
groupData = new MessageRecord.GroupData(groupSize, groupSent, groupSendFailed);
|
||||
}
|
||||
|
||||
return new SmsMessageRecord(context, messageId, body, recipients,
|
||||
recipients.getPrimaryRecipient(),
|
||||
dateSent, dateReceived, type,
|
||||
threadId, status, groupData);
|
||||
threadId, status);
|
||||
}
|
||||
|
||||
private Recipients getRecipientsFor(String address) {
|
||||
|
||||
@@ -38,18 +38,18 @@ import java.util.Set;
|
||||
|
||||
public class ThreadDatabase extends Database {
|
||||
|
||||
static final String TABLE_NAME = "thread";
|
||||
public static final String ID = "_id";
|
||||
public static final String DATE = "date";
|
||||
public static final String MESSAGE_COUNT = "message_count";
|
||||
public static final String RECIPIENT_IDS = "recipient_ids";
|
||||
public static final String SNIPPET = "snippet";
|
||||
private static final String SNIPPET_CHARSET = "snippet_cs";
|
||||
public static final String READ = "read";
|
||||
private static final String TYPE = "type";
|
||||
private static final String ERROR = "error";
|
||||
private static final String HAS_ATTACHMENT = "has_attachment";
|
||||
public static final String SNIPPET_TYPE = "snippet_type";
|
||||
static final String TABLE_NAME = "thread";
|
||||
public static final String ID = "_id";
|
||||
public static final String DATE = "date";
|
||||
public static final String MESSAGE_COUNT = "message_count";
|
||||
public static final String RECIPIENT_IDS = "recipient_ids";
|
||||
public static final String SNIPPET = "snippet";
|
||||
private static final String SNIPPET_CHARSET = "snippet_cs";
|
||||
public static final String READ = "read";
|
||||
private static final String TYPE = "type";
|
||||
private static final String ERROR = "error";
|
||||
private static final String HAS_ATTACHMENT = "has_attachment";
|
||||
public static final String SNIPPET_TYPE = "snippet_type";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||
DATE + " INTEGER DEFAULT 0, " + MESSAGE_COUNT + " INTEGER DEFAULT 0, " +
|
||||
@@ -98,7 +98,7 @@ public class ThreadDatabase extends Database {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private long createThreadForRecipients(String recipients, int recipientCount) {
|
||||
private long createThreadForRecipients(String recipients, int recipientCount, int distributionType) {
|
||||
ContentValues contentValues = new ContentValues(4);
|
||||
long date = System.currentTimeMillis();
|
||||
|
||||
@@ -106,7 +106,7 @@ public class ThreadDatabase extends Database {
|
||||
contentValues.put(RECIPIENT_IDS, recipients);
|
||||
|
||||
if (recipientCount > 1)
|
||||
contentValues.put(TYPE, 1);
|
||||
contentValues.put(TYPE, distributionType);
|
||||
|
||||
contentValues.put(MESSAGE_COUNT, 0);
|
||||
|
||||
@@ -216,7 +216,16 @@ public class ThreadDatabase extends Database {
|
||||
|
||||
public void setUnread(long threadId) {
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
contentValues.put("read", 0);
|
||||
contentValues.put(READ, 0);
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
||||
notifyConversationListListeners();
|
||||
}
|
||||
|
||||
public void setDistributionType(long threadId, int distributionType) {
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
contentValues.put(TYPE, distributionType);
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
||||
@@ -301,6 +310,10 @@ public class ThreadDatabase extends Database {
|
||||
}
|
||||
|
||||
public long getThreadIdFor(Recipients recipients) {
|
||||
return getThreadIdFor(recipients, 0);
|
||||
}
|
||||
|
||||
public long getThreadIdFor(Recipients recipients, int distributionType) {
|
||||
long[] recipientIds = getRecipientIds(recipients);
|
||||
String recipientsList = getRecipientsAsString(recipientIds);
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
@@ -314,7 +327,7 @@ public class ThreadDatabase extends Database {
|
||||
if (cursor != null && cursor.moveToFirst())
|
||||
return cursor.getLong(cursor.getColumnIndexOrThrow(ID));
|
||||
else
|
||||
return createThreadForRecipients(recipientsList, recipientIds.length);
|
||||
return createThreadForRecipients(recipientsList, recipientIds.length, distributionType);
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
@@ -378,6 +391,12 @@ public class ThreadDatabase extends Database {
|
||||
return new Reader(cursor, masterSecret);
|
||||
}
|
||||
|
||||
public static class DistributionTypes {
|
||||
public static final int DEFAULT = 2;
|
||||
public static final int BROADCAST = 1;
|
||||
public static final int CONVERSATION = 2;
|
||||
}
|
||||
|
||||
public class Reader {
|
||||
|
||||
private final Cursor cursor;
|
||||
@@ -405,8 +424,10 @@ public class ThreadDatabase extends Database {
|
||||
long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT));
|
||||
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));
|
||||
|
||||
return new ThreadRecord(context, body, recipients, date, count, read == 1, threadId, type);
|
||||
return new ThreadRecord(context, body, recipients, date, count,
|
||||
read == 1, threadId, type, distributionType);
|
||||
}
|
||||
|
||||
private String getPlaintextBody(Cursor cursor) {
|
||||
|
||||
@@ -10,21 +10,15 @@ public class ConversationLoader extends CursorLoader {
|
||||
|
||||
private final Context context;
|
||||
private final long threadId;
|
||||
private final boolean isGroupConversation;
|
||||
|
||||
public ConversationLoader(Context context, long threadId, boolean isGroupConversation) {
|
||||
public ConversationLoader(Context context, long threadId) {
|
||||
super(context);
|
||||
this.context = context.getApplicationContext();
|
||||
this.threadId = threadId;
|
||||
this.isGroupConversation = isGroupConversation;
|
||||
this.context = context.getApplicationContext();
|
||||
this.threadId = threadId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor loadInBackground() {
|
||||
if (!isGroupConversation) {
|
||||
return DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId);
|
||||
} else {
|
||||
return DatabaseFactory.getMmsSmsDatabase(context).getCollatedGroupConversation(threadId);
|
||||
}
|
||||
return DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,13 +41,11 @@ public class MediaMmsMessageRecord extends MessageRecord {
|
||||
|
||||
public MediaMmsMessageRecord(Context context, long id, Recipients recipients,
|
||||
Recipient individualRecipient, long dateSent, long dateReceived,
|
||||
long threadId, SlideDeck slideDeck, long mailbox,
|
||||
GroupData groupData)
|
||||
long threadId, SlideDeck slideDeck, long mailbox)
|
||||
{
|
||||
super(context, id, getBodyFromSlidesIfAvailable(slideDeck), recipients,
|
||||
individualRecipient, dateSent, dateReceived,
|
||||
threadId, DELIVERY_STATUS_NONE, mailbox,
|
||||
groupData);
|
||||
threadId, DELIVERY_STATUS_NONE, mailbox);
|
||||
|
||||
this.context = context.getApplicationContext();
|
||||
this.slideDeck = slideDeck;
|
||||
|
||||
@@ -45,19 +45,17 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
private final Recipient individualRecipient;
|
||||
private final long id;
|
||||
private final int deliveryStatus;
|
||||
private final GroupData groupData;
|
||||
|
||||
public MessageRecord(Context context, long id, String body, Recipients recipients,
|
||||
Recipient individualRecipient,
|
||||
long dateSent, long dateReceived,
|
||||
long threadId, int deliveryStatus,
|
||||
long type, GroupData groupData)
|
||||
long type)
|
||||
{
|
||||
super(context, body, recipients, dateSent, dateReceived, threadId, type);
|
||||
this.id = id;
|
||||
this.individualRecipient = individualRecipient;
|
||||
this.deliveryStatus = deliveryStatus;
|
||||
this.groupData = groupData;
|
||||
}
|
||||
|
||||
public abstract boolean isMms();
|
||||
@@ -73,7 +71,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
}
|
||||
|
||||
public boolean isPending() {
|
||||
return MmsSmsColumns.Types.isPendingMessageType(type) || isGroupDeliveryPending();
|
||||
return MmsSmsColumns.Types.isPendingMessageType(type);
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
@@ -109,18 +107,6 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return individualRecipient;
|
||||
}
|
||||
|
||||
public GroupData getGroupData() {
|
||||
return this.groupData;
|
||||
}
|
||||
|
||||
protected boolean isGroupDeliveryPending() {
|
||||
if (this.groupData != null) {
|
||||
return groupData.groupSentCount + groupData.groupSendFailedCount < groupData.groupSize;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected SpannableString emphasisAdded(String sequence) {
|
||||
SpannableString spannable = new SpannableString(sequence);
|
||||
spannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(android.R.color.darker_gray)), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class NotificationMmsMessageRecord extends MessageRecord {
|
||||
int status, byte[] transactionId, long mailbox)
|
||||
{
|
||||
super(context, id, "", recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, DELIVERY_STATUS_NONE, mailbox, null);
|
||||
threadId, DELIVERY_STATUS_NONE, mailbox);
|
||||
|
||||
this.contentLocation = contentLocation;
|
||||
this.messageSize = messageSize;
|
||||
|
||||
@@ -40,10 +40,10 @@ public class SmsMessageRecord extends MessageRecord {
|
||||
Recipient individualRecipient,
|
||||
long dateSent, long dateReceived,
|
||||
long type, long threadId,
|
||||
int status, GroupData groupData)
|
||||
int status)
|
||||
{
|
||||
super(context, id, body, recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, getGenericDeliveryStatus(status), type, groupData);
|
||||
threadId, getGenericDeliveryStatus(status), type);
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
|
||||
@@ -37,14 +37,17 @@ public class ThreadRecord extends DisplayRecord {
|
||||
private final Context context;
|
||||
private final long count;
|
||||
private final boolean read;
|
||||
private final int distributionType;
|
||||
|
||||
public ThreadRecord(Context context, String body, Recipients recipients, long date,
|
||||
long count, boolean read, long threadId, long type)
|
||||
long count, boolean read, long threadId, long snippetType,
|
||||
int distributionType)
|
||||
{
|
||||
super(context, body, recipients, date, date, threadId, type);
|
||||
this.context = context.getApplicationContext();
|
||||
this.count = count;
|
||||
this.read = read;
|
||||
super(context, body, recipients, date, date, threadId, snippetType);
|
||||
this.context = context.getApplicationContext();
|
||||
this.count = count;
|
||||
this.read = read;
|
||||
this.distributionType = distributionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,4 +89,7 @@ public class ThreadRecord extends DisplayRecord {
|
||||
return getDateReceived();
|
||||
}
|
||||
|
||||
public int getDistributionType() {
|
||||
return distributionType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -137,13 +138,13 @@ public class MessageNotifier {
|
||||
NotificationState notificationState,
|
||||
boolean signal)
|
||||
{
|
||||
List<NotificationItem> notifications = notificationState.getNotifications();
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
Recipients recipients = notifications.get(0).getRecipients();
|
||||
List<NotificationItem>notifications = notificationState.getNotifications();
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
Recipient recipient = notifications.get(0).getIndividualRecipient();
|
||||
|
||||
builder.setSmallIcon(R.drawable.icon_notification);
|
||||
builder.setLargeIcon(recipients.getPrimaryRecipient().getContactPhoto());
|
||||
builder.setContentTitle(recipients.getPrimaryRecipient().toShortString());
|
||||
builder.setLargeIcon(recipient.getContactPhoto());
|
||||
builder.setContentTitle(recipient.toShortString());
|
||||
builder.setContentText(notifications.get(0).getText());
|
||||
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
||||
|
||||
@@ -179,7 +180,7 @@ public class MessageNotifier {
|
||||
builder.setContentTitle(String.format(context.getString(R.string.MessageNotifier_d_new_messages),
|
||||
notificationState.getMessageCount()));
|
||||
builder.setContentText(String.format(context.getString(R.string.MessageNotifier_most_recent_from_s),
|
||||
notifications.get(0).getRecipientName()));
|
||||
notifications.get(0).getIndividualRecipientName()));
|
||||
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, RoutingActivity.class), 0));
|
||||
|
||||
InboxStyle style = new InboxStyle();
|
||||
@@ -246,6 +247,7 @@ public class MessageNotifier {
|
||||
else reader = DatabaseFactory.getMmsSmsDatabase(context).readerFor(cursor, masterSecret);
|
||||
|
||||
while ((record = reader.getNext()) != null) {
|
||||
Recipient recipient = record.getIndividualRecipient();
|
||||
Recipients recipients = record.getRecipients();
|
||||
long threadId = record.getThreadId();
|
||||
SpannableString body = record.getDisplayBody();
|
||||
@@ -257,7 +259,7 @@ public class MessageNotifier {
|
||||
body.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
notificationState.addNotification(new NotificationItem(recipients, threadId, body, image));
|
||||
notificationState.addNotification(new NotificationItem(recipient, recipients, threadId, body, image));
|
||||
}
|
||||
|
||||
return notificationState;
|
||||
|
||||
@@ -7,29 +7,34 @@ import android.net.Uri;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
import org.thoughtcrime.securesms.RoutingActivity;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
public class NotificationItem {
|
||||
|
||||
private final Recipients recipients;
|
||||
private final Recipient individualRecipient;
|
||||
private final long threadId;
|
||||
private final CharSequence text;
|
||||
private final Uri image;
|
||||
|
||||
public NotificationItem(Recipients recipients, long threadId, CharSequence text, Uri image) {
|
||||
this.recipients = recipients;
|
||||
this.text = text;
|
||||
this.image = image;
|
||||
this.threadId = threadId;
|
||||
public NotificationItem(Recipient individualRecipient, Recipients recipients, long threadId,
|
||||
CharSequence text, Uri image)
|
||||
{
|
||||
this.individualRecipient = individualRecipient;
|
||||
this.recipients = recipients;
|
||||
this.text = text;
|
||||
this.image = image;
|
||||
this.threadId = threadId;
|
||||
}
|
||||
|
||||
public Recipients getRecipients() {
|
||||
return recipients;
|
||||
public Recipient getIndividualRecipient() {
|
||||
return individualRecipient;
|
||||
}
|
||||
|
||||
public String getRecipientName() {
|
||||
return recipients.getPrimaryRecipient().toShortString();
|
||||
public String getIndividualRecipientName() {
|
||||
return individualRecipient.toShortString();
|
||||
}
|
||||
|
||||
public CharSequence getText() {
|
||||
@@ -54,7 +59,7 @@ public class NotificationItem {
|
||||
|
||||
public CharSequence getTickerText() {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
builder.append(Util.getBoldedString(getRecipientName()));
|
||||
builder.append(Util.getBoldedString(getIndividualRecipientName()));
|
||||
builder.append(": ");
|
||||
builder.append(getText());
|
||||
|
||||
@@ -65,7 +70,7 @@ public class NotificationItem {
|
||||
Intent intent = new Intent(context, RoutingActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
|
||||
if (recipients.getPrimaryRecipient() != null) {
|
||||
if (recipients != null) {
|
||||
intent.putExtra("recipients", recipients);
|
||||
intent.putExtra("thread_id", threadId);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class NotificationState {
|
||||
}
|
||||
|
||||
public Bitmap getContactPhoto() {
|
||||
return notifications.get(0).getRecipients().getPrimaryRecipient().getContactPhoto();
|
||||
return notifications.get(0).getIndividualRecipient().getContactPhoto();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,29 +91,29 @@ public class Recipients implements Parcelable {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Recipients getSecureSessionRecipients(Context context) {
|
||||
List<Recipient> secureRecipients = new LinkedList<Recipient>();
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
if (KeyUtil.isSessionFor(context, recipient)) {
|
||||
secureRecipients.add(recipient);
|
||||
}
|
||||
}
|
||||
|
||||
return new Recipients(secureRecipients);
|
||||
}
|
||||
|
||||
public Recipients getInsecureSessionRecipients(Context context) {
|
||||
List<Recipient> insecureRecipients = new LinkedList<Recipient>();
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
if (!KeyUtil.isSessionFor(context, recipient)) {
|
||||
insecureRecipients.add(recipient);
|
||||
}
|
||||
}
|
||||
|
||||
return new Recipients(insecureRecipients);
|
||||
}
|
||||
// public Recipients getSecureSessionRecipients(Context context) {
|
||||
// List<Recipient> secureRecipients = new LinkedList<Recipient>();
|
||||
//
|
||||
// for (Recipient recipient : recipients) {
|
||||
// if (KeyUtil.isSessionFor(context, recipient)) {
|
||||
// secureRecipients.add(recipient);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return new Recipients(secureRecipients);
|
||||
// }
|
||||
//
|
||||
// public Recipients getInsecureSessionRecipients(Context context) {
|
||||
// List<Recipient> insecureRecipients = new LinkedList<Recipient>();
|
||||
//
|
||||
// for (Recipient recipient : recipients) {
|
||||
// if (!KeyUtil.isSessionFor(context, recipient)) {
|
||||
// insecureRecipients.add(recipient);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return new Recipients(insecureRecipients);
|
||||
// }
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.recipients.isEmpty();
|
||||
|
||||
@@ -22,9 +22,9 @@ import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.mms.TextSlide;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.service.SendReceiveService;
|
||||
|
||||
@@ -39,11 +39,12 @@ import ws.com.google.android.mms.pdu.SendReq;
|
||||
public class MessageSender {
|
||||
|
||||
public static long sendMms(Context context, MasterSecret masterSecret, Recipients recipients,
|
||||
long threadId, SlideDeck slideDeck, String message, boolean forcePlaintext)
|
||||
long threadId, SlideDeck slideDeck, String message, int distributionType,
|
||||
boolean forcePlaintext)
|
||||
throws MmsException
|
||||
{
|
||||
if (threadId == -1)
|
||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients, distributionType);
|
||||
|
||||
if (message.trim().length() > 0)
|
||||
slideDeck.addSlide(new TextSlide(context, message));
|
||||
@@ -55,17 +56,19 @@ public class MessageSender {
|
||||
sendRequest.setBody(body);
|
||||
sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes());
|
||||
|
||||
Recipients secureRecipients = recipients.getSecureSessionRecipients(context);
|
||||
Recipients insecureRecipients = recipients.getInsecureSessionRecipients(context);
|
||||
// Recipients secureRecipients = recipients.getSecureSessionRecipients(context);
|
||||
// Recipients insecureRecipients = recipients.getInsecureSessionRecipients(context);
|
||||
|
||||
for (Recipient secureRecipient : secureRecipients.getRecipientsList()) {
|
||||
sendMms(context, new Recipients(secureRecipient), masterSecret,
|
||||
sendRequest, threadId, !forcePlaintext);
|
||||
}
|
||||
// for (Recipient secureRecipient : secureRecipients.getRecipientsList()) {
|
||||
// sendMms(context, new Recipients(secureRecipient), masterSecret,
|
||||
// sendRequest, threadId, !forcePlaintext);
|
||||
// }
|
||||
//
|
||||
// if (!insecureRecipients.isEmpty()) {
|
||||
// sendMms(context, insecureRecipients, masterSecret, sendRequest, threadId, false);
|
||||
// }
|
||||
|
||||
if (!insecureRecipients.isEmpty()) {
|
||||
sendMms(context, insecureRecipients, masterSecret, sendRequest, threadId, false);
|
||||
}
|
||||
sendMms(context, recipients, masterSecret, sendRequest, threadId, distributionType, false);
|
||||
|
||||
return threadId;
|
||||
}
|
||||
@@ -93,13 +96,19 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private static void sendMms(Context context, Recipients recipients, MasterSecret masterSecret,
|
||||
SendReq sendRequest, long threadId, boolean secure)
|
||||
SendReq sendRequest, long threadId, int distributionType, boolean secure)
|
||||
throws MmsException
|
||||
{
|
||||
String[] recipientsArray = recipients.toNumberStringArray(true);
|
||||
EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(recipientsArray);
|
||||
|
||||
sendRequest.setTo(encodedNumbers);
|
||||
if (recipients.isSingleRecipient()) {
|
||||
sendRequest.setTo(encodedNumbers);
|
||||
} else if (distributionType == ThreadDatabase.DistributionTypes.BROADCAST) {
|
||||
sendRequest.setBcc(encodedNumbers);
|
||||
} else if (distributionType == ThreadDatabase.DistributionTypes.CONVERSATION) {
|
||||
sendRequest.setCc(encodedNumbers);
|
||||
}
|
||||
|
||||
long messageId = DatabaseFactory.getMmsDatabase(context)
|
||||
.insertMessageOutbox(masterSecret, sendRequest, threadId, secure);
|
||||
|
||||
@@ -24,7 +24,7 @@ public class UniversalTransport {
|
||||
}
|
||||
|
||||
public void deliver(SmsMessageRecord message) throws UndeliverableMessageException {
|
||||
Recipient recipient = message.getRecipients().getPrimaryRecipient();
|
||||
Recipient recipient = message.getIndividualRecipient();
|
||||
String number = PhoneNumberFormatter.formatNumber(context, recipient.getNumber());
|
||||
|
||||
if (NumberFilter.getInstance(context).containsNumber(number)) {
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ws.com.google.android.mms.pdu.EncodedStringValue;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static byte[] combine(byte[] one, byte[] two) {
|
||||
@@ -105,6 +107,10 @@ public class Util {
|
||||
return value == null || value.length() == 0;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(EncodedStringValue[] value) {
|
||||
return value == null || value.length == 0;
|
||||
}
|
||||
|
||||
public static CharSequence getBoldedString(String value) {
|
||||
SpannableString spanned = new SpannableString(value);
|
||||
spanned.setSpan(new StyleSpan(Typeface.BOLD), 0,
|
||||
@@ -156,6 +162,7 @@ public class Util {
|
||||
return new String(bout.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
// public static Bitmap loadScaledBitmap(InputStream src, int targetWidth, int targetHeight) {
|
||||
// return BitmapFactory.decodeStream(src);
|
||||
//// BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
|
||||
Reference in New Issue
Block a user