|
|
|
@ -23,7 +23,6 @@ import android.content.Context;
|
|
|
|
|
import android.content.DialogInterface;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.content.IntentFilter;
|
|
|
|
|
import android.content.res.TypedArray;
|
|
|
|
|
import android.graphics.Bitmap;
|
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
|
|
|
import android.net.Uri;
|
|
|
|
@ -34,18 +33,15 @@ import android.provider.ContactsContract;
|
|
|
|
|
import android.telephony.PhoneNumberUtils;
|
|
|
|
|
import android.text.Editable;
|
|
|
|
|
import android.text.InputType;
|
|
|
|
|
import android.text.Spannable;
|
|
|
|
|
import android.text.SpannableString;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
import android.text.TextWatcher;
|
|
|
|
|
import android.text.style.RelativeSizeSpan;
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
import android.view.ContextMenu;
|
|
|
|
|
import android.view.ContextThemeWrapper;
|
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
|
import android.view.Menu;
|
|
|
|
|
import android.view.MenuInflater;
|
|
|
|
|
import android.view.MenuItem;
|
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
|
import android.view.View;
|
|
|
|
|
import android.view.View.OnClickListener;
|
|
|
|
|
import android.view.View.OnFocusChangeListener;
|
|
|
|
@ -53,7 +49,6 @@ import android.view.View.OnKeyListener;
|
|
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
|
|
import android.view.inputmethod.InputMethodManager;
|
|
|
|
|
import android.widget.EditText;
|
|
|
|
|
import android.widget.ImageButton;
|
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
|
@ -61,6 +56,7 @@ import com.google.protobuf.ByteString;
|
|
|
|
|
|
|
|
|
|
import org.thoughtcrime.securesms.components.EmojiDrawer;
|
|
|
|
|
import org.thoughtcrime.securesms.components.EmojiToggle;
|
|
|
|
|
import org.thoughtcrime.securesms.components.SendButton;
|
|
|
|
|
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
|
|
|
|
import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
|
|
|
|
|
import org.thoughtcrime.securesms.crypto.KeyExchangeInitiator;
|
|
|
|
@ -113,6 +109,7 @@ import org.whispersystems.libaxolotl.state.SessionStore;
|
|
|
|
|
import org.whispersystems.textsecure.api.push.PushAddress;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.LinkedList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
|
|
|
@ -147,14 +144,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
private static final int PICK_CONTACT_INFO = 4;
|
|
|
|
|
private static final int GROUP_EDIT = 5;
|
|
|
|
|
|
|
|
|
|
private static final int SEND_ATTRIBUTES[] = new int[]{R.attr.conversation_send_button_push,
|
|
|
|
|
R.attr.conversation_send_button_sms_secure,
|
|
|
|
|
R.attr.conversation_send_button_sms_insecure};
|
|
|
|
|
|
|
|
|
|
private MasterSecret masterSecret;
|
|
|
|
|
private EditText composeText;
|
|
|
|
|
private ImageButton sendButton;
|
|
|
|
|
private TextView charactersLeft;
|
|
|
|
|
private MasterSecret masterSecret;
|
|
|
|
|
private EditText composeText;
|
|
|
|
|
private SendButton sendButton;
|
|
|
|
|
private TextView charactersLeft;
|
|
|
|
|
|
|
|
|
|
private AttachmentTypeSelectorAdapter attachmentAdapter;
|
|
|
|
|
private AttachmentManager attachmentManager;
|
|
|
|
@ -317,49 +310,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
|
|
|
|
if (isEncryptedConversation && isSingleConversation()) {
|
|
|
|
|
SessionStore sessionStore = new TextSecureSessionStore(this, masterSecret);
|
|
|
|
|
Recipient primaryRecipient = getRecipients() == null ? null : getRecipients().getPrimaryRecipient();
|
|
|
|
|
boolean isPushDestination = DirectoryHelper.isPushDestination(this, getRecipients());
|
|
|
|
|
boolean isSecureDestination = isSingleConversation() && sessionStore.containsSession(primaryRecipient.getRecipientId(),
|
|
|
|
|
PushAddress.DEFAULT_DEVICE_ID);
|
|
|
|
|
|
|
|
|
|
getMenuInflater().inflate(R.menu.conversation_button_context, menu);
|
|
|
|
|
|
|
|
|
|
if (attachmentManager.isAttachmentPresent()) {
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_encrypted_sms);
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_unencrypted_sms);
|
|
|
|
|
} else {
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_encrypted_mms);
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_unencrypted_mms);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isPushDestination) {
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_push);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isSecureDestination) {
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_encrypted_mms);
|
|
|
|
|
menu.removeItem(R.id.menu_context_send_encrypted_sms);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onContextItemSelected(android.view.MenuItem item) {
|
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
|
case R.id.menu_context_send_push: sendMessage(false, false); return true;
|
|
|
|
|
case R.id.menu_context_send_encrypted_mms:
|
|
|
|
|
case R.id.menu_context_send_encrypted_sms: sendMessage(false, true); return true;
|
|
|
|
|
case R.id.menu_context_send_unencrypted_mms:
|
|
|
|
|
case R.id.menu_context_send_unencrypted_sms: sendMessage(true, true); return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onBackPressed() {
|
|
|
|
|
if (emojiDrawer.getVisibility() == View.VISIBLE) {
|
|
|
|
@ -700,7 +650,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeSecurity() {
|
|
|
|
|
TypedArray drawables = obtainStyledAttributes(SEND_ATTRIBUTES);
|
|
|
|
|
SessionStore sessionStore = new TextSecureSessionStore(this, masterSecret);
|
|
|
|
|
Recipient primaryRecipient = getRecipients() == null ? null : getRecipients().getPrimaryRecipient();
|
|
|
|
|
boolean isPushDestination = DirectoryHelper.isPushDestination(this, getRecipients());
|
|
|
|
@ -715,27 +664,21 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
this.characterCalculator = new CharacterCalculator();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sendButton.initializeAvailableTransports(!recipients.isSingleRecipient() || attachmentManager.isAttachmentPresent());
|
|
|
|
|
if (!isPushDestination ) sendButton.disableTransport("textsecure");
|
|
|
|
|
if (!isSecureDestination) sendButton.disableTransport("secure_sms");
|
|
|
|
|
|
|
|
|
|
if (isPushDestination) {
|
|
|
|
|
sendButton.setImageDrawable(drawables.getDrawable(0));
|
|
|
|
|
setComposeHint(getString(R.string.conversation_activity__type_message_push));
|
|
|
|
|
sendButton.setDefaultTransport("textsecure");
|
|
|
|
|
} else if (isSecureDestination) {
|
|
|
|
|
sendButton.setImageDrawable(drawables.getDrawable(1));
|
|
|
|
|
setComposeHint(attachmentManager.isAttachmentPresent() ?
|
|
|
|
|
getString(R.string.conversation_activity__type_message_mms_secure) :
|
|
|
|
|
getString(R.string.conversation_activity__type_message_sms_secure));
|
|
|
|
|
sendButton.setDefaultTransport("secure_sms");
|
|
|
|
|
} else {
|
|
|
|
|
sendButton.setImageDrawable(drawables.getDrawable(2));
|
|
|
|
|
setComposeHint((attachmentManager.isAttachmentPresent() || !recipients.isSingleRecipient()) ?
|
|
|
|
|
getString(R.string.conversation_activity__type_message_mms_insecure) :
|
|
|
|
|
getString(R.string.conversation_activity__type_message_sms_insecure));
|
|
|
|
|
sendButton.setDefaultTransport("insecure_sms");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drawables.recycle();
|
|
|
|
|
|
|
|
|
|
calculateCharactersRemaining();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void initializeMmsEnabledCheck() {
|
|
|
|
|
new AsyncTask<Void, Void, Boolean>() {
|
|
|
|
|
@Override
|
|
|
|
@ -763,7 +706,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
|
|
|
|
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA,
|
|
|
|
|
ThreadDatabase.DistributionTypes.DEFAULT);
|
|
|
|
|
sendButton = (ImageButton)findViewById(R.id.send_button);
|
|
|
|
|
sendButton = (SendButton)findViewById(R.id.send_button);
|
|
|
|
|
composeText = (EditText)findViewById(R.id.embedded_text_editor);
|
|
|
|
|
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
|
|
|
|
|
charactersLeft = (TextView)findViewById(R.id.space_left);
|
|
|
|
@ -782,6 +725,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
|
|
|
|
|
sendButton.setOnClickListener(sendButtonListener);
|
|
|
|
|
sendButton.setEnabled(true);
|
|
|
|
|
sendButton.setComposeTextView(composeText);
|
|
|
|
|
composeText.setOnKeyListener(composeKeyPressedListener);
|
|
|
|
|
composeText.addTextChangedListener(composeKeyPressedListener);
|
|
|
|
|
composeText.setOnEditorActionListener(sendButtonListener);
|
|
|
|
@ -796,8 +740,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
initializeTitleBar();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
registerForContextMenu(sendButton);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeReceivers() {
|
|
|
|
@ -1056,20 +998,20 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
fragment.scrollToBottom();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void sendMessage(boolean forcePlaintext, boolean forceSms) {
|
|
|
|
|
private void sendMessage() {
|
|
|
|
|
try {
|
|
|
|
|
final Recipients recipients = getRecipients();
|
|
|
|
|
|
|
|
|
|
if (recipients == null)
|
|
|
|
|
if (recipients == null) {
|
|
|
|
|
throw new RecipientFormattingException("Badly formatted");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((!recipients.isSingleRecipient() || recipients.isEmailRecipient()) && !isMmsEnabled) {
|
|
|
|
|
handleManualMmsRequired();
|
|
|
|
|
} else if (attachmentManager.isAttachmentPresent() || !recipients.isSingleRecipient() || recipients.isGroupRecipient() || recipients.isEmailRecipient()) {
|
|
|
|
|
sendMediaMessage(forcePlaintext, forceSms);
|
|
|
|
|
sendMediaMessage(sendButton.getSelectedTransport().isForcedPlaintext(), sendButton.getSelectedTransport().isForcedSms());
|
|
|
|
|
} else {
|
|
|
|
|
sendTextMessage(forcePlaintext, forceSms);
|
|
|
|
|
sendTextMessage(sendButton.getSelectedTransport().isForcedPlaintext(), sendButton.getSelectedTransport().isForcedSms());
|
|
|
|
|
}
|
|
|
|
|
} catch (RecipientFormattingException ex) {
|
|
|
|
|
Toast.makeText(ConversationActivity.this,
|
|
|
|
@ -1171,7 +1113,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
private class SendButtonListener implements OnClickListener, TextView.OnEditorActionListener {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
sendMessage(false, false);
|
|
|
|
|
sendMessage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@ -1239,17 +1181,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
|
this.composeText.setText(text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setComposeHint(String hint){
|
|
|
|
|
if (hint == null) {
|
|
|
|
|
this.composeText.setHint(null);
|
|
|
|
|
} else {
|
|
|
|
|
SpannableString span = new SpannableString(hint);
|
|
|
|
|
span.setSpan(new RelativeSizeSpan(0.8f), 0, hint.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
|
|
|
|
this.composeText.setHint(span);
|
|
|
|
|
this.sendButton.setContentDescription(hint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onAttachmentChanged() {
|
|
|
|
|
initializeSecurity();
|
|
|
|
|