mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-22 07:38:26 +00:00
UX for unencrypted fallback case
This commit is contained in:
parent
40629a3bcf
commit
832763f695
@ -35,6 +35,27 @@ public class Session {
|
|||||||
return hasV1Session(context, recipient) || hasV2Session(context, masterSecret, recipient);
|
return hasV1Session(context, recipient) || hasV2Session(context, masterSecret, recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasEncryptCapableSession(Context context,
|
||||||
|
MasterSecret masterSecret,
|
||||||
|
CanonicalRecipient recipient)
|
||||||
|
{
|
||||||
|
RecipientDevice device = new RecipientDevice(recipient.getRecipientId(),
|
||||||
|
RecipientDevice.DEFAULT_DEVICE_ID);
|
||||||
|
|
||||||
|
return hasEncryptCapableSession(context, masterSecret, recipient, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasEncryptCapableSession(Context context,
|
||||||
|
MasterSecret masterSecret,
|
||||||
|
CanonicalRecipient recipient,
|
||||||
|
RecipientDevice device)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
hasV1Session(context, recipient) ||
|
||||||
|
(hasV2Session(context, masterSecret, recipient) &&
|
||||||
|
!SessionRecordV2.needsRefresh(context, masterSecret, device));
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean hasRemoteIdentityKey(Context context,
|
public static boolean hasRemoteIdentityKey(Context context,
|
||||||
MasterSecret masterSecret,
|
MasterSecret masterSecret,
|
||||||
CanonicalRecipient recipient)
|
CanonicalRecipient recipient)
|
||||||
|
@ -64,7 +64,10 @@
|
|||||||
<string name="ConversationItem_group_action_joined">%1$s have joined the group.</string>
|
<string name="ConversationItem_group_action_joined">%1$s have joined the group.</string>
|
||||||
<string name="ConversationItem_group_action_modify">%1$s has updated the group.</string>
|
<string name="ConversationItem_group_action_modify">%1$s has updated the group.</string>
|
||||||
<string name="ConversationItem_click_to_approve">Tap for SMS fallback</string>
|
<string name="ConversationItem_click_to_approve">Tap for SMS fallback</string>
|
||||||
|
<string name="ConversationItem_click_to_approve_unencrypted">Tap for insecure fallback</string>
|
||||||
<string name="ConversationItem_click_to_approve_dialog_title">Fallback to SMS?</string>
|
<string name="ConversationItem_click_to_approve_dialog_title">Fallback to SMS?</string>
|
||||||
|
<string name="ConversationItem_click_to_approve_unencrypted_dialog_title">Fallback to unencrypted SMS?</string>
|
||||||
|
<string name="ConversationItem_click_to_approve_unencrypted_dialog_message">This message will <b>not</b> be encrypted because a secure session could not be established.\n\nSend insecure message?</string>
|
||||||
|
|
||||||
<!-- ConversationActivity -->
|
<!-- ConversationActivity -->
|
||||||
<string name="ConversationActivity_initiate_secure_session_question">Initiate Secure Session?</string>
|
<string name="ConversationActivity_initiate_secure_session_question">Initiate Secure Session?</string>
|
||||||
|
@ -675,7 +675,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
|||||||
R.attr.conversation_send_secure_button};
|
R.attr.conversation_send_secure_button};
|
||||||
TypedArray drawables = obtainStyledAttributes(attributes);
|
TypedArray drawables = obtainStyledAttributes(attributes);
|
||||||
|
|
||||||
if ((getRecipients() != null && getRecipients().isGroupRecipient()) ||
|
if (isPushDestination() || (getRecipients() != null && getRecipients().isGroupRecipient()) ||
|
||||||
(isSingleConversation() && Session.hasSession(this, masterSecret, getRecipients().getPrimaryRecipient())))
|
(isSingleConversation() && Session.hasSession(this, masterSecret, getRecipients().getPrimaryRecipient())))
|
||||||
{
|
{
|
||||||
sendButton.setImageDrawable(drawables.getDrawable(1));
|
sendButton.setImageDrawable(drawables.getDrawable(1));
|
||||||
|
@ -25,8 +25,6 @@ import android.content.res.TypedArray;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.media.MediaScannerConnection;
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
@ -59,8 +57,6 @@ import org.thoughtcrime.securesms.util.DateUtils;
|
|||||||
import org.thoughtcrime.securesms.util.Emoji;
|
import org.thoughtcrime.securesms.util.Emoji;
|
||||||
import org.thoughtcrime.securesms.util.Dialogs;
|
import org.thoughtcrime.securesms.util.Dialogs;
|
||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
import org.whispersystems.textsecure.directory.Directory;
|
|
||||||
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
|
||||||
import org.whispersystems.textsecure.storage.Session;
|
import org.whispersystems.textsecure.storage.Session;
|
||||||
import org.whispersystems.textsecure.util.FutureTaskListener;
|
import org.whispersystems.textsecure.util.FutureTaskListener;
|
||||||
import org.whispersystems.textsecure.util.ListenableFutureTask;
|
import org.whispersystems.textsecure.util.ListenableFutureTask;
|
||||||
@ -230,7 +226,7 @@ public class ConversationItem extends LinearLayout {
|
|||||||
if (messageRecord.isPending() && pushDestination && !messageRecord.isForcedSms()) {
|
if (messageRecord.isPending() && pushDestination && !messageRecord.isForcedSms()) {
|
||||||
background = SENT_PUSH_PENDING;
|
background = SENT_PUSH_PENDING;
|
||||||
triangleBackground = SENT_PUSH_PENDING_TRIANGLE;
|
triangleBackground = SENT_PUSH_PENDING_TRIANGLE;
|
||||||
} else if (messageRecord.isPending() || messageRecord.isPendingFallbackApproval()) {
|
} else if (messageRecord.isPending() || messageRecord.isPendingSmsFallback()) {
|
||||||
background = SENT_SMS_PENDING;
|
background = SENT_SMS_PENDING;
|
||||||
triangleBackground = SENT_SMS_PENDING_TRIANGLE;
|
triangleBackground = SENT_SMS_PENDING_TRIANGLE;
|
||||||
} else if (messageRecord.isPush()) {
|
} else if (messageRecord.isPush()) {
|
||||||
@ -265,8 +261,8 @@ public class ConversationItem extends LinearLayout {
|
|||||||
private void setStatusIcons(MessageRecord messageRecord) {
|
private void setStatusIcons(MessageRecord messageRecord) {
|
||||||
failedImage.setVisibility(messageRecord.isFailed() ? View.VISIBLE : View.GONE);
|
failedImage.setVisibility(messageRecord.isFailed() ? View.VISIBLE : View.GONE);
|
||||||
if (messageRecord.isOutgoing()) {
|
if (messageRecord.isOutgoing()) {
|
||||||
pendingIndicator.setVisibility(messageRecord.isPendingFallbackApproval() ? View.VISIBLE : View.GONE);
|
pendingIndicator.setVisibility(messageRecord.isPendingSmsFallback() ? View.VISIBLE : View.GONE);
|
||||||
indicatorText.setVisibility(messageRecord.isPendingFallbackApproval() ? View.VISIBLE : View.GONE);
|
indicatorText.setVisibility(messageRecord.isPendingSmsFallback() ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
secureImage.setVisibility(messageRecord.isSecure() ? View.VISIBLE : View.GONE);
|
secureImage.setVisibility(messageRecord.isSecure() ? View.VISIBLE : View.GONE);
|
||||||
keyImage.setVisibility(messageRecord.isKeyExchange() ? View.VISIBLE : View.GONE);
|
keyImage.setVisibility(messageRecord.isKeyExchange() ? View.VISIBLE : View.GONE);
|
||||||
@ -278,9 +274,10 @@ public class ConversationItem extends LinearLayout {
|
|||||||
|
|
||||||
if (messageRecord.isFailed()) {
|
if (messageRecord.isFailed()) {
|
||||||
dateText.setText(R.string.ConversationItem_error_sending_message);
|
dateText.setText(R.string.ConversationItem_error_sending_message);
|
||||||
} else if (messageRecord.isPendingFallbackApproval() && indicatorText != null) {
|
} else if (messageRecord.isPendingSmsFallback() && indicatorText != null) {
|
||||||
dateText.setText("");
|
dateText.setText("");
|
||||||
indicatorText.setText(R.string.ConversationItem_click_to_approve);
|
if (messageRecord.isPendingSecureSmsFallback()) indicatorText.setText(R.string.ConversationItem_click_to_approve);
|
||||||
|
else indicatorText.setText(R.string.ConversationItem_click_to_approve_unencrypted);
|
||||||
} else if (messageRecord.isPending()) {
|
} else if (messageRecord.isPending()) {
|
||||||
dateText.setText(" ··· ");
|
dateText.setText(" ··· ");
|
||||||
} else {
|
} else {
|
||||||
@ -294,14 +291,15 @@ public class ConversationItem extends LinearLayout {
|
|||||||
|
|
||||||
private void setMinimumWidth() {
|
private void setMinimumWidth() {
|
||||||
if (indicatorText != null && indicatorText.getVisibility() == View.VISIBLE && indicatorText.getText() != null) {
|
if (indicatorText != null && indicatorText.getVisibility() == View.VISIBLE && indicatorText.getText() != null) {
|
||||||
conversationParent.setMinimumWidth(indicatorText.getText().length() * 20);
|
final float density = getResources().getDisplayMetrics().density;
|
||||||
|
conversationParent.setMinimumWidth(indicatorText.getText().length() * (int)(6.5 * density));
|
||||||
} else {
|
} else {
|
||||||
conversationParent.setMinimumWidth(0);
|
conversationParent.setMinimumWidth(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEvents(MessageRecord messageRecord) {
|
private void setEvents(MessageRecord messageRecord) {
|
||||||
setClickable(messageRecord.isPendingFallbackApproval() ||
|
setClickable(messageRecord.isPendingSmsFallback() ||
|
||||||
(messageRecord.isKeyExchange() &&
|
(messageRecord.isKeyExchange() &&
|
||||||
!messageRecord.isCorruptedKeyExchange() &&
|
!messageRecord.isCorruptedKeyExchange() &&
|
||||||
!messageRecord.isOutgoing()));
|
!messageRecord.isOutgoing()));
|
||||||
@ -640,23 +638,40 @@ public class ConversationItem extends LinearLayout {
|
|||||||
!messageRecord.isProcessedKeyExchange() &&
|
!messageRecord.isProcessedKeyExchange() &&
|
||||||
!messageRecord.isStaleKeyExchange())
|
!messageRecord.isStaleKeyExchange())
|
||||||
handleKeyExchangeClicked();
|
handleKeyExchangeClicked();
|
||||||
else if (messageRecord.isPendingFallbackApproval())
|
else if (messageRecord.isPendingSmsFallback())
|
||||||
handleMessageApproval();
|
handleMessageApproval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMessageApproval() {
|
private void handleMessageApproval() {
|
||||||
|
final int title;
|
||||||
|
final int message;
|
||||||
|
if (messageRecord.isPendingSecureSmsFallback()) {
|
||||||
|
title = R.string.ConversationItem_click_to_approve_dialog_title;
|
||||||
|
message = -1;
|
||||||
|
} else {
|
||||||
|
title = R.string.ConversationItem_click_to_approve_unencrypted_dialog_title;
|
||||||
|
message = R.string.ConversationItem_click_to_approve_unencrypted_dialog_message;
|
||||||
|
}
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
builder.setTitle(R.string.ConversationItem_click_to_approve_dialog_title);
|
builder.setTitle(title);
|
||||||
|
if (message > -1) builder.setMessage(message);
|
||||||
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
if (messageRecord.isMms()) {
|
if (messageRecord.isMms()) {
|
||||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
|
if (messageRecord.isPendingInsecureSmsFallback()) {
|
||||||
|
database.markAsInsecure(messageRecord.getId());
|
||||||
|
}
|
||||||
database.markAsOutbox(messageRecord.getId());
|
database.markAsOutbox(messageRecord.getId());
|
||||||
database.markAsForcedSms(messageRecord.getId());
|
database.markAsForcedSms(messageRecord.getId());
|
||||||
} else {
|
} else {
|
||||||
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
||||||
|
if (messageRecord.isPendingInsecureSmsFallback()) {
|
||||||
|
database.markAsInsecure(messageRecord.getId());
|
||||||
|
}
|
||||||
database.markAsOutbox(messageRecord.getId());
|
database.markAsOutbox(messageRecord.getId());
|
||||||
database.markAsForcedSms(messageRecord.getId());
|
database.markAsForcedSms(messageRecord.getId());
|
||||||
}
|
}
|
||||||
@ -669,8 +684,11 @@ public class ConversationItem extends LinearLayout {
|
|||||||
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
if (messageRecord.isMms()) DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageRecord.getId());
|
if (messageRecord.isMms()) {
|
||||||
else DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageRecord.getId());
|
DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageRecord.getId());
|
||||||
|
} else {
|
||||||
|
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageRecord.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.show();
|
builder.show();
|
||||||
|
@ -285,8 +285,13 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
|||||||
updateMailboxBitmask(id, 0, Types.MESSAGE_FORCE_SMS_BIT);
|
updateMailboxBitmask(id, 0, Types.MESSAGE_FORCE_SMS_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAsPendingApproval(long messageId) {
|
public void markAsPendingSecureSmsFallback(long messageId) {
|
||||||
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_PENDING_FALLBACK_APPROVAL);
|
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_PENDING_SECURE_SMS_FALLBACK);
|
||||||
|
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markAsPendingInsecureSmsFallback(long messageId) {
|
||||||
|
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_PENDING_INSECURE_SMS_FALLBACK);
|
||||||
notifyConversationListeners(getThreadIdForMessage(messageId));
|
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,6 +343,10 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
|||||||
updateMailboxBitmask(messageId, 0, Types.SECURE_MESSAGE_BIT);
|
updateMailboxBitmask(messageId, 0, Types.SECURE_MESSAGE_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void markAsInsecure(long messageId) {
|
||||||
|
updateMailboxBitmask(messageId, Types.SECURE_MESSAGE_BIT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void markAsPush(long messageId) {
|
public void markAsPush(long messageId) {
|
||||||
updateMailboxBitmask(messageId, 0, Types.PUSH_MESSAGE_BIT);
|
updateMailboxBitmask(messageId, 0, Types.PUSH_MESSAGE_BIT);
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,13 @@ public interface MmsSmsColumns {
|
|||||||
protected static final long BASE_SENDING_TYPE = 22;
|
protected static final long BASE_SENDING_TYPE = 22;
|
||||||
protected static final long BASE_SENT_TYPE = 23;
|
protected static final long BASE_SENT_TYPE = 23;
|
||||||
protected static final long BASE_SENT_FAILED_TYPE = 24;
|
protected static final long BASE_SENT_FAILED_TYPE = 24;
|
||||||
protected static final long BASE_PENDING_FALLBACK_APPROVAL = 25;
|
protected static final long BASE_PENDING_SECURE_SMS_FALLBACK = 25;
|
||||||
|
protected static final long BASE_PENDING_INSECURE_SMS_FALLBACK = 26;
|
||||||
|
|
||||||
protected static final long[] OUTGOING_MESSAGE_TYPES = {BASE_OUTBOX_TYPE, BASE_SENT_TYPE,
|
protected static final long[] OUTGOING_MESSAGE_TYPES = {BASE_OUTBOX_TYPE, BASE_SENT_TYPE,
|
||||||
BASE_SENDING_TYPE, BASE_SENT_FAILED_TYPE,
|
BASE_SENDING_TYPE, BASE_SENT_FAILED_TYPE,
|
||||||
BASE_PENDING_FALLBACK_APPROVAL};
|
BASE_PENDING_SECURE_SMS_FALLBACK,
|
||||||
|
BASE_PENDING_INSECURE_SMS_FALLBACK};
|
||||||
|
|
||||||
// Message attributes
|
// Message attributes
|
||||||
protected static final long MESSAGE_ATTRIBUTE_MASK = 0xE0;
|
protected static final long MESSAGE_ATTRIBUTE_MASK = 0xE0;
|
||||||
@ -82,8 +84,17 @@ public interface MmsSmsColumns {
|
|||||||
(type & BASE_TYPE_MASK) == BASE_SENDING_TYPE;
|
(type & BASE_TYPE_MASK) == BASE_SENDING_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPendingApprovalType(long type) {
|
public static boolean isPendingSmsFallbackType(long type) {
|
||||||
return (type & BASE_TYPE_MASK) == BASE_PENDING_FALLBACK_APPROVAL;
|
return (type & BASE_TYPE_MASK) == BASE_PENDING_INSECURE_SMS_FALLBACK ||
|
||||||
|
(type & BASE_TYPE_MASK) == BASE_PENDING_SECURE_SMS_FALLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPendingSecureSmsFallbackType(long type) {
|
||||||
|
return (type & BASE_TYPE_MASK) == BASE_PENDING_SECURE_SMS_FALLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPendingInsecureSmsFallbackType(long type) {
|
||||||
|
return (type & BASE_TYPE_MASK) == BASE_PENDING_INSECURE_SMS_FALLBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isInboxType(long type) {
|
public static boolean isInboxType(long type) {
|
||||||
|
@ -174,6 +174,10 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
|||||||
updateTypeBitmask(id, 0, Types.SECURE_MESSAGE_BIT);
|
updateTypeBitmask(id, 0, Types.SECURE_MESSAGE_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void markAsInsecure(long id) {
|
||||||
|
updateTypeBitmask(id, Types.SECURE_MESSAGE_BIT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void markAsPush(long id) {
|
public void markAsPush(long id) {
|
||||||
updateTypeBitmask(id, 0, Types.PUSH_MESSAGE_BIT);
|
updateTypeBitmask(id, 0, Types.PUSH_MESSAGE_BIT);
|
||||||
}
|
}
|
||||||
@ -202,8 +206,12 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
|||||||
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_OUTBOX_TYPE);
|
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_OUTBOX_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAsPendingApproval(long id) {
|
public void markAsPendingSecureSmsFallback(long id) {
|
||||||
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_PENDING_FALLBACK_APPROVAL);
|
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_PENDING_SECURE_SMS_FALLBACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markAsPendingInsecureSmsFallback(long id) {
|
||||||
|
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_PENDING_INSECURE_SMS_FALLBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAsSending(long id) {
|
public void markAsSending(long id) {
|
||||||
|
@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.database.SmsDatabase;
|
|||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.whispersystems.textsecure.util.Util;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base class for message record models that are displayed in
|
* The base class for message record models that are displayed in
|
||||||
@ -125,8 +124,16 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
return SmsDatabase.Types.isProcessedKeyExchange(type);
|
return SmsDatabase.Types.isProcessedKeyExchange(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPendingFallbackApproval() {
|
public boolean isPendingSmsFallback() {
|
||||||
return SmsDatabase.Types.isPendingApprovalType(type);
|
return SmsDatabase.Types.isPendingSmsFallbackType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPendingSecureSmsFallback() {
|
||||||
|
return SmsDatabase.Types.isPendingSecureSmsFallbackType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPendingInsecureSmsFallback() {
|
||||||
|
return SmsDatabase.Types.isPendingInsecureSmsFallbackType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBundleKeyExchange() {
|
public boolean isBundleKeyExchange() {
|
||||||
|
@ -31,11 +31,12 @@ 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.transport.InsecureFallbackApprovalException;
|
||||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||||
|
import org.thoughtcrime.securesms.transport.SecureFallbackApprovalException;
|
||||||
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.thoughtcrime.securesms.transport.UserInterventionRequiredException;
|
|
||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
|
|
||||||
import ws.com.google.android.mms.MmsException;
|
import ws.com.google.android.mms.MmsException;
|
||||||
@ -84,16 +85,18 @@ public class MmsSender {
|
|||||||
result.getResponseStatus());
|
result.getResponseStatus());
|
||||||
|
|
||||||
systemStateListener.unregisterForConnectivityChange();
|
systemStateListener.unregisterForConnectivityChange();
|
||||||
} catch (UserInterventionRequiredException uire) {
|
} catch (InsecureFallbackApprovalException ifae) {
|
||||||
Log.w("MmsSender", uire);
|
Log.w("MmsSender", ifae);
|
||||||
database.markAsPendingApproval(message.getDatabaseMessageId());
|
database.markAsPendingInsecureSmsFallback(message.getDatabaseMessageId());
|
||||||
Recipients recipients = threads.getRecipientsForThreadId(threadId);
|
notifyMessageDeliveryFailed(context, threads, threadId);
|
||||||
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
} catch (SecureFallbackApprovalException sfae) {
|
||||||
|
Log.w("MmsSender", sfae);
|
||||||
|
database.markAsPendingSecureSmsFallback(message.getDatabaseMessageId());
|
||||||
|
notifyMessageDeliveryFailed(context, threads, threadId);
|
||||||
} catch (UndeliverableMessageException e) {
|
} catch (UndeliverableMessageException e) {
|
||||||
Log.w("MmsSender", e);
|
Log.w("MmsSender", e);
|
||||||
database.markAsSentFailed(message.getDatabaseMessageId());
|
database.markAsSentFailed(message.getDatabaseMessageId());
|
||||||
Recipients recipients = threads.getRecipientsForThreadId(threadId);
|
notifyMessageDeliveryFailed(context, threads, threadId);
|
||||||
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
|
||||||
} catch (UntrustedIdentityException uie) {
|
} catch (UntrustedIdentityException uie) {
|
||||||
IncomingIdentityUpdateMessage identityUpdateMessage = IncomingIdentityUpdateMessage.createFor(message.getTo()[0].getString(), uie.getIdentityKey());
|
IncomingIdentityUpdateMessage identityUpdateMessage = IncomingIdentityUpdateMessage.createFor(message.getTo()[0].getString(), uie.getIdentityKey());
|
||||||
DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageInbox(masterSecret, identityUpdateMessage);
|
DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageInbox(masterSecret, identityUpdateMessage);
|
||||||
@ -117,6 +120,11 @@ public class MmsSender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void notifyMessageDeliveryFailed(Context context, ThreadDatabase threads, long threadId) {
|
||||||
|
Recipients recipients = threads.getRecipientsForThreadId(threadId);
|
||||||
|
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
||||||
|
}
|
||||||
|
|
||||||
private void scheduleQuickRetryAlarm() {
|
private void scheduleQuickRetryAlarm() {
|
||||||
((AlarmManager)context.getSystemService(Context.ALARM_SERVICE))
|
((AlarmManager)context.getSystemService(Context.ALARM_SERVICE))
|
||||||
.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (30 * 1000),
|
.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (30 * 1000),
|
||||||
|
@ -36,12 +36,12 @@ 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.transport.InsecureFallbackApprovalException;
|
||||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||||
|
import org.thoughtcrime.securesms.transport.SecureFallbackApprovalException;
|
||||||
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.thoughtcrime.securesms.transport.UserInterventionRequiredException;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
import org.whispersystems.textsecure.storage.Session;
|
import org.whispersystems.textsecure.storage.Session;
|
||||||
|
|
||||||
@ -86,9 +86,13 @@ public class SmsSender {
|
|||||||
database.markAsSending(record.getId());
|
database.markAsSending(record.getId());
|
||||||
|
|
||||||
transport.deliver(record);
|
transport.deliver(record);
|
||||||
} catch (UserInterventionRequiredException uire) {
|
} catch (InsecureFallbackApprovalException ifae) {
|
||||||
Log.w("SmsSender", uire);
|
Log.w("SmsSender", ifae);
|
||||||
DatabaseFactory.getSmsDatabase(context).markAsPendingApproval(record.getId());
|
DatabaseFactory.getSmsDatabase(context).markAsPendingInsecureSmsFallback(record.getId());
|
||||||
|
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
|
||||||
|
} catch (SecureFallbackApprovalException sfae) {
|
||||||
|
Log.w("SmsSender", sfae);
|
||||||
|
DatabaseFactory.getSmsDatabase(context).markAsPendingSecureSmsFallback(record.getId());
|
||||||
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
|
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
|
||||||
} catch (UntrustedIdentityException e) {
|
} catch (UntrustedIdentityException e) {
|
||||||
Log.w("SmsSender", e);
|
Log.w("SmsSender", e);
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package org.thoughtcrime.securesms.transport;
|
||||||
|
|
||||||
|
public class InsecureFallbackApprovalException extends Exception {
|
||||||
|
public InsecureFallbackApprovalException(String detailMessage) {
|
||||||
|
super(detailMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -36,6 +36,7 @@ import org.whispersystems.textsecure.crypto.MasterSecret;
|
|||||||
import org.whispersystems.textsecure.crypto.SessionCipher;
|
import org.whispersystems.textsecure.crypto.SessionCipher;
|
||||||
import org.whispersystems.textsecure.crypto.protocol.CiphertextMessage;
|
import org.whispersystems.textsecure.crypto.protocol.CiphertextMessage;
|
||||||
import org.whispersystems.textsecure.storage.RecipientDevice;
|
import org.whispersystems.textsecure.storage.RecipientDevice;
|
||||||
|
import org.whispersystems.textsecure.storage.Session;
|
||||||
import org.whispersystems.textsecure.util.Hex;
|
import org.whispersystems.textsecure.util.Hex;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -62,7 +63,9 @@ public class MmsTransport {
|
|||||||
this.radio = MmsRadio.getInstance(context);
|
this.radio = MmsRadio.getInstance(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MmsSendResult deliver(SendReq message) throws UndeliverableMessageException {
|
public MmsSendResult deliver(SendReq message) throws UndeliverableMessageException,
|
||||||
|
InsecureFallbackApprovalException
|
||||||
|
{
|
||||||
if (TextSecurePreferences.isPushRegistered(context) &&
|
if (TextSecurePreferences.isPushRegistered(context) &&
|
||||||
!TextSecurePreferences.isSmsFallbackEnabled(context))
|
!TextSecurePreferences.isSmsFallbackEnabled(context))
|
||||||
{
|
{
|
||||||
@ -109,7 +112,7 @@ public class MmsTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MmsSendResult sendMms(SendReq message, boolean usingMmsRadio, boolean useProxy)
|
private MmsSendResult sendMms(SendReq message, boolean usingMmsRadio, boolean useProxy)
|
||||||
throws IOException, UndeliverableMessageException
|
throws IOException, UndeliverableMessageException, InsecureFallbackApprovalException
|
||||||
{
|
{
|
||||||
String number = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number();
|
String number = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number();
|
||||||
boolean upgradedSecure = false;
|
boolean upgradedSecure = false;
|
||||||
@ -141,7 +144,7 @@ public class MmsTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendReq getEncryptedMessage(SendReq pdu) {
|
private SendReq getEncryptedMessage(SendReq pdu) throws InsecureFallbackApprovalException {
|
||||||
EncodedStringValue[] encodedRecipient = pdu.getTo();
|
EncodedStringValue[] encodedRecipient = pdu.getTo();
|
||||||
String recipient = encodedRecipient[0].getString();
|
String recipient = encodedRecipient[0].getString();
|
||||||
byte[] pduBytes = new PduComposer(context, pdu).make();
|
byte[] pduBytes = new PduComposer(context, pdu).make();
|
||||||
@ -162,11 +165,16 @@ public class MmsTransport {
|
|||||||
return encryptedPdu;
|
return encryptedPdu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getEncryptedPdu(MasterSecret masterSecret, String recipientString, byte[] pduBytes) {
|
private byte[] getEncryptedPdu(MasterSecret masterSecret, String recipientString, byte[] pduBytes) throws InsecureFallbackApprovalException {
|
||||||
try {
|
try {
|
||||||
TextTransport transportDetails = new TextTransport();
|
TextTransport transportDetails = new TextTransport();
|
||||||
Recipient recipient = RecipientFactory.getRecipientsFromString(context, recipientString, false).getPrimaryRecipient();
|
Recipient recipient = RecipientFactory.getRecipientsFromString(context, recipientString, false).getPrimaryRecipient();
|
||||||
RecipientDevice recipientDevice = new RecipientDevice(recipient.getRecipientId(), RecipientDevice.DEFAULT_DEVICE_ID);
|
RecipientDevice recipientDevice = new RecipientDevice(recipient.getRecipientId(), RecipientDevice.DEFAULT_DEVICE_ID);
|
||||||
|
|
||||||
|
if (!Session.hasEncryptCapableSession(context, masterSecret, recipient, recipientDevice)) {
|
||||||
|
throw new InsecureFallbackApprovalException("No session exists for this secure message.");
|
||||||
|
}
|
||||||
|
|
||||||
SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipientDevice);
|
SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipientDevice);
|
||||||
CiphertextMessage ciphertextMessage = sessionCipher.encrypt(pduBytes);
|
CiphertextMessage ciphertextMessage = sessionCipher.encrypt(pduBytes);
|
||||||
|
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package org.thoughtcrime.securesms.transport;
|
||||||
|
|
||||||
|
public class SecureFallbackApprovalException extends Exception {
|
||||||
|
public SecureFallbackApprovalException(String detailMessage) {
|
||||||
|
super(detailMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,7 @@ import org.whispersystems.textsecure.crypto.MasterSecret;
|
|||||||
import org.whispersystems.textsecure.crypto.SessionCipher;
|
import org.whispersystems.textsecure.crypto.SessionCipher;
|
||||||
import org.whispersystems.textsecure.crypto.protocol.CiphertextMessage;
|
import org.whispersystems.textsecure.crypto.protocol.CiphertextMessage;
|
||||||
import org.whispersystems.textsecure.storage.RecipientDevice;
|
import org.whispersystems.textsecure.storage.RecipientDevice;
|
||||||
|
import org.whispersystems.textsecure.storage.Session;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -46,7 +47,9 @@ public class SmsTransport extends BaseTransport {
|
|||||||
this.masterSecret = masterSecret;
|
this.masterSecret = masterSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deliver(SmsMessageRecord message) throws UndeliverableMessageException {
|
public void deliver(SmsMessageRecord message) throws UndeliverableMessageException,
|
||||||
|
InsecureFallbackApprovalException
|
||||||
|
{
|
||||||
if (!TextSecurePreferences.isSmsNonDataOutEnabled(context) && !TextSecurePreferences.isSmsFallbackEnabled(context)) {
|
if (!TextSecurePreferences.isSmsNonDataOutEnabled(context) && !TextSecurePreferences.isSmsFallbackEnabled(context)) {
|
||||||
throw new UndeliverableMessageException("SMS Transport is not enabled!");
|
throw new UndeliverableMessageException("SMS Transport is not enabled!");
|
||||||
}
|
}
|
||||||
@ -58,7 +61,9 @@ public class SmsTransport extends BaseTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deliverSecureMessage(SmsMessageRecord message) throws UndeliverableMessageException {
|
private void deliverSecureMessage(SmsMessageRecord message) throws UndeliverableMessageException,
|
||||||
|
InsecureFallbackApprovalException
|
||||||
|
{
|
||||||
MultipartSmsMessageHandler multipartMessageHandler = new MultipartSmsMessageHandler();
|
MultipartSmsMessageHandler multipartMessageHandler = new MultipartSmsMessageHandler();
|
||||||
OutgoingTextMessage transportMessage = OutgoingTextMessage.from(message);
|
OutgoingTextMessage transportMessage = OutgoingTextMessage.from(message);
|
||||||
|
|
||||||
@ -161,9 +166,16 @@ public class SmsTransport extends BaseTransport {
|
|||||||
|
|
||||||
private OutgoingTextMessage getAsymmetricEncrypt(MasterSecret masterSecret,
|
private OutgoingTextMessage getAsymmetricEncrypt(MasterSecret masterSecret,
|
||||||
OutgoingTextMessage message)
|
OutgoingTextMessage message)
|
||||||
|
throws InsecureFallbackApprovalException
|
||||||
{
|
{
|
||||||
Recipient recipient = message.getRecipients().getPrimaryRecipient();
|
Recipient recipient = message.getRecipients().getPrimaryRecipient();
|
||||||
RecipientDevice recipientDevice = new RecipientDevice(recipient.getRecipientId(), RecipientDevice.DEFAULT_DEVICE_ID);
|
RecipientDevice recipientDevice = new RecipientDevice(recipient.getRecipientId(),
|
||||||
|
RecipientDevice.DEFAULT_DEVICE_ID);
|
||||||
|
|
||||||
|
if (!Session.hasEncryptCapableSession(context, masterSecret, recipient, recipientDevice)) {
|
||||||
|
throw new InsecureFallbackApprovalException("No session exists for this secure message.");
|
||||||
|
}
|
||||||
|
|
||||||
String body = message.getMessageBody();
|
String body = message.getMessageBody();
|
||||||
SmsTransportDetails transportDetails = new SmsTransportDetails();
|
SmsTransportDetails transportDetails = new SmsTransportDetails();
|
||||||
SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipientDevice);
|
SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipientDevice);
|
||||||
|
@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
|||||||
import org.thoughtcrime.securesms.mms.MmsSendResult;
|
import org.thoughtcrime.securesms.mms.MmsSendResult;
|
||||||
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
|
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||||
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
||||||
import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage;
|
import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage;
|
||||||
@ -36,6 +37,7 @@ import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
|||||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||||
import org.whispersystems.textsecure.push.UnregisteredUserException;
|
import org.whispersystems.textsecure.push.UnregisteredUserException;
|
||||||
|
import org.whispersystems.textsecure.storage.Session;
|
||||||
import org.whispersystems.textsecure.util.DirectoryUtil;
|
import org.whispersystems.textsecure.util.DirectoryUtil;
|
||||||
import org.whispersystems.textsecure.util.InvalidNumberException;
|
import org.whispersystems.textsecure.util.InvalidNumberException;
|
||||||
|
|
||||||
@ -60,7 +62,8 @@ public class UniversalTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deliver(SmsMessageRecord message)
|
public void deliver(SmsMessageRecord message)
|
||||||
throws UndeliverableMessageException, UntrustedIdentityException, RetryLaterException, UserInterventionRequiredException
|
throws UndeliverableMessageException, UntrustedIdentityException, RetryLaterException,
|
||||||
|
SecureFallbackApprovalException, InsecureFallbackApprovalException
|
||||||
{
|
{
|
||||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||||
smsTransport.deliver(message);
|
smsTransport.deliver(message);
|
||||||
@ -99,7 +102,8 @@ public class UniversalTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public MmsSendResult deliver(SendReq mediaMessage, long threadId)
|
public MmsSendResult deliver(SendReq mediaMessage, long threadId)
|
||||||
throws UndeliverableMessageException, RetryLaterException, UntrustedIdentityException, UserInterventionRequiredException
|
throws UndeliverableMessageException, RetryLaterException, UntrustedIdentityException,
|
||||||
|
SecureFallbackApprovalException, InsecureFallbackApprovalException
|
||||||
{
|
{
|
||||||
if (Util.isEmpty(mediaMessage.getTo())) {
|
if (Util.isEmpty(mediaMessage.getTo())) {
|
||||||
return mmsTransport.deliver(mediaMessage);
|
return mmsTransport.deliver(mediaMessage);
|
||||||
@ -155,28 +159,42 @@ public class UniversalTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MmsSendResult fallbackOrAskApproval(SendReq mediaMessage, String destination)
|
private MmsSendResult fallbackOrAskApproval(SendReq mediaMessage, String destination)
|
||||||
throws UserInterventionRequiredException, UndeliverableMessageException
|
throws SecureFallbackApprovalException, UndeliverableMessageException, InsecureFallbackApprovalException
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
Recipient recipient = RecipientFactory.getRecipientsFromString(context, destination, false).getPrimaryRecipient();
|
||||||
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination);
|
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination);
|
||||||
|
|
||||||
if (!isSmsFallbackApprovalRequired) {
|
if (!isSmsFallbackApprovalRequired) {
|
||||||
Log.i("UniversalTransport", "Falling back to MMS without user intervention");
|
Log.w("UniversalTransport", "Falling back to MMS");
|
||||||
return mmsTransport.deliver(mediaMessage);
|
return mmsTransport.deliver(mediaMessage);
|
||||||
|
} else if (!Session.hasEncryptCapableSession(context, masterSecret, recipient)) {
|
||||||
|
Log.w("UniversalTransport", "Marking message as pending insecure SMS fallback");
|
||||||
|
throw new InsecureFallbackApprovalException("Pending user approval for fallback to insecure SMS");
|
||||||
} else {
|
} else {
|
||||||
Log.i("UniversalTransport", "Marking message as pending user approval per their settings");
|
Log.w("UniversalTransport", "Marking message as pending secure SMS fallback");
|
||||||
throw new UserInterventionRequiredException("Pending user approval for fallback to SMS");
|
throw new SecureFallbackApprovalException("Pending user approval for fallback secure to SMS");
|
||||||
|
}
|
||||||
|
} catch (RecipientFormattingException rfe) {
|
||||||
|
throw new UndeliverableMessageException(rfe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fallbackOrAskApproval(SmsMessageRecord smsMessage, String destination)
|
private void fallbackOrAskApproval(SmsMessageRecord smsMessage, String destination)
|
||||||
throws UserInterventionRequiredException, UndeliverableMessageException
|
throws SecureFallbackApprovalException, UndeliverableMessageException, InsecureFallbackApprovalException
|
||||||
{
|
{
|
||||||
|
Recipient recipient = smsMessage.getIndividualRecipient();
|
||||||
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination);
|
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination);
|
||||||
|
|
||||||
if (!isSmsFallbackApprovalRequired) {
|
if (!isSmsFallbackApprovalRequired) {
|
||||||
Log.i("UniversalTransport", "Falling back to SMS without user intervention");
|
Log.w("UniversalTransport", "Falling back to SMS");
|
||||||
smsTransport.deliver(smsMessage);
|
smsTransport.deliver(smsMessage);
|
||||||
|
} else if (!Session.hasEncryptCapableSession(context, masterSecret, recipient)) {
|
||||||
|
Log.w("UniversalTransport", "Marking message as pending insecure fallback.");
|
||||||
|
throw new InsecureFallbackApprovalException("Pending user approval for fallback to insecure SMS");
|
||||||
} else {
|
} else {
|
||||||
Log.i("UniversalTransport", "Marking message as pending user approval per their settings");
|
Log.w("UniversalTransport", "Marking message as pending secure fallback.");
|
||||||
throw new UserInterventionRequiredException("Pending user approval for fallback to SMS");
|
throw new SecureFallbackApprovalException("Pending user approval for fallback to secure SMS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +236,6 @@ public class UniversalTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isMultipleRecipients(SendReq mediaMessage) {
|
public boolean isMultipleRecipients(SendReq mediaMessage) {
|
||||||
int recipientCount = 0;
|
int recipientCount = 0;
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.transport;
|
|
||||||
|
|
||||||
public class UserInterventionRequiredException extends Exception {
|
|
||||||
public UserInterventionRequiredException(String detailMessage) {
|
|
||||||
super(detailMessage);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user