diff --git a/res/menu/conversation_button_context.xml b/res/menu/conversation_button_context.xml
deleted file mode 100644
index d6929404a7..0000000000
--- a/res/menu/conversation_button_context.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
diff --git a/res/menu/conversation_button_context_insecure_push.xml b/res/menu/conversation_button_context_insecure_push.xml
new file mode 100644
index 0000000000..81dcf7419b
--- /dev/null
+++ b/res/menu/conversation_button_context_insecure_push.xml
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/res/menu/conversation_button_context_secure_push.xml b/res/menu/conversation_button_context_secure_push.xml
new file mode 100644
index 0000000000..7c60057cf2
--- /dev/null
+++ b/res/menu/conversation_button_context_secure_push.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/res/menu/conversation_button_context_secure_sms.xml b/res/menu/conversation_button_context_secure_sms.xml
new file mode 100644
index 0000000000..457505e7bd
--- /dev/null
+++ b/res/menu/conversation_button_context_secure_sms.xml
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 185e16f392..0a37494291 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -781,7 +781,9 @@
Refresh contact list
- Send unencrypted
+ Send TextSecure message
+ Send unencrypted SMS
+ Send encrypted SMS
Call
@@ -841,6 +843,7 @@
Verified
+
diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java
index b3b06986ee..072bf79497 100644
--- a/src/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationActivity.java
@@ -193,7 +193,6 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
@Override
protected void onResume() {
-
super.onResume();
dynamicTheme.onResume(this);
dynamicLanguage.onResume(this);
@@ -312,16 +311,28 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
- if (isEncryptedConversation) {
- android.view.MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.conversation_button_context, menu);
+ if (isEncryptedConversation && isSingleConversation()) {
+ boolean isPushDestination = DirectoryHelper.isPushDestination(this, getRecipients());
+ Recipient primaryRecipient = getRecipients() == null ? null : getRecipients().getPrimaryRecipient();
+ boolean hasSession = Session.hasSession(this, masterSecret, primaryRecipient);
+
+ int context;
+
+ if (isPushDestination && hasSession) context = R.menu.conversation_button_context_secure_push;
+ else if (isPushDestination) context = R.menu.conversation_button_context_insecure_push;
+ else if (hasSession) context = R.menu.conversation_button_context_secure_sms;
+ else return;
+
+ getMenuInflater().inflate(context, menu);
}
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
switch (item.getItemId()) {
- case R.id.menu_context_send_unencrypted: sendMessage(true); return true;
+ case R.id.menu_context_send_push: sendMessage(false, false); return true;
+ case R.id.menu_context_send_encrypted_sms: sendMessage(false, true); return true;
+ case R.id.menu_context_send_unencrypted_sms: sendMessage(true, true); return true;
}
return false;
@@ -402,7 +413,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
new OutgoingEndSessionMessage(new OutgoingTextMessage(getRecipients(), "TERMINATE"));
long allocatedThreadId = MessageSender.send(self, masterSecret,
- endSessionMessage, threadId);
+ endSessionMessage, threadId, false);
sendComplete(recipients, allocatedThreadId, allocatedThreadId != self.threadId);
} else {
@@ -444,7 +455,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(self, getRecipients(),
context, null);
- MessageSender.send(self, masterSecret, outgoingMessage, threadId);
+ MessageSender.send(self, masterSecret, outgoingMessage, threadId, false);
DatabaseFactory.getGroupDatabase(self).remove(groupId, TextSecurePreferences.getLocalNumber(self));
initializeEnabledCheck();
} catch (IOException e) {
@@ -1009,45 +1020,22 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
fragment.scrollToBottom();
}
- private void sendMessage(boolean forcePlaintext) {
+ private void sendMessage(boolean forcePlaintext, boolean forceSms) {
try {
Recipients recipients = getRecipients();
if (recipients == null)
throw new RecipientFormattingException("Badly formatted");
- String body = getMessage();
long allocatedThreadId;
if ((!recipients.isSingleRecipient() || recipients.isEmailRecipient()) && !isMmsEnabled) {
handleManualMmsRequired();
return;
} else if (attachmentManager.isAttachmentPresent() || !recipients.isSingleRecipient() || recipients.isGroupRecipient() || recipients.isEmailRecipient()) {
- SlideDeck slideDeck;
-
- if (attachmentManager.isAttachmentPresent()) slideDeck = attachmentManager.getSlideDeck();
- else slideDeck = new SlideDeck();
-
- OutgoingMediaMessage outgoingMessage = new OutgoingMediaMessage(this, recipients, slideDeck,
- body, distributionType);
-
- if (isEncryptedConversation && !forcePlaintext) {
- outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessage);
- }
-
- allocatedThreadId = MessageSender.send(this, masterSecret, outgoingMessage, threadId);
+ allocatedThreadId = sendMediaMessage(forcePlaintext, forceSms);
} else {
- OutgoingTextMessage message;
-
- if (isEncryptedConversation && !forcePlaintext) {
- message = new OutgoingEncryptedMessage(recipients, body);
- } else {
- message = new OutgoingTextMessage(recipients, body);
- }
-
- Log.w(TAG, "Sending message...");
- allocatedThreadId = MessageSender.send(ConversationActivity.this, masterSecret,
- message, threadId);
+ allocatedThreadId = sendTextMessage(forcePlaintext, forceSms);
}
sendComplete(recipients, allocatedThreadId, allocatedThreadId != this.threadId);
@@ -1065,6 +1053,41 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
}
}
+ private long sendMediaMessage(boolean forcePlaintext, boolean forceSms)
+ throws InvalidMessageException, MmsException
+ {
+ SlideDeck slideDeck;
+
+ if (attachmentManager.isAttachmentPresent()) slideDeck = attachmentManager.getSlideDeck();
+ else slideDeck = new SlideDeck();
+
+ OutgoingMediaMessage outgoingMessage = new OutgoingMediaMessage(this, recipients, slideDeck,
+ getMessage(), distributionType);
+
+ if (isEncryptedConversation && !forcePlaintext) {
+ outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessage);
+ }
+
+ return MessageSender.send(this, masterSecret, outgoingMessage, threadId, forceSms);
+ }
+
+ private long sendTextMessage(boolean forcePlaintext, boolean forceSms)
+ throws InvalidMessageException
+ {
+ OutgoingTextMessage message;
+
+ if (isEncryptedConversation && !forcePlaintext) {
+ message = new OutgoingEncryptedMessage(recipients, getMessage());
+ } else {
+ message = new OutgoingTextMessage(recipients, getMessage());
+ }
+
+ Log.w(TAG, "Sending message...");
+
+ return MessageSender.send(ConversationActivity.this, masterSecret, message, threadId, forceSms);
+ }
+
+
// Listeners
private class AttachmentTypeListener implements DialogInterface.OnClickListener {
@@ -1092,7 +1115,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private class SendButtonListener implements OnClickListener, TextView.OnEditorActionListener {
@Override
public void onClick(View v) {
- sendMessage(false);
+ sendMessage(false, false);
}
@Override
diff --git a/src/org/thoughtcrime/securesms/GroupCreateActivity.java b/src/org/thoughtcrime/securesms/GroupCreateActivity.java
index ebd8ded7ad..68de5474c7 100644
--- a/src/org/thoughtcrime/securesms/GroupCreateActivity.java
+++ b/src/org/thoughtcrime/securesms/GroupCreateActivity.java
@@ -459,7 +459,7 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
.build();
OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(this, groupRecipient, context, avatar);
- long threadId = MessageSender.send(this, masterSecret, outgoingMessage, -1);
+ long threadId = MessageSender.send(this, masterSecret, outgoingMessage, -1, false);
return new Pair(threadId, groupRecipient);
} catch (RecipientFormattingException e) {
diff --git a/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java b/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java
index 679030cdce..6921f05e6d 100644
--- a/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java
+++ b/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java
@@ -77,7 +77,7 @@ public class KeyExchangeInitiator {
sessionRecordV2.getSessionState().setPendingKeyExchange(sequence, baseKey, ephemeralKey, identityKey);
sessionRecordV2.save();
- MessageSender.send(context, masterSecret, textMessage, -1);
+ MessageSender.send(context, masterSecret, textMessage, -1, false);
}
private static boolean hasInitiatedSession(Context context, MasterSecret masterSecret,
diff --git a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java
index ce501e5c78..e8bae08205 100644
--- a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java
+++ b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java
@@ -206,7 +206,7 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor {
OutgoingKeyExchangeMessage textMessage = new OutgoingKeyExchangeMessage(recipient,
ourMessage.serialize());
- MessageSender.send(context, masterSecret, textMessage, threadId);
+ MessageSender.send(context, masterSecret, textMessage, threadId, false);
}
if (message.getSequence() != sessionRecord.getSessionState().getPendingKeyExchangeSequence()) {
diff --git a/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java b/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java
index ab65267565..b566f54d28 100644
--- a/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java
@@ -59,13 +59,13 @@ public class EncryptingSmsDatabase extends SmsDatabase {
}
public List insertMessageOutbox(MasterSecret masterSecret, long threadId,
- OutgoingTextMessage message)
+ OutgoingTextMessage message, boolean forceSms)
{
long type = Types.BASE_OUTBOX_TYPE;
message = message.withBody(getEncryptedBody(masterSecret, message.getMessageBody()));
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
- return insertMessageOutbox(threadId, message, type);
+ return insertMessageOutbox(threadId, message, type, forceSms);
}
public Pair insertMessageInbox(MasterSecret masterSecret,
diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java
index 3d4a398414..fed8abb753 100644
--- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java
@@ -572,14 +572,14 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
Trimmer.trimThread(context, threadId);
}
- public long insertMessageOutbox(MasterSecret masterSecret, OutgoingMediaMessage message, long threadId)
+ public long insertMessageOutbox(MasterSecret masterSecret, OutgoingMediaMessage message,
+ long threadId, boolean forceSms)
throws MmsException
{
long type = Types.BASE_OUTBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT;
- if (message.isSecure()) {
- type |= Types.SECURE_MESSAGE_BIT;
- }
+ if (message.isSecure()) type |= Types.SECURE_MESSAGE_BIT;
+ if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT;
if (message.isGroup()) {
if (((OutgoingGroupMediaMessage)message).isGroupUpdate()) type |= Types.GROUP_UPDATE_BIT;
diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
index b57bbb3c71..e4cf49ba38 100644
--- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
@@ -362,10 +362,13 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
return insertMessageInbox(message, Types.BASE_INBOX_TYPE);
}
- protected List insertMessageOutbox(long threadId, OutgoingTextMessage message, long type) {
+ protected List insertMessageOutbox(long threadId, OutgoingTextMessage message,
+ long type, boolean forceSms)
+ {
if (message.isKeyExchange()) type |= Types.KEY_EXCHANGE_BIT;
else if (message.isSecureMessage()) type |= Types.SECURE_MESSAGE_BIT;
else if (message.isEndSession()) type |= Types.END_SESSION_BIT;
+ if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT;
long date = System.currentTimeMillis();
List messageIds = new LinkedList();
diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java
index 09b89147e8..b9ccf36540 100644
--- a/src/org/thoughtcrime/securesms/sms/MessageSender.java
+++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java
@@ -32,14 +32,14 @@ import ws.com.google.android.mms.MmsException;
public class MessageSender {
public static long send(Context context, MasterSecret masterSecret,
- OutgoingTextMessage message, long threadId)
+ OutgoingTextMessage message, long threadId,
+ boolean forceSms)
{
if (threadId == -1)
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(message.getRecipients());
List messageIds = DatabaseFactory.getEncryptingSmsDatabase(context)
- .insertMessageOutbox(masterSecret, threadId, message);
-
+ .insertMessageOutbox(masterSecret, threadId, message, forceSms);
for (long messageId : messageIds) {
Log.w("SMSSender", "Got message id for new message: " + messageId);
@@ -53,14 +53,16 @@ public class MessageSender {
return threadId;
}
- public static long send(Context context, MasterSecret masterSecret, OutgoingMediaMessage message, long threadId)
+ public static long send(Context context, MasterSecret masterSecret,
+ OutgoingMediaMessage message,
+ long threadId, boolean forceSms)
throws MmsException
{
if (threadId == -1)
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(message.getRecipients(), message.getDistributionType());
long messageId = DatabaseFactory.getMmsDatabase(context)
- .insertMessageOutbox(masterSecret, message, threadId);
+ .insertMessageOutbox(masterSecret, message, threadId, forceSms);
Intent intent = new Intent(SendReceiveService.SEND_MMS_ACTION, null,
context, SendReceiveService.class);