Indicate a message was delivered via push in its delivery status.

This commit is contained in:
Moxie Marlinspike 2014-02-20 16:14:58 -08:00
parent 918f223149
commit ff238a1ce9
16 changed files with 65 additions and 29 deletions

View File

@ -212,7 +212,8 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
} }
} else { } else {
if (TextSecurePreferences.isInterceptAllMmsEnabled(this) || if (TextSecurePreferences.isInterceptAllMmsEnabled(this) ||
TextSecurePreferences.isInterceptAllSmsEnabled(this)) TextSecurePreferences.isInterceptAllSmsEnabled(this) ||
!TextSecurePreferences.isPushRegistered(this))
{ {
allowSmsPreference.setEnabled(false); allowSmsPreference.setEnabled(false);
allowSmsPreference.setChecked(true); allowSmsPreference.setChecked(true);
@ -293,7 +294,8 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
} else if (key.equals(TextSecurePreferences.LANGUAGE_PREF)) { } else if (key.equals(TextSecurePreferences.LANGUAGE_PREF)) {
dynamicLanguage.onResume(this); dynamicLanguage.onResume(this);
} else if (key.equals(TextSecurePreferences.ALL_MMS_PREF) || } else if (key.equals(TextSecurePreferences.ALL_MMS_PREF) ||
key.equals(TextSecurePreferences.ALL_SMS_PREF)) key.equals(TextSecurePreferences.ALL_SMS_PREF) ||
key.equals(TextSecurePreferences.REGISTERED_GCM_PREF))
{ {
initializeSmsFallbackOption(); initializeSmsFallbackOption();
} }

View File

@ -174,6 +174,12 @@ public class ConversationItem extends LinearLayout {
/// MessageRecord Attribute Parsers /// MessageRecord Attribute Parsers
private void setBodyText(MessageRecord messageRecord) { private void setBodyText(MessageRecord messageRecord) {
// TODO jake is going to fix this up
if (messageRecord.isPushSent()) {
bodyText.setText("PUSH " + messageRecord.getDisplayBody());
return;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(), Emoji.EMOJI_LARGE), bodyText.setText(Emoji.getInstance(context).emojify(messageRecord.getDisplayBody(), Emoji.EMOJI_LARGE),
TextView.BufferType.SPANNABLE); TextView.BufferType.SPANNABLE);

View File

@ -284,6 +284,15 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
notifyConversationListeners(getThreadIdForMessage(messageId)); notifyConversationListeners(getThreadIdForMessage(messageId));
} }
public void markDeliveryStatus(long messageId, int status) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(STATUS, status);
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {messageId + ""});
notifyConversationListeners(getThreadIdForMessage(messageId));
}
public void markAsNoSession(long messageId, long threadId) { public void markAsNoSession(long messageId, long threadId) {
updateMailboxBitmask(messageId, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_NO_SESSION_BIT); updateMailboxBitmask(messageId, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_NO_SESSION_BIT);
notifyConversationListeners(threadId); notifyConversationListeners(threadId);
@ -855,6 +864,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID)); long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.THREAD_ID));
String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS)); String address = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS));
int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID)); int addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS_DEVICE_ID));
int status = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.STATUS));
DisplayRecord.Body body = getBody(cursor); DisplayRecord.Body body = getBody(cursor);
int partCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.PART_COUNT)); int partCount = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.PART_COUNT));
Recipients recipients = getRecipientsFor(address); Recipients recipients = getRecipientsFor(address);
@ -863,7 +873,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(), return new MediaMmsMessageRecord(context, id, recipients, recipients.getPrimaryRecipient(),
addressDeviceId, dateSent, dateReceived, threadId, body, addressDeviceId, dateSent, dateReceived, threadId, body,
slideDeck, partCount, box); slideDeck, partCount, status, box);
} }
private Recipients getRecipientsFor(String address) { private Recipients getRecipientsFor(String address) {

View File

@ -467,9 +467,10 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
public static class Status { public static class Status {
public static final int STATUS_NONE = -1; public static final int STATUS_NONE = -1;
public static final int STATUS_COMPLETE = 0; public static final int STATUS_COMPLETE = 0;
public static final int STATUS_PENDING = 32; public static final int STATUS_PENDING = 0x20;
public static final int STATUS_FAILED = 64; public static final int STATUS_FAILED = 0x40;
public static final int STATUS_SENT_PUSH = 0x8000;
} }
public Reader readerFor(Cursor cursor) { public Reader readerFor(Cursor cursor) {

View File

@ -18,10 +18,10 @@ package org.thoughtcrime.securesms.database.model;
import android.content.Context; import android.content.Context;
import android.text.SpannableString; import android.text.SpannableString;
import android.util.Log;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.recipients.Recipients;
@ -45,10 +45,10 @@ public class MediaMmsMessageRecord extends MessageRecord {
Recipient individualRecipient, int recipientDeviceId, Recipient individualRecipient, int recipientDeviceId,
long dateSent, long dateReceived, long threadId, Body body, long dateSent, long dateReceived, long threadId, Body body,
ListenableFutureTask<SlideDeck> slideDeck, ListenableFutureTask<SlideDeck> slideDeck,
int partCount, long mailbox) int partCount, int deliveryStatus, long mailbox)
{ {
super(context, id, body, recipients, individualRecipient, recipientDeviceId, super(context, id, body, recipients, individualRecipient, recipientDeviceId,
dateSent, dateReceived, threadId, DELIVERY_STATUS_NONE, mailbox); dateSent, dateReceived, threadId, getGenericDeliveryStatus(deliveryStatus), mailbox);
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.partCount = partCount; this.partCount = partCount;
@ -82,4 +82,8 @@ public class MediaMmsMessageRecord extends MessageRecord {
return super.getDisplayBody(); return super.getDisplayBody();
} }
private static int getGenericDeliveryStatus(int status) {
return status == SmsDatabase.Status.STATUS_SENT_PUSH ? DELVIERY_STATUS_PUSH : DELIVERY_STATUS_NONE;
}
} }

View File

@ -17,10 +17,8 @@
package org.thoughtcrime.securesms.database.model; package org.thoughtcrime.securesms.database.model;
import android.content.Context; import android.content.Context;
import android.graphics.Color;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.text.style.TextAppearanceSpan; import android.text.style.TextAppearanceSpan;
@ -46,6 +44,7 @@ public abstract class MessageRecord extends DisplayRecord {
public static final int DELIVERY_STATUS_RECEIVED = 1; public static final int DELIVERY_STATUS_RECEIVED = 1;
public static final int DELIVERY_STATUS_PENDING = 2; public static final int DELIVERY_STATUS_PENDING = 2;
public static final int DELIVERY_STATUS_FAILED = 3; public static final int DELIVERY_STATUS_FAILED = 3;
public static final int DELVIERY_STATUS_PUSH = 4;
private final Recipient individualRecipient; private final Recipient individualRecipient;
private final int recipientDeviceId; private final int recipientDeviceId;
@ -109,6 +108,10 @@ public abstract class MessageRecord extends DisplayRecord {
return getDeliveryStatus() == DELIVERY_STATUS_RECEIVED; return getDeliveryStatus() == DELIVERY_STATUS_RECEIVED;
} }
public boolean isPushSent() {
return getDeliveryStatus() == DELVIERY_STATUS_PUSH;
}
public boolean isStaleKeyExchange() { public boolean isStaleKeyExchange() {
return SmsDatabase.Types.isStaleKeyExchange(type); return SmsDatabase.Types.isStaleKeyExchange(type);
} }

View File

@ -97,6 +97,8 @@ public class SmsMessageRecord extends MessageRecord {
private static int getGenericDeliveryStatus(int status) { private static int getGenericDeliveryStatus(int status) {
if (status == SmsDatabase.Status.STATUS_NONE) { if (status == SmsDatabase.Status.STATUS_NONE) {
return MessageRecord.DELIVERY_STATUS_NONE; return MessageRecord.DELIVERY_STATUS_NONE;
} else if (status >= SmsDatabase.Status.STATUS_SENT_PUSH) {
return MessageRecord.DELVIERY_STATUS_PUSH;
} else if (status >= SmsDatabase.Status.STATUS_FAILED) { } else if (status >= SmsDatabase.Status.STATUS_FAILED) {
return MessageRecord.DELIVERY_STATUS_FAILED; return MessageRecord.DELIVERY_STATUS_FAILED;
} else if (status >= SmsDatabase.Status.STATUS_PENDING) { } else if (status >= SmsDatabase.Status.STATUS_PENDING) {

View File

@ -5,12 +5,17 @@ public class MmsSendResult {
private final byte[] messageId; private final byte[] messageId;
private final int responseStatus; private final int responseStatus;
private final boolean upgradedSecure; private final boolean upgradedSecure;
private final boolean push;
public MmsSendResult(byte[] messageId, int responseStatus, boolean upgradedSecure, boolean push) {
public MmsSendResult(byte[] messageId, int responseStatus, boolean upgradedSecure) {
this.messageId = messageId; this.messageId = messageId;
this.responseStatus = responseStatus; this.responseStatus = responseStatus;
this.upgradedSecure = upgradedSecure; this.upgradedSecure = upgradedSecure;
this.push = push;
}
public boolean isPush() {
return push;
} }
public boolean isUpgradedSecure() { public boolean isUpgradedSecure() {

View File

@ -31,17 +31,17 @@ import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.SendReceiveService.ToastHandler; import org.thoughtcrime.securesms.service.SendReceiveService.ToastHandler;
import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage; import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.transport.UniversalTransport; import org.thoughtcrime.securesms.transport.UniversalTransport;
import org.thoughtcrime.securesms.transport.UntrustedIdentityException; import org.thoughtcrime.securesms.transport.UntrustedIdentityException;
import org.whispersystems.textsecure.crypto.MasterSecret; import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.util.Base64;
import ws.com.google.android.mms.MmsException; import ws.com.google.android.mms.MmsException;
import ws.com.google.android.mms.pdu.SendReq; import ws.com.google.android.mms.pdu.SendReq;
import static org.thoughtcrime.securesms.database.SmsDatabase.Status;
public class MmsSender { public class MmsSender {
private final Context context; private final Context context;
@ -78,9 +78,9 @@ public class MmsSender {
database.markAsSending(message.getDatabaseMessageId()); database.markAsSending(message.getDatabaseMessageId());
MmsSendResult result = transport.deliver(message, threadId); MmsSendResult result = transport.deliver(message, threadId);
if (result.isUpgradedSecure()) { if (result.isUpgradedSecure()) database.markAsSecure(message.getDatabaseMessageId());
database.markAsSecure(message.getDatabaseMessageId()); if (result.isPush()) database.markDeliveryStatus(message.getDatabaseMessageId(),
} Status.STATUS_SENT_PUSH);
database.markAsSent(message.getDatabaseMessageId(), result.getMessageId(), database.markAsSent(message.getDatabaseMessageId(), result.getMessageId(),
result.getResponseStatus()); result.getResponseStatus());

View File

@ -108,6 +108,7 @@ public class SmsSender {
long messageId = intent.getLongExtra("message_id", -1); long messageId = intent.getLongExtra("message_id", -1);
int result = intent.getIntExtra("ResultCode", -31337); int result = intent.getIntExtra("ResultCode", -31337);
boolean upgraded = intent.getBooleanExtra("upgraded", false); boolean upgraded = intent.getBooleanExtra("upgraded", false);
boolean push = intent.getBooleanExtra("push", false);
Log.w("SMSReceiverService", "Intent resultcode: " + result); Log.w("SMSReceiverService", "Intent resultcode: " + result);
Log.w("SMSReceiverService", "Running sent callback: " + messageId); Log.w("SMSReceiverService", "Running sent callback: " + messageId);
@ -119,9 +120,8 @@ public class SmsSender {
database.markAsSent(messageId); database.markAsSent(messageId);
if (upgraded) { if (upgraded) database.markAsSecure(messageId);
database.markAsSecure(messageId); if (push) database.markStatus(messageId, SmsDatabase.Status.STATUS_SENT_PUSH);
}
SmsMessageRecord record = reader.getNext(); SmsMessageRecord record = reader.getNext();

View File

@ -9,7 +9,9 @@ import org.thoughtcrime.securesms.service.SmsDeliveryListener;
public abstract class BaseTransport { public abstract class BaseTransport {
protected Intent constructSentIntent(Context context, long messageId, long type, boolean upgraded) { protected Intent constructSentIntent(Context context, long messageId, long type,
boolean upgraded, boolean push)
{
Intent pending = new Intent(SendReceiveService.SENT_SMS_ACTION, Intent pending = new Intent(SendReceiveService.SENT_SMS_ACTION,
Uri.parse("custom://" + messageId + System.currentTimeMillis()), Uri.parse("custom://" + messageId + System.currentTimeMillis()),
context, SmsDeliveryListener.class); context, SmsDeliveryListener.class);
@ -17,6 +19,7 @@ public abstract class BaseTransport {
pending.putExtra("type", type); pending.putExtra("type", type);
pending.putExtra("message_id", messageId); pending.putExtra("message_id", messageId);
pending.putExtra("upgraded", upgraded); pending.putExtra("upgraded", upgraded);
pending.putExtra("push", push);
return pending; return pending;
} }

View File

@ -130,7 +130,7 @@ public class MmsTransport {
} else if (isInconsistentResponse(message, conf)) { } else if (isInconsistentResponse(message, conf)) {
throw new UndeliverableMessageException("Mismatched response!"); throw new UndeliverableMessageException("Mismatched response!");
} else { } else {
return new MmsSendResult(conf.getMessageId(), conf.getResponseStatus(), upgradedSecure); return new MmsSendResult(conf.getMessageId(), conf.getResponseStatus(), upgradedSecure, false);
} }
} }

View File

@ -96,7 +96,7 @@ public class PushTransport extends BaseTransport {
KeyExchangeProcessor.broadcastSecurityUpdateEvent(context, threadId); KeyExchangeProcessor.broadcastSecurityUpdateEvent(context, threadId);
} }
context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType(), true)); context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType(), true, true));
} catch (InvalidNumberException e) { } catch (InvalidNumberException e) {
Log.w("PushTransport", e); Log.w("PushTransport", e);

View File

@ -139,7 +139,7 @@ public class SmsTransport extends BaseTransport {
for (String ignored : messages) { for (String ignored : messages) {
sentIntents.add(PendingIntent.getBroadcast(context, 0, sentIntents.add(PendingIntent.getBroadcast(context, 0,
constructSentIntent(context, messageId, type, secure), constructSentIntent(context, messageId, type, secure, false),
0)); 0));
} }

View File

@ -124,7 +124,7 @@ public class UniversalTransport {
try { try {
Log.w("UniversalTransport", "Delivering media message with GCM..."); Log.w("UniversalTransport", "Delivering media message with GCM...");
pushTransport.deliver(mediaMessage, threadId); pushTransport.deliver(mediaMessage, threadId);
return new MmsSendResult("push".getBytes("UTF-8"), 0, true); return new MmsSendResult("push".getBytes("UTF-8"), 0, true, true);
} catch (IOException ioe) { } catch (IOException ioe) {
Log.w("UniversalTransport", ioe); Log.w("UniversalTransport", ioe);
if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage); if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage);
@ -161,7 +161,7 @@ public class UniversalTransport {
try { try {
pushTransport.deliver(mediaMessage, threadId); pushTransport.deliver(mediaMessage, threadId);
return new MmsSendResult("push".getBytes("UTF-8"), 0, true); return new MmsSendResult("push".getBytes("UTF-8"), 0, true, true);
} catch (IOException e) { } catch (IOException e) {
Log.w("UniversalTransport", e); Log.w("UniversalTransport", e);
throw new RetryLaterException(e); throw new RetryLaterException(e);
@ -183,7 +183,7 @@ public class UniversalTransport {
DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageInbox(masterSecret, identityMessage); DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageInbox(masterSecret, identityMessage);
} }
return new MmsSendResult("push".getBytes("UTF-8"), 0, true); return new MmsSendResult("push".getBytes("UTF-8"), 0, true, true);
} catch (IOException ioe) { } catch (IOException ioe) {
throw new AssertionError(ioe); throw new AssertionError(ioe);
} }

View File

@ -35,7 +35,7 @@ public class TextSecurePreferences {
private static final String THREAD_TRIM_ENABLED = "pref_trim_threads"; private static final String THREAD_TRIM_ENABLED = "pref_trim_threads";
private static final String LOCAL_NUMBER_PREF = "pref_local_number"; private static final String LOCAL_NUMBER_PREF = "pref_local_number";
private static final String VERIFYING_STATE_PREF = "pref_verifying"; private static final String VERIFYING_STATE_PREF = "pref_verifying";
private static final String REGISTERED_GCM_PREF = "pref_gcm_registered"; public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
private static final String GCM_PASSWORD_PREF = "pref_gcm_password"; private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration"; private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration";
private static final String PROMPTED_DEFAULT_SMS_PREF = "pref_prompted_default_sms"; private static final String PROMPTED_DEFAULT_SMS_PREF = "pref_prompted_default_sms";