1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Set;
6
7import net.java.otr4j.session.SessionStatus;
8import eu.siacs.conversations.R;
9import eu.siacs.conversations.crypto.PgpEngine;
10import eu.siacs.conversations.entities.Account;
11import eu.siacs.conversations.entities.Contact;
12import eu.siacs.conversations.entities.Conversation;
13import eu.siacs.conversations.entities.Message;
14import eu.siacs.conversations.entities.MucOptions;
15import eu.siacs.conversations.entities.Presences;
16import eu.siacs.conversations.services.XmppConnectionService;
17import eu.siacs.conversations.ui.EditMessage.OnEnterPressed;
18import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected;
19import eu.siacs.conversations.ui.XmppActivity.OnValueEdited;
20import eu.siacs.conversations.ui.adapter.MessageAdapter;
21import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked;
22import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked;
23import eu.siacs.conversations.utils.UIHelper;
24import android.app.AlertDialog;
25import android.app.Fragment;
26import android.app.PendingIntent;
27import android.content.Context;
28import android.content.DialogInterface;
29import android.content.Intent;
30import android.content.IntentSender;
31import android.content.IntentSender.SendIntentException;
32import android.os.Bundle;
33import android.text.Editable;
34import android.text.Selection;
35import android.view.Gravity;
36import android.view.KeyEvent;
37import android.view.LayoutInflater;
38import android.view.View;
39import android.view.View.OnClickListener;
40import android.view.ViewGroup;
41import android.view.inputmethod.EditorInfo;
42import android.view.inputmethod.InputMethodManager;
43import android.widget.AbsListView.OnScrollListener;
44import android.widget.TextView.OnEditorActionListener;
45import android.widget.AbsListView;
46
47import android.widget.ListView;
48import android.widget.ImageButton;
49import android.widget.RelativeLayout;
50import android.widget.TextView;
51import android.widget.Toast;
52
53public class ConversationFragment extends Fragment {
54
55 protected Conversation conversation;
56 protected ListView messagesView;
57 protected LayoutInflater inflater;
58 protected List<Message> messageList = new ArrayList<Message>();
59 protected MessageAdapter messageListAdapter;
60 protected Contact contact;
61
62 protected String queuedPqpMessage = null;
63
64 private EditMessage mEditMessage;
65 private ImageButton mSendButton;
66 private String pastedText = null;
67 private RelativeLayout snackbar;
68 private TextView snackbarMessage;
69 private TextView snackbarAction;
70
71 private boolean messagesLoaded = false;
72
73 private IntentSender askForPassphraseIntent = null;
74
75 private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() {
76
77 @Override
78 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
79 if (actionId == EditorInfo.IME_ACTION_SEND) {
80 InputMethodManager imm = (InputMethodManager) v.getContext()
81 .getSystemService(Context.INPUT_METHOD_SERVICE);
82 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
83 sendMessage();
84 return true;
85 } else {
86 return false;
87 }
88 }
89 };
90
91 private OnClickListener mSendButtonListener = new OnClickListener() {
92
93 @Override
94 public void onClick(View v) {
95 sendMessage();
96 }
97 };
98 protected OnClickListener clickToDecryptListener = new OnClickListener() {
99
100 @Override
101 public void onClick(View v) {
102 if (activity.hasPgp() && askForPassphraseIntent != null) {
103 try {
104 getActivity().startIntentSenderForResult(
105 askForPassphraseIntent,
106 ConversationActivity.REQUEST_DECRYPT_PGP, null, 0,
107 0, 0);
108 } catch (SendIntentException e) {
109 //
110 }
111 }
112 }
113 };
114
115 private OnClickListener clickToMuc = new OnClickListener() {
116
117 @Override
118 public void onClick(View v) {
119 Intent intent = new Intent(getActivity(),
120 ConferenceDetailsActivity.class);
121 intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
122 intent.putExtra("uuid", conversation.getUuid());
123 startActivity(intent);
124 }
125 };
126
127 private OnClickListener leaveMuc = new OnClickListener() {
128
129 @Override
130 public void onClick(View v) {
131 activity.endConversation(conversation);
132 }
133 };
134
135 private OnClickListener joinMuc = new OnClickListener() {
136
137 @Override
138 public void onClick(View v) {
139 activity.xmppConnectionService.joinMuc(conversation);
140 }
141 };
142
143 private OnClickListener enterPassword = new OnClickListener() {
144
145 @Override
146 public void onClick(View v) {
147 MucOptions muc = conversation.getMucOptions();
148 String password = muc.getPassword();
149 if (password == null) {
150 password = "";
151 }
152 activity.quickPasswordEdit(password, new OnValueEdited() {
153
154 @Override
155 public void onValueEdited(String value) {
156 activity.xmppConnectionService.providePasswordForMuc(
157 conversation, value);
158 }
159 });
160 }
161 };
162
163 private OnScrollListener mOnScrollListener = new OnScrollListener() {
164
165 @Override
166 public void onScrollStateChanged(AbsListView view, int scrollState) {
167 // TODO Auto-generated method stub
168
169 }
170
171 @Override
172 public void onScroll(AbsListView view, int firstVisibleItem,
173 int visibleItemCount, int totalItemCount) {
174 if (firstVisibleItem == 0 && messagesLoaded) {
175 long timestamp = messageList.get(0).getTimeSent();
176 messagesLoaded = false;
177 int size = activity.xmppConnectionService.loadMoreMessages(
178 conversation, timestamp);
179 messageList.clear();
180 messageList.addAll(conversation.getMessages());
181 updateStatusMessages();
182 messageListAdapter.notifyDataSetChanged();
183 if (size != 0) {
184 messagesLoaded = true;
185 }
186 messagesView.setSelectionFromTop(size + 1, 0);
187 }
188 }
189 };
190
191 private ConversationActivity activity;
192
193 private void sendMessage() {
194 if (this.conversation == null) {
195 return;
196 }
197 if (mEditMessage.getText().length() < 1) {
198 if (this.conversation.getMode() == Conversation.MODE_MULTI) {
199 conversation.setNextPresence(null);
200 updateChatMsgHint();
201 }
202 return;
203 }
204 Message message = new Message(conversation, mEditMessage.getText()
205 .toString(), conversation.getNextEncryption(activity
206 .forceEncryption()));
207 if (conversation.getMode() == Conversation.MODE_MULTI) {
208 if (conversation.getNextPresence() != null) {
209 message.setPresence(conversation.getNextPresence());
210 message.setType(Message.TYPE_PRIVATE);
211 conversation.setNextPresence(null);
212 }
213 }
214 if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_OTR) {
215 sendOtrMessage(message);
216 } else if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_PGP) {
217 sendPgpMessage(message);
218 } else {
219 sendPlainTextMessage(message);
220 }
221 }
222
223 public void updateChatMsgHint() {
224 if (conversation.getMode() == Conversation.MODE_MULTI
225 && conversation.getNextPresence() != null) {
226 this.mEditMessage.setHint(getString(
227 R.string.send_private_message_to,
228 conversation.getNextPresence()));
229 } else {
230 switch (conversation.getNextEncryption(activity.forceEncryption())) {
231 case Message.ENCRYPTION_NONE:
232 mEditMessage
233 .setHint(getString(R.string.send_plain_text_message));
234 break;
235 case Message.ENCRYPTION_OTR:
236 mEditMessage.setHint(getString(R.string.send_otr_message));
237 break;
238 case Message.ENCRYPTION_PGP:
239 mEditMessage.setHint(getString(R.string.send_pgp_message));
240 break;
241 default:
242 break;
243 }
244 }
245 }
246
247 @Override
248 public View onCreateView(final LayoutInflater inflater,
249 ViewGroup container, Bundle savedInstanceState) {
250 final View view = inflater.inflate(R.layout.fragment_conversation,
251 container, false);
252 mEditMessage = (EditMessage) view.findViewById(R.id.textinput);
253 mEditMessage.setOnClickListener(new OnClickListener() {
254
255 @Override
256 public void onClick(View v) {
257 activity.hideConversationsOverview();
258 }
259 });
260 mEditMessage.setOnEditorActionListener(mEditorActionListener);
261 mEditMessage.setOnEnterPressedListener(new OnEnterPressed() {
262
263 @Override
264 public void onEnterPressed() {
265 sendMessage();
266 }
267 });
268
269 mSendButton = (ImageButton) view.findViewById(R.id.textSendButton);
270 mSendButton.setOnClickListener(this.mSendButtonListener);
271
272 snackbar = (RelativeLayout) view.findViewById(R.id.snackbar);
273 snackbarMessage = (TextView) view.findViewById(R.id.snackbar_message);
274 snackbarAction = (TextView) view.findViewById(R.id.snackbar_action);
275
276 messagesView = (ListView) view.findViewById(R.id.messages_view);
277 messagesView.setOnScrollListener(mOnScrollListener);
278 messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
279 messageListAdapter = new MessageAdapter(
280 (ConversationActivity) getActivity(), this.messageList);
281 messageListAdapter
282 .setOnContactPictureClicked(new OnContactPictureClicked() {
283
284 @Override
285 public void onContactPictureClicked(Message message) {
286 if (message.getStatus() <= Message.STATUS_RECEIVED) {
287 if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
288 if (message.getPresence() != null) {
289 highlightInConference(message.getPresence());
290 } else {
291 highlightInConference(message
292 .getCounterpart());
293 }
294 } else {
295 Contact contact = message.getConversation()
296 .getContact();
297 if (contact.showInRoster()) {
298 activity.switchToContactDetails(contact);
299 } else {
300 activity.showAddToRosterDialog(message
301 .getConversation());
302 }
303 }
304 }
305 }
306 });
307 messageListAdapter
308 .setOnContactPictureLongClicked(new OnContactPictureLongClicked() {
309
310 @Override
311 public void onContactPictureLongClicked(Message message) {
312 if (message.getStatus() <= Message.STATUS_RECEIVED) {
313 if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
314 if (message.getPresence() != null) {
315 privateMessageWith(message.getPresence());
316 } else {
317 privateMessageWith(message.getCounterpart());
318 }
319 }
320 }
321 }
322 });
323 messagesView.setAdapter(messageListAdapter);
324
325 return view;
326 }
327
328 protected void privateMessageWith(String counterpart) {
329 this.mEditMessage.setText("");
330 this.conversation.setNextPresence(counterpart);
331 updateChatMsgHint();
332 }
333
334 protected void highlightInConference(String nick) {
335 String oldString = mEditMessage.getText().toString().trim();
336 if (oldString.isEmpty() || mEditMessage.getSelectionStart() == 0) {
337 mEditMessage.getText().insert(0, nick + ": ");
338 } else {
339 if (mEditMessage.getText().charAt(
340 mEditMessage.getSelectionStart() - 1) != ' ') {
341 nick = " " + nick;
342 }
343 mEditMessage.getText().insert(mEditMessage.getSelectionStart(),
344 nick + " ");
345 }
346 }
347
348 @Override
349 public void onStart() {
350 super.onStart();
351 this.activity = (ConversationActivity) getActivity();
352 if (activity.xmppConnectionServiceBound) {
353 this.onBackendConnected();
354 }
355 }
356
357 @Override
358 public void onStop() {
359 super.onStop();
360 if (this.conversation != null) {
361 this.conversation.setNextMessage(mEditMessage.getText().toString());
362 }
363 }
364
365 public void onBackendConnected() {
366 this.activity = (ConversationActivity) getActivity();
367 this.conversation = activity.getSelectedConversation();
368 if (this.conversation == null) {
369 return;
370 }
371 String oldString = conversation.getNextMessage().trim();
372 if (this.pastedText == null) {
373 this.mEditMessage.setText(oldString);
374 } else {
375
376 if (oldString.isEmpty()) {
377 mEditMessage.setText(pastedText);
378 } else {
379 mEditMessage.setText(oldString + " " + pastedText);
380 }
381 pastedText = null;
382 }
383 int position = mEditMessage.length();
384 Editable etext = mEditMessage.getText();
385 Selection.setSelection(etext, position);
386 if (activity.isConversationsOverviewHideable()) {
387 if (!activity.shouldPaneBeOpen()) {
388 activity.hideConversationsOverview();
389 activity.openConversation(conversation);
390 }
391 }
392 if (this.conversation.getMode() == Conversation.MODE_MULTI) {
393 conversation.setNextPresence(null);
394 }
395 updateMessages();
396 }
397
398 private void decryptMessage(Message message) {
399 PgpEngine engine = activity.xmppConnectionService.getPgpEngine();
400 if (engine != null) {
401 engine.decrypt(message, new UiCallback<Message>() {
402
403 @Override
404 public void userInputRequried(PendingIntent pi, Message message) {
405 askForPassphraseIntent = pi.getIntentSender();
406 showSnackbar(R.string.openpgp_messages_found,
407 R.string.decrypt, clickToDecryptListener);
408 }
409
410 @Override
411 public void success(Message message) {
412 activity.xmppConnectionService.databaseBackend
413 .updateMessage(message);
414 updateMessages();
415 }
416
417 @Override
418 public void error(int error, Message message) {
419 message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
420 // updateMessages();
421 }
422 });
423 }
424 }
425
426 public void updateMessages() {
427 if (getView() == null) {
428 return;
429 }
430 hideSnackbar();
431 final ConversationActivity activity = (ConversationActivity) getActivity();
432 if (this.conversation != null) {
433 final Contact contact = this.conversation.getContact();
434 if (this.conversation.isMuted()) {
435 showSnackbar(R.string.notifications_disabled, R.string.enable,
436 new OnClickListener() {
437
438 @Override
439 public void onClick(View v) {
440 conversation.setMutedTill(0);
441 updateMessages();
442 }
443 });
444 } else if (!contact.showInRoster()
445 && contact
446 .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
447 showSnackbar(R.string.contact_added_you, R.string.add_back,
448 new OnClickListener() {
449
450 @Override
451 public void onClick(View v) {
452 activity.xmppConnectionService
453 .createContact(contact);
454 activity.switchToContactDetails(contact);
455 }
456 });
457 }
458 for (Message message : this.conversation.getMessages()) {
459 if ((message.getEncryption() == Message.ENCRYPTION_PGP)
460 && ((message.getStatus() == Message.STATUS_RECEIVED) || (message
461 .getStatus() == Message.STATUS_SEND))) {
462 decryptMessage(message);
463 break;
464 }
465 }
466 this.messageList.clear();
467 if (this.conversation.getMessages().size() == 0) {
468 messagesLoaded = false;
469 } else {
470 this.messageList.addAll(this.conversation.getMessages());
471 messagesLoaded = true;
472 updateStatusMessages();
473 }
474 this.messageListAdapter.notifyDataSetChanged();
475 if (conversation.getMode() == Conversation.MODE_SINGLE) {
476 if (messageList.size() >= 1) {
477 makeFingerprintWarning(conversation.getLatestEncryption());
478 }
479 } else {
480 if (!conversation.getMucOptions().online()
481 && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) {
482 int error = conversation.getMucOptions().getError();
483 switch (error) {
484 case MucOptions.ERROR_NICK_IN_USE:
485 showSnackbar(R.string.nick_in_use, R.string.edit,
486 clickToMuc);
487 break;
488 case MucOptions.ERROR_ROOM_NOT_FOUND:
489 showSnackbar(R.string.conference_not_found,
490 R.string.leave, leaveMuc);
491 break;
492 case MucOptions.ERROR_PASSWORD_REQUIRED:
493 showSnackbar(R.string.conference_requires_password,
494 R.string.enter_password, enterPassword);
495 break;
496 case MucOptions.ERROR_BANNED:
497 showSnackbar(R.string.conference_banned,
498 R.string.leave, leaveMuc);
499 break;
500 case MucOptions.ERROR_MEMBERS_ONLY:
501 showSnackbar(R.string.conference_members_only,
502 R.string.leave, leaveMuc);
503 break;
504 case MucOptions.KICKED_FROM_ROOM:
505 showSnackbar(R.string.conference_kicked,
506 R.string.join, joinMuc);
507 break;
508 default:
509 break;
510 }
511 }
512 }
513 getActivity().invalidateOptionsMenu();
514 updateChatMsgHint();
515 if (!activity.shouldPaneBeOpen()) {
516 activity.xmppConnectionService.markRead(conversation, true);
517 activity.updateConversationList();
518 }
519 this.updateSendButton();
520 }
521 }
522
523 private void messageSent() {
524 int size = this.messageList.size();
525 messagesView.setSelection(size - 1);
526 mEditMessage.setText("");
527 updateChatMsgHint();
528 }
529
530 public void updateSendButton() {
531 Conversation c = this.conversation;
532 if (activity.useSendButtonToIndicateStatus() && c != null
533 && c.getAccount().getStatus() == Account.STATUS_ONLINE) {
534 if (c.getMode() == Conversation.MODE_SINGLE) {
535 switch (c.getContact().getMostAvailableStatus()) {
536 case Presences.CHAT:
537 this.mSendButton
538 .setImageResource(R.drawable.ic_action_send_now_online);
539 break;
540 case Presences.ONLINE:
541 this.mSendButton
542 .setImageResource(R.drawable.ic_action_send_now_online);
543 break;
544 case Presences.AWAY:
545 this.mSendButton
546 .setImageResource(R.drawable.ic_action_send_now_away);
547 break;
548 case Presences.XA:
549 this.mSendButton
550 .setImageResource(R.drawable.ic_action_send_now_away);
551 break;
552 case Presences.DND:
553 this.mSendButton
554 .setImageResource(R.drawable.ic_action_send_now_dnd);
555 break;
556 default:
557 this.mSendButton
558 .setImageResource(R.drawable.ic_action_send_now_offline);
559 break;
560 }
561 } else if (c.getMode() == Conversation.MODE_MULTI) {
562 if (c.getMucOptions().online()) {
563 this.mSendButton
564 .setImageResource(R.drawable.ic_action_send_now_online);
565 } else {
566 this.mSendButton
567 .setImageResource(R.drawable.ic_action_send_now_offline);
568 }
569 } else {
570 this.mSendButton
571 .setImageResource(R.drawable.ic_action_send_now_offline);
572 }
573 } else {
574 this.mSendButton
575 .setImageResource(R.drawable.ic_action_send_now_offline);
576 }
577 }
578
579 protected void updateStatusMessages() {
580 if (conversation.getMode() == Conversation.MODE_SINGLE) {
581 for (int i = this.messageList.size() - 1; i >= 0; --i) {
582 if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) {
583 return;
584 } else {
585 if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
586 this.messageList.add(i + 1,
587 Message.createStatusMessage(conversation));
588 return;
589 }
590 }
591 }
592 }
593 }
594
595 protected void makeFingerprintWarning(int latestEncryption) {
596 Set<String> knownFingerprints = conversation.getContact()
597 .getOtrFingerprints();
598 if ((latestEncryption == Message.ENCRYPTION_OTR)
599 && (conversation.hasValidOtrSession()
600 && (!conversation.isMuted())
601 && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
602 .contains(conversation.getOtrFingerprint())))) {
603 showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify,
604 new OnClickListener() {
605
606 @Override
607 public void onClick(View v) {
608 if (conversation.getOtrFingerprint() != null) {
609 AlertDialog dialog = UIHelper
610 .getVerifyFingerprintDialog(
611 (ConversationActivity) getActivity(),
612 conversation, snackbar);
613 dialog.show();
614 }
615 }
616 });
617 }
618 }
619
620 protected void showSnackbar(int message, int action,
621 OnClickListener clickListener) {
622 snackbar.setVisibility(View.VISIBLE);
623 snackbar.setOnClickListener(null);
624 snackbarMessage.setText(message);
625 snackbarMessage.setOnClickListener(null);
626 snackbarAction.setText(action);
627 snackbarAction.setOnClickListener(clickListener);
628 }
629
630 protected void hideSnackbar() {
631 snackbar.setVisibility(View.GONE);
632 }
633
634 protected void sendPlainTextMessage(Message message) {
635 ConversationActivity activity = (ConversationActivity) getActivity();
636 activity.xmppConnectionService.sendMessage(message);
637 messageSent();
638 }
639
640 protected void sendPgpMessage(final Message message) {
641 final ConversationActivity activity = (ConversationActivity) getActivity();
642 final XmppConnectionService xmppService = activity.xmppConnectionService;
643 final Contact contact = message.getConversation().getContact();
644 if (activity.hasPgp()) {
645 if (conversation.getMode() == Conversation.MODE_SINGLE) {
646 if (contact.getPgpKeyId() != 0) {
647 xmppService.getPgpEngine().hasKey(contact,
648 new UiCallback<Contact>() {
649
650 @Override
651 public void userInputRequried(PendingIntent pi,
652 Contact contact) {
653 activity.runIntent(
654 pi,
655 ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
656 }
657
658 @Override
659 public void success(Contact contact) {
660 messageSent();
661 activity.encryptTextMessage(message);
662 }
663
664 @Override
665 public void error(int error, Contact contact) {
666
667 }
668 });
669
670 } else {
671 showNoPGPKeyDialog(false,
672 new DialogInterface.OnClickListener() {
673
674 @Override
675 public void onClick(DialogInterface dialog,
676 int which) {
677 conversation
678 .setNextEncryption(Message.ENCRYPTION_NONE);
679 xmppService.databaseBackend
680 .updateConversation(conversation);
681 message.setEncryption(Message.ENCRYPTION_NONE);
682 xmppService.sendMessage(message);
683 messageSent();
684 }
685 });
686 }
687 } else {
688 if (conversation.getMucOptions().pgpKeysInUse()) {
689 if (!conversation.getMucOptions().everybodyHasKeys()) {
690 Toast warning = Toast
691 .makeText(getActivity(),
692 R.string.missing_public_keys,
693 Toast.LENGTH_LONG);
694 warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
695 warning.show();
696 }
697 activity.encryptTextMessage(message);
698 messageSent();
699 } else {
700 showNoPGPKeyDialog(true,
701 new DialogInterface.OnClickListener() {
702
703 @Override
704 public void onClick(DialogInterface dialog,
705 int which) {
706 conversation
707 .setNextEncryption(Message.ENCRYPTION_NONE);
708 message.setEncryption(Message.ENCRYPTION_NONE);
709 xmppService.databaseBackend
710 .updateConversation(conversation);
711 xmppService.sendMessage(message);
712 messageSent();
713 }
714 });
715 }
716 }
717 } else {
718 activity.showInstallPgpDialog();
719 }
720 }
721
722 public void showNoPGPKeyDialog(boolean plural,
723 DialogInterface.OnClickListener listener) {
724 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
725 builder.setIconAttribute(android.R.attr.alertDialogIcon);
726 if (plural) {
727 builder.setTitle(getString(R.string.no_pgp_keys));
728 builder.setMessage(getText(R.string.contacts_have_no_pgp_keys));
729 } else {
730 builder.setTitle(getString(R.string.no_pgp_key));
731 builder.setMessage(getText(R.string.contact_has_no_pgp_key));
732 }
733 builder.setNegativeButton(getString(R.string.cancel), null);
734 builder.setPositiveButton(getString(R.string.send_unencrypted),
735 listener);
736 builder.create().show();
737 }
738
739 protected void sendOtrMessage(final Message message) {
740 final ConversationActivity activity = (ConversationActivity) getActivity();
741 final XmppConnectionService xmppService = activity.xmppConnectionService;
742 if (conversation.hasValidOtrSession()) {
743 activity.xmppConnectionService.sendMessage(message);
744 messageSent();
745 } else {
746 activity.selectPresence(message.getConversation(),
747 new OnPresenceSelected() {
748
749 @Override
750 public void onPresenceSelected() {
751 message.setPresence(conversation.getNextPresence());
752 xmppService.sendMessage(message);
753 messageSent();
754 }
755 });
756 }
757 }
758
759 public void setText(String text) {
760 this.pastedText = text;
761 }
762
763 public void clearInputField() {
764 this.mEditMessage.setText("");
765 }
766}