1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.Hashtable;
6import java.util.LinkedList;
7import java.util.List;
8import java.util.Set;
9
10import net.java.otr4j.session.SessionStatus;
11
12import eu.siacs.conversations.R;
13import eu.siacs.conversations.crypto.PgpEngine.OpenPgpException;
14import eu.siacs.conversations.crypto.PgpEngine.UserInputRequiredException;
15import eu.siacs.conversations.entities.Account;
16import eu.siacs.conversations.entities.Contact;
17import eu.siacs.conversations.entities.Conversation;
18import eu.siacs.conversations.entities.Message;
19import eu.siacs.conversations.entities.MucOptions;
20import eu.siacs.conversations.entities.MucOptions.OnRenameListener;
21import eu.siacs.conversations.services.XmppConnectionService;
22import eu.siacs.conversations.utils.UIHelper;
23import android.app.AlertDialog;
24import android.app.Fragment;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.Intent;
28import android.content.IntentSender;
29import android.content.SharedPreferences;
30import android.content.IntentSender.SendIntentException;
31import android.graphics.Bitmap;
32import android.graphics.Typeface;
33import android.os.AsyncTask;
34import android.os.Bundle;
35import android.preference.PreferenceManager;
36import android.util.DisplayMetrics;
37import android.util.Log;
38import android.view.LayoutInflater;
39import android.view.View;
40import android.view.View.OnClickListener;
41import android.view.ViewGroup;
42import android.widget.ArrayAdapter;
43import android.widget.EditText;
44import android.widget.LinearLayout;
45import android.widget.ListView;
46import android.widget.ImageButton;
47import android.widget.ImageView;
48import android.widget.TextView;
49import android.widget.Toast;
50
51public class ConversationFragment extends Fragment {
52
53 protected Conversation conversation;
54 protected ListView messagesView;
55 protected LayoutInflater inflater;
56 protected List<Message> messageList = new ArrayList<Message>();
57 protected ArrayAdapter<Message> messageListAdapter;
58 protected Contact contact;
59 protected BitmapCache mBitmapCache = new BitmapCache();
60
61 protected String queuedPqpMessage = null;
62
63 private EditText chatMsg;
64 private String pastedText = null;
65
66 protected Bitmap selfBitmap;
67
68 private boolean useSubject = true;
69
70 private IntentSender askForPassphraseIntent = null;
71
72 private OnClickListener sendMsgListener = new OnClickListener() {
73
74 @Override
75 public void onClick(View v) {
76 if (chatMsg.getText().length() < 1)
77 return;
78 Message message = new Message(conversation, chatMsg.getText()
79 .toString(), conversation.nextMessageEncryption);
80 if (conversation.nextMessageEncryption == Message.ENCRYPTION_OTR) {
81 sendOtrMessage(message);
82 } else if (conversation.nextMessageEncryption == Message.ENCRYPTION_PGP) {
83 sendPgpMessage(message);
84 } else {
85 sendPlainTextMessage(message);
86 }
87 }
88 };
89 protected OnClickListener clickToDecryptListener = new OnClickListener() {
90
91 @Override
92 public void onClick(View v) {
93 if (askForPassphraseIntent != null) {
94 try {
95 getActivity().startIntentSenderForResult(
96 askForPassphraseIntent,
97 ConversationActivity.REQUEST_DECRYPT_PGP, null, 0,
98 0, 0);
99 } catch (SendIntentException e) {
100 Log.d("xmppService", "couldnt fire intent");
101 }
102 }
103 }
104 };
105
106 private LinearLayout pgpInfo;
107 private LinearLayout mucError;
108 private TextView mucErrorText;
109 private OnClickListener clickToMuc = new OnClickListener() {
110
111 @Override
112 public void onClick(View v) {
113 Intent intent = new Intent(getActivity(), MucDetailsActivity.class);
114 intent.setAction(MucDetailsActivity.ACTION_VIEW_MUC);
115 intent.putExtra("uuid", conversation.getUuid());
116 startActivity(intent);
117 }
118 };
119 private ConversationActivity activity;
120
121 public void hidePgpPassphraseBox() {
122 pgpInfo.setVisibility(View.GONE);
123 }
124
125 public void updateChatMsgHint() {
126 if (conversation.getMode() == Conversation.MODE_MULTI) {
127 chatMsg.setHint("Send message to conference");
128 } else {
129 switch (conversation.nextMessageEncryption) {
130 case Message.ENCRYPTION_NONE:
131 chatMsg.setHint("Send plain text message");
132 break;
133 case Message.ENCRYPTION_OTR:
134 chatMsg.setHint("Send OTR encrypted message");
135 break;
136 case Message.ENCRYPTION_PGP:
137 chatMsg.setHint("Send openPGP encryted messeage");
138 break;
139 case Message.ENCRYPTION_DECRYPTED:
140 chatMsg.setHint("Send openPGP encryted messeage");
141 break;
142 default:
143 break;
144 }
145 }
146 }
147
148 @Override
149 public View onCreateView(final LayoutInflater inflater,
150 ViewGroup container, Bundle savedInstanceState) {
151
152 final DisplayMetrics metrics = getResources().getDisplayMetrics();
153
154 this.inflater = inflater;
155
156 final View view = inflater.inflate(R.layout.fragment_conversation,
157 container, false);
158 chatMsg = (EditText) view.findViewById(R.id.textinput);
159
160 if (pastedText!=null) {
161 chatMsg.setText(pastedText);
162 }
163
164 ImageButton sendButton = (ImageButton) view
165 .findViewById(R.id.textSendButton);
166 sendButton.setOnClickListener(this.sendMsgListener);
167
168 pgpInfo = (LinearLayout) view.findViewById(R.id.pgp_keyentry);
169 pgpInfo.setOnClickListener(clickToDecryptListener);
170 mucError = (LinearLayout) view.findViewById(R.id.muc_error);
171 mucError.setOnClickListener(clickToMuc);
172 mucErrorText = (TextView) view.findViewById(R.id.muc_error_msg);
173
174 messagesView = (ListView) view.findViewById(R.id.messages_view);
175
176 messageListAdapter = new ArrayAdapter<Message>(this.getActivity()
177 .getApplicationContext(), R.layout.message_sent,
178 this.messageList) {
179
180 private static final int SENT = 0;
181 private static final int RECIEVED = 1;
182
183 @Override
184 public int getViewTypeCount() {
185 return 2;
186 }
187
188 @Override
189 public int getItemViewType(int position) {
190 if (getItem(position).getStatus() <= Message.STATUS_RECIEVED) {
191 return RECIEVED;
192 } else {
193 return SENT;
194 }
195 }
196
197 @Override
198 public View getView(int position, View view, ViewGroup parent) {
199 Message item = getItem(position);
200 int type = getItemViewType(position);
201 ViewHolder viewHolder;
202 if (view == null) {
203 viewHolder = new ViewHolder();
204 switch (type) {
205 case SENT:
206 view = (View) inflater.inflate(R.layout.message_sent,
207 null);
208 viewHolder.imageView = (ImageView) view
209 .findViewById(R.id.message_photo);
210 viewHolder.imageView.setImageBitmap(selfBitmap);
211 viewHolder.indicator = (ImageView) view.findViewById(R.id.security_indicator);
212 break;
213 case RECIEVED:
214 view = (View) inflater.inflate(
215 R.layout.message_recieved, null);
216 viewHolder.imageView = (ImageView) view
217 .findViewById(R.id.message_photo);
218 viewHolder.indicator = (ImageView) view.findViewById(R.id.security_indicator);
219 if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
220
221 viewHolder.imageView.setImageBitmap(mBitmapCache
222 .get(item.getConversation().getName(useSubject), item
223 .getConversation().getContact(),
224 getActivity()
225 .getApplicationContext()));
226
227 }
228 break;
229 default:
230 viewHolder = null;
231 break;
232 }
233 viewHolder.image = (ImageView) view.findViewById(R.id.message_image);
234 viewHolder.messageBody = (TextView) view
235 .findViewById(R.id.message_body);
236 viewHolder.time = (TextView) view
237 .findViewById(R.id.message_time);
238 view.setTag(viewHolder);
239 } else {
240 viewHolder = (ViewHolder) view.getTag();
241 }
242 if (type == RECIEVED) {
243 if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
244 if (item.getCounterpart() != null) {
245 viewHolder.imageView.setImageBitmap(mBitmapCache
246 .get(item.getCounterpart(), null,
247 getActivity()
248 .getApplicationContext()));
249 } else {
250 viewHolder.imageView.setImageBitmap(mBitmapCache
251 .get(item.getConversation().getName(useSubject),
252 null, getActivity()
253 .getApplicationContext()));
254 }
255 }
256 }
257 if (item.getType() == Message.TYPE_IMAGE) {
258 viewHolder.image.setVisibility(View.VISIBLE);
259 if (item.getStatus() != Message.STATUS_RECIEVING) {
260 viewHolder.image.setImageBitmap(activity.xmppConnectionService.getFileBackend().getThumbnailFromMessage(item,(int) (metrics.density * 288)));
261 viewHolder.messageBody.setVisibility(View.GONE);
262 } else {
263 viewHolder.messageBody.setVisibility(View.VISIBLE);
264 viewHolder.messageBody.setText("receiving image file");
265 }
266 } else {
267 if (viewHolder.image != null) viewHolder.image.setVisibility(View.GONE);
268 viewHolder.messageBody.setVisibility(View.VISIBLE);
269 String body = item.getBody();
270 if (body != null) {
271 if (item.getEncryption() == Message.ENCRYPTION_PGP) {
272 viewHolder.messageBody
273 .setText(getString(R.string.encrypted_message));
274 viewHolder.messageBody.setTextColor(0xff33B5E5);
275 viewHolder.messageBody.setTypeface(null,
276 Typeface.ITALIC);
277 viewHolder.indicator.setVisibility(View.VISIBLE);
278 } else if ((item.getEncryption() == Message.ENCRYPTION_OTR)||(item.getEncryption() == Message.ENCRYPTION_DECRYPTED)) {
279 viewHolder.messageBody.setText(body.trim());
280 viewHolder.messageBody.setTextColor(0xff333333);
281 viewHolder.messageBody.setTypeface(null,
282 Typeface.NORMAL);
283 viewHolder.indicator.setVisibility(View.VISIBLE);
284 } else {
285 viewHolder.messageBody.setText(body.trim());
286 viewHolder.messageBody.setTextColor(0xff333333);
287 viewHolder.messageBody.setTypeface(null,
288 Typeface.NORMAL);
289 viewHolder.indicator.setVisibility(View.GONE);
290 }
291 } else {
292 viewHolder.indicator.setVisibility(View.GONE);
293 }
294 }
295 switch (item.getStatus()) {
296 case Message.STATUS_UNSEND:
297 viewHolder.time.setTypeface(null, Typeface.ITALIC);
298 viewHolder.time.setTextColor(0xFF8e8e8e);
299 viewHolder.time.setText("sending\u2026");
300 break;
301 case Message.STATUS_SEND_FAILED:
302 viewHolder.time.setText(getString(R.string.send_failed) + " \u00B7 " + UIHelper.readableTimeDifference(item
303 .getTimeSent()));
304 viewHolder.time.setTextColor(0xFFe92727);
305 viewHolder.time.setTypeface(null,Typeface.NORMAL);
306 break;
307 case Message.STATUS_SEND_REJECTED:
308 viewHolder.time.setText(getString(R.string.send_rejected));
309 viewHolder.time.setTextColor(0xFFe92727);
310 viewHolder.time.setTypeface(null,Typeface.NORMAL);
311 break;
312 default:
313 viewHolder.time.setTypeface(null, Typeface.NORMAL);
314 viewHolder.time.setTextColor(0xFF8e8e8e);
315 if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
316 viewHolder.time.setText(UIHelper
317 .readableTimeDifference(item.getTimeSent()));
318 } else {
319 viewHolder.time.setText(item.getCounterpart()
320 + " \u00B7 "
321 + UIHelper.readableTimeDifference(item
322 .getTimeSent()));
323 }
324 break;
325 }
326 return view;
327 }
328 };
329 messagesView.setAdapter(messageListAdapter);
330
331 return view;
332 }
333
334 protected Bitmap findSelfPicture() {
335 SharedPreferences sharedPref = PreferenceManager
336 .getDefaultSharedPreferences(getActivity()
337 .getApplicationContext());
338 boolean showPhoneSelfContactPicture = sharedPref.getBoolean(
339 "show_phone_selfcontact_picture", true);
340
341 return UIHelper.getSelfContactPicture(conversation.getAccount(), 48,
342 showPhoneSelfContactPicture, getActivity());
343 }
344
345 @Override
346 public void onStart() {
347 super.onStart();
348 this.activity = (ConversationActivity) getActivity();
349 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
350 this.useSubject = preferences.getBoolean("use_subject_in_muc", true);
351 if (activity.xmppConnectionServiceBound) {
352 this.onBackendConnected();
353 }
354 }
355
356 public void onBackendConnected() {
357 this.conversation = activity.getSelectedConversation();
358 if (this.conversation == null) {
359 return;
360 }
361 this.selfBitmap = findSelfPicture();
362 updateMessages();
363 // rendering complete. now go tell activity to close pane
364 if (activity.getSlidingPaneLayout().isSlideable()) {
365 if (!activity.shouldPaneBeOpen()) {
366 activity.getSlidingPaneLayout().closePane();
367 activity.getActionBar().setDisplayHomeAsUpEnabled(true);
368 activity.getActionBar().setTitle(conversation.getName(useSubject));
369 activity.invalidateOptionsMenu();
370
371 }
372 }
373 if (queuedPqpMessage != null) {
374 this.conversation.nextMessageEncryption = Message.ENCRYPTION_PGP;
375 Message message = new Message(conversation, queuedPqpMessage,
376 Message.ENCRYPTION_PGP);
377 sendPgpMessage(message);
378 }
379 if (conversation.getMode() == Conversation.MODE_MULTI) {
380 activity.xmppConnectionService
381 .setOnRenameListener(new OnRenameListener() {
382
383 @Override
384 public void onRename(final boolean success) {
385 activity.xmppConnectionService.updateConversation(conversation);
386 getActivity().runOnUiThread(new Runnable() {
387
388 @Override
389 public void run() {
390 if (success) {
391 Toast.makeText(
392 getActivity(),
393 "Your nickname has been changed",
394 Toast.LENGTH_SHORT).show();
395 } else {
396 Toast.makeText(getActivity(),
397 "Nichname is already in use",
398 Toast.LENGTH_SHORT).show();
399 }
400 }
401 });
402 }
403 });
404 }
405 }
406
407 public void updateMessages() {
408 ConversationActivity activity = (ConversationActivity) getActivity();
409 if (this.conversation != null) {
410 List<Message> encryptedMessages = new LinkedList<Message>();
411 for (Message message : this.conversation.getMessages()) {
412 if (message.getEncryption() == Message.ENCRYPTION_PGP) {
413 encryptedMessages.add(message);
414 }
415 }
416 if (encryptedMessages.size() > 0) {
417 DecryptMessage task = new DecryptMessage();
418 Message[] msgs = new Message[encryptedMessages.size()];
419 task.execute(encryptedMessages.toArray(msgs));
420 }
421 this.messageList.clear();
422 this.messageList.addAll(this.conversation.getMessages());
423 this.messageListAdapter.notifyDataSetChanged();
424 if (conversation.getMode() == Conversation.MODE_SINGLE) {
425 if (messageList.size() >= 1) {
426 int latestEncryption = this.conversation.getLatestMessage()
427 .getEncryption();
428 if (latestEncryption == Message.ENCRYPTION_DECRYPTED) {
429 conversation.nextMessageEncryption = Message.ENCRYPTION_PGP;
430 } else {
431 conversation.nextMessageEncryption = latestEncryption;
432 }
433 makeFingerprintWarning(latestEncryption);
434 }
435 } else {
436 if (conversation.getMucOptions().getError() != 0) {
437 mucError.setVisibility(View.VISIBLE);
438 if (conversation.getMucOptions().getError() == MucOptions.ERROR_NICK_IN_USE) {
439 mucErrorText.setText(getString(R.string.nick_in_use));
440 }
441 } else {
442 mucError.setVisibility(View.GONE);
443 }
444 }
445 getActivity().invalidateOptionsMenu();
446 updateChatMsgHint();
447 int size = this.messageList.size();
448 if (size >= 1)
449 messagesView.setSelection(size - 1);
450 if (!activity.shouldPaneBeOpen()) {
451 conversation.markRead();
452 // TODO update notifications
453 UIHelper.updateNotification(getActivity(),
454 activity.getConversationList(), null, false);
455 activity.updateConversationList();
456 }
457 }
458 }
459
460 protected void makeFingerprintWarning(int latestEncryption) {
461 final LinearLayout fingerprintWarning = (LinearLayout) getView()
462 .findViewById(R.id.new_fingerprint);
463 if (conversation.getContact() != null) {
464 Set<String> knownFingerprints = conversation.getContact()
465 .getOtrFingerprints();
466 if ((latestEncryption == Message.ENCRYPTION_OTR)
467 && (conversation.hasValidOtrSession()
468 && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
469 .contains(conversation.getOtrFingerprint())))) {
470 fingerprintWarning.setVisibility(View.VISIBLE);
471 TextView fingerprint = (TextView) getView().findViewById(
472 R.id.otr_fingerprint);
473 fingerprint.setText(conversation.getOtrFingerprint());
474 fingerprintWarning.setOnClickListener(new OnClickListener() {
475
476 @Override
477 public void onClick(View v) {
478 AlertDialog dialog = UIHelper
479 .getVerifyFingerprintDialog(
480 (ConversationActivity) getActivity(),
481 conversation, fingerprintWarning);
482 dialog.show();
483 }
484 });
485 } else {
486 fingerprintWarning.setVisibility(View.GONE);
487 }
488 } else {
489 fingerprintWarning.setVisibility(View.GONE);
490 }
491 }
492
493 protected void sendPlainTextMessage(Message message) {
494 ConversationActivity activity = (ConversationActivity) getActivity();
495 activity.xmppConnectionService.sendMessage(message, null);
496 chatMsg.setText("");
497 }
498
499 protected void sendPgpMessage(final Message message) {
500 ConversationActivity activity = (ConversationActivity) getActivity();
501 final XmppConnectionService xmppService = activity.xmppConnectionService;
502 Contact contact = message.getConversation().getContact();
503 Account account = message.getConversation().getAccount();
504 if (activity.hasPgp()) {
505 if (contact.getPgpKeyId() != 0) {
506 try {
507 message.setEncryptedBody(xmppService.getPgpEngine().encrypt(account, contact.getPgpKeyId(), message.getBody()));
508 xmppService.sendMessage(message, null);
509 chatMsg.setText("");
510 } catch (UserInputRequiredException e) {
511 try {
512 getActivity().startIntentSenderForResult(e.getPendingIntent().getIntentSender(),
513 ConversationActivity.REQUEST_SEND_MESSAGE, null, 0,
514 0, 0);
515 } catch (SendIntentException e1) {
516 Log.d("xmppService","failed to start intent to send message");
517 }
518 } catch (OpenPgpException e) {
519 Log.d("xmppService","error encrypting with pgp: "+e.getOpenPgpError().getMessage());
520 }
521 } else {
522 AlertDialog.Builder builder = new AlertDialog.Builder(
523 getActivity());
524 builder.setTitle("No openPGP key found");
525 builder.setIconAttribute(android.R.attr.alertDialogIcon);
526 builder.setMessage("There is no openPGP key associated with this contact");
527 builder.setNegativeButton("Cancel", null);
528 builder.setPositiveButton("Send plain text",
529 new DialogInterface.OnClickListener() {
530
531 @Override
532 public void onClick(DialogInterface dialog,
533 int which) {
534 conversation.nextMessageEncryption = Message.ENCRYPTION_NONE;
535 message.setEncryption(Message.ENCRYPTION_NONE);
536 xmppService.sendMessage(message, null);
537 chatMsg.setText("");
538 }
539 });
540 builder.create().show();
541 }
542 }
543 }
544
545 protected void sendOtrMessage(final Message message) {
546 ConversationActivity activity = (ConversationActivity) getActivity();
547 final XmppConnectionService xmppService = activity.xmppConnectionService;
548 if (conversation.hasValidOtrSession()) {
549 activity.xmppConnectionService.sendMessage(message, null);
550 chatMsg.setText("");
551 } else {
552 Hashtable<String, Integer> presences;
553 if (conversation.getContact() != null) {
554 presences = conversation.getContact().getPresences();
555 } else {
556 presences = null;
557 }
558 if ((presences == null) || (presences.size() == 0)) {
559 AlertDialog.Builder builder = new AlertDialog.Builder(
560 getActivity());
561 builder.setTitle("Contact is offline");
562 builder.setIconAttribute(android.R.attr.alertDialogIcon);
563 builder.setMessage("Sending OTR encrypted messages to an offline contact is impossible.");
564 builder.setPositiveButton("Send plain text",
565 new DialogInterface.OnClickListener() {
566
567 @Override
568 public void onClick(DialogInterface dialog,
569 int which) {
570 conversation.nextMessageEncryption = Message.ENCRYPTION_NONE;
571 message.setEncryption(Message.ENCRYPTION_NONE);
572 xmppService.sendMessage(message, null);
573 chatMsg.setText("");
574 }
575 });
576 builder.setNegativeButton("Cancel", null);
577 builder.create().show();
578 } else if (presences.size() == 1) {
579 xmppService.sendMessage(message, (String) presences.keySet()
580 .toArray()[0]);
581 chatMsg.setText("");
582 } else {
583 AlertDialog.Builder builder = new AlertDialog.Builder(
584 getActivity());
585 builder.setTitle("Choose Presence");
586 final String[] presencesArray = new String[presences.size()];
587 presences.keySet().toArray(presencesArray);
588 builder.setItems(presencesArray,
589 new DialogInterface.OnClickListener() {
590
591 @Override
592 public void onClick(DialogInterface dialog,
593 int which) {
594 xmppService.sendMessage(message,
595 presencesArray[which]);
596 chatMsg.setText("");
597 }
598 });
599 builder.create().show();
600 }
601 }
602 }
603
604 private static class ViewHolder {
605
606 protected ImageView image;
607 protected ImageView indicator;
608 protected TextView time;
609 protected TextView messageBody;
610 protected ImageView imageView;
611
612 }
613
614 private class BitmapCache {
615 private HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>();
616 private Bitmap error = null;
617
618 public Bitmap get(String name, Contact contact, Context context) {
619 if (bitmaps.containsKey(name)) {
620 return bitmaps.get(name);
621 } else {
622 Bitmap bm;
623 if (contact != null){
624 bm = UIHelper.getContactPicture(contact, 48, context, false);
625 } else {
626 bm = UIHelper.getContactPicture(name, 48, context, false);
627 }
628 bitmaps.put(name, bm);
629 return bm;
630 }
631 }
632
633 public Bitmap getError() {
634 if (error == null) {
635 error = UIHelper.getErrorPicture(200);
636 }
637 return error;
638 }
639 }
640
641 class DecryptMessage extends AsyncTask<Message, Void, Boolean> {
642
643 @Override
644 protected Boolean doInBackground(Message... params) {
645 final ConversationActivity activity = (ConversationActivity) getActivity();
646 askForPassphraseIntent = null;
647 for (int i = 0; i < params.length; ++i) {
648 if (params[i].getEncryption() == Message.ENCRYPTION_PGP) {
649 String body = params[i].getBody();
650 String decrypted = null;
651 if (activity == null) {
652 return false;
653 } else if (!activity.xmppConnectionServiceBound) {
654 return false;
655 }
656 try {
657 decrypted = activity.xmppConnectionService
658 .getPgpEngine().decrypt(conversation.getAccount(),body);
659 } catch (UserInputRequiredException e) {
660 askForPassphraseIntent = e.getPendingIntent()
661 .getIntentSender();
662 activity.runOnUiThread(new Runnable() {
663
664 @Override
665 public void run() {
666 pgpInfo.setVisibility(View.VISIBLE);
667 }
668 });
669
670 return false;
671
672 } catch (OpenPgpException e) {
673 Log.d("gultsch", "error decrypting pgp");
674 }
675 if (decrypted != null) {
676 params[i].setBody(decrypted);
677 params[i].setEncryption(Message.ENCRYPTION_DECRYPTED);
678 activity.xmppConnectionService.updateMessage(params[i]);
679 }
680 if (activity != null) {
681 activity.runOnUiThread(new Runnable() {
682
683 @Override
684 public void run() {
685 messageListAdapter.notifyDataSetChanged();
686 }
687 });
688 }
689 }
690 if (activity != null) {
691 activity.runOnUiThread(new Runnable() {
692
693 @Override
694 public void run() {
695 activity.updateConversationList();
696 }
697 });
698 }
699 }
700 return true;
701 }
702
703 }
704
705 public void setText(String text) {
706 this.pastedText = text;
707 }
708}