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 activity.xmppConnectionService.databaseBackend
442 .updateConversation(conversation);
443 updateMessages();
444 }
445 });
446 } else if (!contact.showInRoster()
447 && contact
448 .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
449 showSnackbar(R.string.contact_added_you, R.string.add_back,
450 new OnClickListener() {
451
452 @Override
453 public void onClick(View v) {
454 activity.xmppConnectionService
455 .createContact(contact);
456 activity.switchToContactDetails(contact);
457 }
458 });
459 }
460 for (Message message : this.conversation.getMessages()) {
461 if ((message.getEncryption() == Message.ENCRYPTION_PGP)
462 && ((message.getStatus() == Message.STATUS_RECEIVED) || (message
463 .getStatus() == Message.STATUS_SEND))) {
464 decryptMessage(message);
465 break;
466 }
467 }
468 this.messageList.clear();
469 if (this.conversation.getMessages().size() == 0) {
470 messagesLoaded = false;
471 } else {
472 this.messageList.addAll(this.conversation.getMessages());
473 messagesLoaded = true;
474 updateStatusMessages();
475 }
476 this.messageListAdapter.notifyDataSetChanged();
477 if (conversation.getMode() == Conversation.MODE_SINGLE) {
478 if (messageList.size() >= 1) {
479 makeFingerprintWarning(conversation.getLatestEncryption());
480 }
481 } else {
482 if (!conversation.getMucOptions().online()
483 && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) {
484 int error = conversation.getMucOptions().getError();
485 switch (error) {
486 case MucOptions.ERROR_NICK_IN_USE:
487 showSnackbar(R.string.nick_in_use, R.string.edit,
488 clickToMuc);
489 break;
490 case MucOptions.ERROR_ROOM_NOT_FOUND:
491 showSnackbar(R.string.conference_not_found,
492 R.string.leave, leaveMuc);
493 break;
494 case MucOptions.ERROR_PASSWORD_REQUIRED:
495 showSnackbar(R.string.conference_requires_password,
496 R.string.enter_password, enterPassword);
497 break;
498 case MucOptions.ERROR_BANNED:
499 showSnackbar(R.string.conference_banned,
500 R.string.leave, leaveMuc);
501 break;
502 case MucOptions.ERROR_MEMBERS_ONLY:
503 showSnackbar(R.string.conference_members_only,
504 R.string.leave, leaveMuc);
505 break;
506 case MucOptions.KICKED_FROM_ROOM:
507 showSnackbar(R.string.conference_kicked, R.string.join,
508 joinMuc);
509 break;
510 default:
511 break;
512 }
513 }
514 }
515 getActivity().invalidateOptionsMenu();
516 updateChatMsgHint();
517 if (!activity.shouldPaneBeOpen()) {
518 activity.xmppConnectionService.markRead(conversation, true);
519 activity.updateConversationList();
520 }
521 this.updateSendButton();
522 }
523 }
524
525 private void messageSent() {
526 int size = this.messageList.size();
527 messagesView.setSelection(size - 1);
528 mEditMessage.setText("");
529 updateChatMsgHint();
530 }
531
532 public void updateSendButton() {
533 Conversation c = this.conversation;
534 if (activity.useSendButtonToIndicateStatus() && c != null
535 && c.getAccount().getStatus() == Account.STATUS_ONLINE) {
536 if (c.getMode() == Conversation.MODE_SINGLE) {
537 switch (c.getContact().getMostAvailableStatus()) {
538 case Presences.CHAT:
539 this.mSendButton
540 .setImageResource(R.drawable.ic_action_send_now_online);
541 break;
542 case Presences.ONLINE:
543 this.mSendButton
544 .setImageResource(R.drawable.ic_action_send_now_online);
545 break;
546 case Presences.AWAY:
547 this.mSendButton
548 .setImageResource(R.drawable.ic_action_send_now_away);
549 break;
550 case Presences.XA:
551 this.mSendButton
552 .setImageResource(R.drawable.ic_action_send_now_away);
553 break;
554 case Presences.DND:
555 this.mSendButton
556 .setImageResource(R.drawable.ic_action_send_now_dnd);
557 break;
558 default:
559 this.mSendButton
560 .setImageResource(R.drawable.ic_action_send_now_offline);
561 break;
562 }
563 } else if (c.getMode() == Conversation.MODE_MULTI) {
564 if (c.getMucOptions().online()) {
565 this.mSendButton
566 .setImageResource(R.drawable.ic_action_send_now_online);
567 } else {
568 this.mSendButton
569 .setImageResource(R.drawable.ic_action_send_now_offline);
570 }
571 } else {
572 this.mSendButton
573 .setImageResource(R.drawable.ic_action_send_now_offline);
574 }
575 } else {
576 this.mSendButton
577 .setImageResource(R.drawable.ic_action_send_now_offline);
578 }
579 }
580
581 protected void updateStatusMessages() {
582 if (conversation.getMode() == Conversation.MODE_SINGLE) {
583 for (int i = this.messageList.size() - 1; i >= 0; --i) {
584 if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) {
585 return;
586 } else {
587 if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
588 this.messageList.add(i + 1,
589 Message.createStatusMessage(conversation));
590 return;
591 }
592 }
593 }
594 }
595 }
596
597 protected void makeFingerprintWarning(int latestEncryption) {
598 Set<String> knownFingerprints = conversation.getContact()
599 .getOtrFingerprints();
600 if ((latestEncryption == Message.ENCRYPTION_OTR)
601 && (conversation.hasValidOtrSession()
602 && (!conversation.isMuted())
603 && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
604 .contains(conversation.getOtrFingerprint())))) {
605 showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify,
606 new OnClickListener() {
607
608 @Override
609 public void onClick(View v) {
610 if (conversation.getOtrFingerprint() != null) {
611 AlertDialog dialog = UIHelper
612 .getVerifyFingerprintDialog(
613 (ConversationActivity) getActivity(),
614 conversation, snackbar);
615 dialog.show();
616 }
617 }
618 });
619 }
620 }
621
622 protected void showSnackbar(int message, int action,
623 OnClickListener clickListener) {
624 snackbar.setVisibility(View.VISIBLE);
625 snackbar.setOnClickListener(null);
626 snackbarMessage.setText(message);
627 snackbarMessage.setOnClickListener(null);
628 snackbarAction.setText(action);
629 snackbarAction.setOnClickListener(clickListener);
630 }
631
632 protected void hideSnackbar() {
633 snackbar.setVisibility(View.GONE);
634 }
635
636 protected void sendPlainTextMessage(Message message) {
637 ConversationActivity activity = (ConversationActivity) getActivity();
638 activity.xmppConnectionService.sendMessage(message);
639 messageSent();
640 }
641
642 protected void sendPgpMessage(final Message message) {
643 final ConversationActivity activity = (ConversationActivity) getActivity();
644 final XmppConnectionService xmppService = activity.xmppConnectionService;
645 final Contact contact = message.getConversation().getContact();
646 if (activity.hasPgp()) {
647 if (conversation.getMode() == Conversation.MODE_SINGLE) {
648 if (contact.getPgpKeyId() != 0) {
649 xmppService.getPgpEngine().hasKey(contact,
650 new UiCallback<Contact>() {
651
652 @Override
653 public void userInputRequried(PendingIntent pi,
654 Contact contact) {
655 activity.runIntent(
656 pi,
657 ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
658 }
659
660 @Override
661 public void success(Contact contact) {
662 messageSent();
663 activity.encryptTextMessage(message);
664 }
665
666 @Override
667 public void error(int error, Contact contact) {
668
669 }
670 });
671
672 } else {
673 showNoPGPKeyDialog(false,
674 new DialogInterface.OnClickListener() {
675
676 @Override
677 public void onClick(DialogInterface dialog,
678 int which) {
679 conversation
680 .setNextEncryption(Message.ENCRYPTION_NONE);
681 xmppService.databaseBackend
682 .updateConversation(conversation);
683 message.setEncryption(Message.ENCRYPTION_NONE);
684 xmppService.sendMessage(message);
685 messageSent();
686 }
687 });
688 }
689 } else {
690 if (conversation.getMucOptions().pgpKeysInUse()) {
691 if (!conversation.getMucOptions().everybodyHasKeys()) {
692 Toast warning = Toast
693 .makeText(getActivity(),
694 R.string.missing_public_keys,
695 Toast.LENGTH_LONG);
696 warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
697 warning.show();
698 }
699 activity.encryptTextMessage(message);
700 messageSent();
701 } else {
702 showNoPGPKeyDialog(true,
703 new DialogInterface.OnClickListener() {
704
705 @Override
706 public void onClick(DialogInterface dialog,
707 int which) {
708 conversation
709 .setNextEncryption(Message.ENCRYPTION_NONE);
710 message.setEncryption(Message.ENCRYPTION_NONE);
711 xmppService.databaseBackend
712 .updateConversation(conversation);
713 xmppService.sendMessage(message);
714 messageSent();
715 }
716 });
717 }
718 }
719 } else {
720 activity.showInstallPgpDialog();
721 }
722 }
723
724 public void showNoPGPKeyDialog(boolean plural,
725 DialogInterface.OnClickListener listener) {
726 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
727 builder.setIconAttribute(android.R.attr.alertDialogIcon);
728 if (plural) {
729 builder.setTitle(getString(R.string.no_pgp_keys));
730 builder.setMessage(getText(R.string.contacts_have_no_pgp_keys));
731 } else {
732 builder.setTitle(getString(R.string.no_pgp_key));
733 builder.setMessage(getText(R.string.contact_has_no_pgp_key));
734 }
735 builder.setNegativeButton(getString(R.string.cancel), null);
736 builder.setPositiveButton(getString(R.string.send_unencrypted),
737 listener);
738 builder.create().show();
739 }
740
741 protected void sendOtrMessage(final Message message) {
742 final ConversationActivity activity = (ConversationActivity) getActivity();
743 final XmppConnectionService xmppService = activity.xmppConnectionService;
744 if (conversation.hasValidOtrSession()) {
745 activity.xmppConnectionService.sendMessage(message);
746 messageSent();
747 } else {
748 activity.selectPresence(message.getConversation(),
749 new OnPresenceSelected() {
750
751 @Override
752 public void onPresenceSelected() {
753 message.setPresence(conversation.getNextPresence());
754 xmppService.sendMessage(message);
755 messageSent();
756 }
757 });
758 }
759 }
760
761 public void setText(String text) {
762 this.pastedText = text;
763 }
764
765 public void clearInputField() {
766 this.mEditMessage.setText("");
767 }
768}