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