ConversationFragment.java

  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(getString(R.string.send_message_to_conference));
128		} else {
129			switch (conversation.nextMessageEncryption) {
130			case Message.ENCRYPTION_NONE:
131				chatMsg.setHint(getString(R.string.send_plain_text_message));
132				break;
133			case Message.ENCRYPTION_OTR:
134				chatMsg.setHint(getString(R.string.send_otr_message));
135				break;
136			case Message.ENCRYPTION_PGP:
137				chatMsg.setHint(getString(R.string.send_pgp_message));
138				break;
139			case Message.ENCRYPTION_DECRYPTED:
140				chatMsg.setHint(getString(R.string.send_pgp_message));
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.contact_picture = (ImageView) view
209								.findViewById(R.id.message_photo);
210						viewHolder.contact_picture.setImageBitmap(selfBitmap);
211						break;
212					case RECIEVED:
213						view = (View) inflater.inflate(
214								R.layout.message_recieved, null);
215						viewHolder.contact_picture = (ImageView) view
216								.findViewById(R.id.message_photo);
217						
218						if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
219
220							viewHolder.contact_picture.setImageBitmap(mBitmapCache
221									.get(item.getConversation().getName(useSubject), item
222											.getConversation().getContact(),
223											getActivity()
224													.getApplicationContext()));
225
226						}
227						break;
228					default:
229						viewHolder = null;
230						break;
231					}
232					viewHolder.indicator = (ImageView) view.findViewById(R.id.security_indicator);
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.contact_picture.setImageBitmap(mBitmapCache
246									.get(item.getCounterpart(), null,
247											getActivity()
248													.getApplicationContext()));
249						} else {
250							viewHolder.contact_picture.setImageBitmap(mBitmapCache
251									.get(item.getConversation().getName(useSubject),
252											null, getActivity()
253													.getApplicationContext()));
254						}
255					}
256				}
257				
258				if (item.getEncryption() == Message.ENCRYPTION_NONE) {
259					viewHolder.indicator.setVisibility(View.GONE);
260				} else {
261					viewHolder.indicator.setVisibility(View.VISIBLE);
262				}
263				
264				
265				if (item.getType() == Message.TYPE_IMAGE) {
266					if (item.getStatus() == Message.STATUS_PREPARING) {
267						viewHolder.image.setVisibility(View.GONE);
268						viewHolder.messageBody.setVisibility(View.VISIBLE);
269						viewHolder.messageBody.setText(getString(R.string.preparing_image));
270						viewHolder.messageBody.setTextColor(0xff33B5E5);
271						viewHolder.messageBody.setTypeface(null,Typeface.ITALIC);
272					} else if (item.getStatus() == Message.STATUS_RECIEVING) {
273						viewHolder.image.setVisibility(View.GONE);
274						viewHolder.messageBody.setVisibility(View.GONE);
275						viewHolder.messageBody.setVisibility(View.VISIBLE);
276						viewHolder.messageBody.setText(getString(R.string.receiving_image));
277						viewHolder.messageBody.setTextColor(0xff33B5E5);
278						viewHolder.messageBody.setTypeface(null,Typeface.ITALIC);
279					} else {
280						viewHolder.image.setImageBitmap(activity.xmppConnectionService.getFileBackend().getThumbnailFromMessage(item,(int) (metrics.density * 288)));
281						viewHolder.messageBody.setVisibility(View.GONE);
282						viewHolder.image.setVisibility(View.VISIBLE);
283					}
284				} else {
285					viewHolder.image.setVisibility(View.GONE);
286					viewHolder.messageBody.setVisibility(View.VISIBLE);
287					String body = item.getBody();
288					if (body != null) {
289						if (item.getEncryption() == Message.ENCRYPTION_PGP) {
290							viewHolder.messageBody
291									.setText(getString(R.string.encrypted_message));
292							viewHolder.messageBody.setTextColor(0xff33B5E5);
293							viewHolder.messageBody.setTypeface(null,
294									Typeface.ITALIC);
295						} else if ((item.getEncryption() == Message.ENCRYPTION_OTR)||(item.getEncryption() == Message.ENCRYPTION_DECRYPTED)) {
296							viewHolder.messageBody.setText(body.trim());
297							viewHolder.messageBody.setTextColor(0xff333333);
298							viewHolder.messageBody.setTypeface(null,
299									Typeface.NORMAL);
300						} else {
301							viewHolder.messageBody.setText(body.trim());
302							viewHolder.messageBody.setTextColor(0xff333333);
303							viewHolder.messageBody.setTypeface(null,
304									Typeface.NORMAL);
305						}
306					}
307				}
308				switch (item.getStatus()) {
309				case Message.STATUS_UNSEND:
310					viewHolder.time.setTypeface(null, Typeface.ITALIC);
311					viewHolder.time.setTextColor(0xFF8e8e8e);
312					viewHolder.time.setText("sending\u2026");
313					break;
314				case Message.STATUS_SEND_FAILED:
315					viewHolder.time.setText(getString(R.string.send_failed) + " \u00B7 " + UIHelper.readableTimeDifference(item
316							.getTimeSent()));
317					viewHolder.time.setTextColor(0xFFe92727);
318					viewHolder.time.setTypeface(null,Typeface.NORMAL);
319					break;
320				case Message.STATUS_SEND_REJECTED:
321					viewHolder.time.setText(getString(R.string.send_rejected));
322					viewHolder.time.setTextColor(0xFFe92727);
323					viewHolder.time.setTypeface(null,Typeface.NORMAL);
324					break;
325				default:
326					viewHolder.time.setTypeface(null, Typeface.NORMAL);
327					viewHolder.time.setTextColor(0xFF8e8e8e);
328					if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
329						viewHolder.time.setText(UIHelper
330								.readableTimeDifference(item.getTimeSent()));
331					} else {
332						viewHolder.time.setText(item.getCounterpart()
333								+ " \u00B7 "
334								+ UIHelper.readableTimeDifference(item
335										.getTimeSent()));
336					}
337					break;
338				}
339				return view;
340			}
341		};
342		messagesView.setAdapter(messageListAdapter);
343
344		return view;
345	}
346
347	protected Bitmap findSelfPicture() {
348		SharedPreferences sharedPref = PreferenceManager
349				.getDefaultSharedPreferences(getActivity()
350						.getApplicationContext());
351		boolean showPhoneSelfContactPicture = sharedPref.getBoolean(
352				"show_phone_selfcontact_picture", true);
353
354		return UIHelper.getSelfContactPicture(conversation.getAccount(), 48,
355				showPhoneSelfContactPicture, getActivity());
356	}
357
358	@Override
359	public void onStart() {
360		super.onStart();
361		this.activity = (ConversationActivity) getActivity();
362		SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
363		this.useSubject = preferences.getBoolean("use_subject_in_muc", true);
364		if (activity.xmppConnectionServiceBound) {
365			this.onBackendConnected();
366		}
367	}
368
369	public void onBackendConnected() {
370		this.conversation = activity.getSelectedConversation();
371		if (this.conversation == null) {
372			return;
373		}
374		this.selfBitmap = findSelfPicture();
375		updateMessages();
376		// rendering complete. now go tell activity to close pane
377		if (activity.getSlidingPaneLayout().isSlideable()) {
378			if (!activity.shouldPaneBeOpen()) {
379				activity.getSlidingPaneLayout().closePane();
380				activity.getActionBar().setDisplayHomeAsUpEnabled(true);
381				activity.getActionBar().setTitle(conversation.getName(useSubject));
382				activity.invalidateOptionsMenu();
383
384			}
385		}
386		if (queuedPqpMessage != null) {
387			this.conversation.nextMessageEncryption = Message.ENCRYPTION_PGP;
388			Message message = new Message(conversation, queuedPqpMessage,
389					Message.ENCRYPTION_PGP);
390			sendPgpMessage(message);
391		}
392		if (conversation.getMode() == Conversation.MODE_MULTI) {
393			activity.xmppConnectionService
394					.setOnRenameListener(new OnRenameListener() {
395
396						@Override
397						public void onRename(final boolean success) {
398							activity.xmppConnectionService.updateConversation(conversation);
399							getActivity().runOnUiThread(new Runnable() {
400
401								@Override
402								public void run() {
403									if (success) {
404										Toast.makeText(
405												getActivity(),
406												getString(R.string.your_nick_has_been_changed),
407												Toast.LENGTH_SHORT).show();
408									} else {
409										Toast.makeText(getActivity(),
410												getString(R.string.nick_in_use),
411												Toast.LENGTH_SHORT).show();
412									}
413								}
414							});
415						}
416					});
417		}
418	}
419
420	public void updateMessages() {
421		ConversationActivity activity = (ConversationActivity) getActivity();
422		if (this.conversation != null) {
423			List<Message> encryptedMessages = new LinkedList<Message>();
424			for (Message message : this.conversation.getMessages()) {
425				if (message.getEncryption() == Message.ENCRYPTION_PGP) {
426					encryptedMessages.add(message);
427				}
428			}
429			if (encryptedMessages.size() > 0) {
430				DecryptMessage task = new DecryptMessage();
431				Message[] msgs = new Message[encryptedMessages.size()];
432				task.execute(encryptedMessages.toArray(msgs));
433			}
434			this.messageList.clear();
435			this.messageList.addAll(this.conversation.getMessages());
436			this.messageListAdapter.notifyDataSetChanged();
437			if (conversation.getMode() == Conversation.MODE_SINGLE) {
438				if (messageList.size() >= 1) {
439					int latestEncryption = this.conversation.getLatestMessage()
440							.getEncryption();
441					if (latestEncryption == Message.ENCRYPTION_DECRYPTED) {
442						conversation.nextMessageEncryption = Message.ENCRYPTION_PGP;
443					} else {
444						conversation.nextMessageEncryption = latestEncryption;
445					}
446					makeFingerprintWarning(latestEncryption);
447				}
448			} else {
449				if (conversation.getMucOptions().getError() != 0) {
450					mucError.setVisibility(View.VISIBLE);
451					if (conversation.getMucOptions().getError() == MucOptions.ERROR_NICK_IN_USE) {
452						mucErrorText.setText(getString(R.string.nick_in_use));
453					}
454				} else {
455					mucError.setVisibility(View.GONE);
456				}
457			}
458			getActivity().invalidateOptionsMenu();
459			updateChatMsgHint();
460			int size = this.messageList.size();
461			if (size >= 1)
462				messagesView.setSelection(size - 1);
463			if (!activity.shouldPaneBeOpen()) {
464				conversation.markRead();
465				// TODO update notifications
466				UIHelper.updateNotification(getActivity(),
467						activity.getConversationList(), null, false);
468				activity.updateConversationList();
469			}
470		}
471	}
472
473	protected void makeFingerprintWarning(int latestEncryption) {
474		final LinearLayout fingerprintWarning = (LinearLayout) getView()
475				.findViewById(R.id.new_fingerprint);
476		if (conversation.getContact() != null) {
477			Set<String> knownFingerprints = conversation.getContact()
478					.getOtrFingerprints();
479			if ((latestEncryption == Message.ENCRYPTION_OTR)
480					&& (conversation.hasValidOtrSession()
481							&& (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
482								.contains(conversation.getOtrFingerprint())))) {
483				fingerprintWarning.setVisibility(View.VISIBLE);
484				TextView fingerprint = (TextView) getView().findViewById(
485						R.id.otr_fingerprint);
486				fingerprint.setText(conversation.getOtrFingerprint());
487				fingerprintWarning.setOnClickListener(new OnClickListener() {
488
489					@Override
490					public void onClick(View v) {
491						AlertDialog dialog = UIHelper
492								.getVerifyFingerprintDialog(
493										(ConversationActivity) getActivity(),
494										conversation, fingerprintWarning);
495						dialog.show();
496					}
497				});
498			} else {
499				fingerprintWarning.setVisibility(View.GONE);
500			}
501		} else {
502			fingerprintWarning.setVisibility(View.GONE);
503		}
504	}
505
506	protected void sendPlainTextMessage(Message message) {
507		ConversationActivity activity = (ConversationActivity) getActivity();
508		activity.xmppConnectionService.sendMessage(message, null);
509		chatMsg.setText("");
510	}
511
512	protected void sendPgpMessage(final Message message) {
513		ConversationActivity activity = (ConversationActivity) getActivity();
514		final XmppConnectionService xmppService = activity.xmppConnectionService;
515		Contact contact = message.getConversation().getContact();
516		Account account = message.getConversation().getAccount();
517		if (activity.hasPgp()) {
518			if (contact.getPgpKeyId() != 0) {
519				try {
520					message.setEncryptedBody(xmppService.getPgpEngine().encrypt(account, contact.getPgpKeyId(), message.getBody()));
521					xmppService.sendMessage(message, null);
522					chatMsg.setText("");
523				} catch (UserInputRequiredException e) {
524					try {
525						getActivity().startIntentSenderForResult(e.getPendingIntent().getIntentSender(),
526								ConversationActivity.REQUEST_SEND_MESSAGE, null, 0,
527								0, 0);
528					} catch (SendIntentException e1) {
529						Log.d("xmppService","failed to start intent to send message");
530					}
531				} catch (OpenPgpException e) {
532					Log.d("xmppService","error encrypting with pgp: "+e.getOpenPgpError().getMessage());
533				}
534			} else {
535				AlertDialog.Builder builder = new AlertDialog.Builder(
536						getActivity());
537				builder.setTitle("No openPGP key found");
538				builder.setIconAttribute(android.R.attr.alertDialogIcon);
539				builder.setMessage("There is no openPGP key associated with this contact");
540				builder.setNegativeButton("Cancel", null);
541				builder.setPositiveButton("Send plain text",
542						new DialogInterface.OnClickListener() {
543
544							@Override
545							public void onClick(DialogInterface dialog,
546									int which) {
547								conversation.nextMessageEncryption = Message.ENCRYPTION_NONE;
548								message.setEncryption(Message.ENCRYPTION_NONE);
549								xmppService.sendMessage(message, null);
550								chatMsg.setText("");
551							}
552						});
553				builder.create().show();
554			}
555		}
556	}
557
558	protected void sendOtrMessage(final Message message) {
559		ConversationActivity activity = (ConversationActivity) getActivity();
560		final XmppConnectionService xmppService = activity.xmppConnectionService;
561		if (conversation.hasValidOtrSession()) {
562			activity.xmppConnectionService.sendMessage(message, null);
563			chatMsg.setText("");
564		} else {
565			Hashtable<String, Integer> presences;
566			if (conversation.getContact() != null) {
567				presences = conversation.getContact().getPresences();
568			} else {
569				presences = null;
570			}
571			if ((presences == null) || (presences.size() == 0)) {
572				AlertDialog.Builder builder = new AlertDialog.Builder(
573						getActivity());
574				builder.setTitle("Contact is offline");
575				builder.setIconAttribute(android.R.attr.alertDialogIcon);
576				builder.setMessage("Sending OTR encrypted messages to an offline contact is impossible.");
577				builder.setPositiveButton("Send plain text",
578						new DialogInterface.OnClickListener() {
579
580							@Override
581							public void onClick(DialogInterface dialog,
582									int which) {
583								conversation.nextMessageEncryption = Message.ENCRYPTION_NONE;
584								message.setEncryption(Message.ENCRYPTION_NONE);
585								xmppService.sendMessage(message, null);
586								chatMsg.setText("");
587							}
588						});
589				builder.setNegativeButton("Cancel", null);
590				builder.create().show();
591			} else if (presences.size() == 1) {
592				xmppService.sendMessage(message, (String) presences.keySet()
593						.toArray()[0]);
594				chatMsg.setText("");
595			} else {
596				AlertDialog.Builder builder = new AlertDialog.Builder(
597						getActivity());
598				builder.setTitle("Choose Presence");
599				final String[] presencesArray = new String[presences.size()];
600				presences.keySet().toArray(presencesArray);
601				builder.setItems(presencesArray,
602						new DialogInterface.OnClickListener() {
603
604							@Override
605							public void onClick(DialogInterface dialog,
606									int which) {
607								xmppService.sendMessage(message,
608										presencesArray[which]);
609								chatMsg.setText("");
610							}
611						});
612				builder.create().show();
613			}
614		}
615	}
616
617	private static class ViewHolder {
618
619		protected ImageView image;
620		protected ImageView indicator;
621		protected TextView time;
622		protected TextView messageBody;
623		protected ImageView contact_picture;
624
625	}
626
627	private class BitmapCache {
628		private HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>();
629		private Bitmap error = null;
630
631		public Bitmap get(String name, Contact contact, Context context) {
632			if (bitmaps.containsKey(name)) {
633				return bitmaps.get(name);
634			} else {
635				Bitmap bm;
636				if (contact != null){
637					bm = UIHelper.getContactPicture(contact, 48, context, false);
638				} else {
639					bm = UIHelper.getContactPicture(name, 48, context, false);
640				}
641				bitmaps.put(name, bm);
642				return bm;
643			}
644		}
645
646		public Bitmap getError() {
647			if (error == null) {
648				error = UIHelper.getErrorPicture(200);
649			}
650			return error;
651		}
652	}
653
654	class DecryptMessage extends AsyncTask<Message, Void, Boolean> {
655
656		@Override
657		protected Boolean doInBackground(Message... params) {
658			final ConversationActivity activity = (ConversationActivity) getActivity();
659			askForPassphraseIntent = null;
660			for (int i = 0; i < params.length; ++i) {
661				if (params[i].getEncryption() == Message.ENCRYPTION_PGP) {
662					String body = params[i].getBody();
663					String decrypted = null;
664					if (activity == null) {
665						return false;
666					} else if (!activity.xmppConnectionServiceBound) {
667						return false;
668					}
669					try {
670						decrypted = activity.xmppConnectionService
671								.getPgpEngine().decrypt(conversation.getAccount(),body);
672					} catch (UserInputRequiredException e) {
673						askForPassphraseIntent = e.getPendingIntent()
674								.getIntentSender();
675						activity.runOnUiThread(new Runnable() {
676
677							@Override
678							public void run() {
679								pgpInfo.setVisibility(View.VISIBLE);
680							}
681						});
682
683						return false;
684
685					} catch (OpenPgpException e) {
686						Log.d("gultsch", "error decrypting pgp");
687					}
688					if (decrypted != null) {
689						params[i].setBody(decrypted);
690						params[i].setEncryption(Message.ENCRYPTION_DECRYPTED);
691						activity.xmppConnectionService.updateMessage(params[i]);
692					}
693					if (activity != null) {
694						activity.runOnUiThread(new Runnable() {
695
696							@Override
697							public void run() {
698								messageListAdapter.notifyDataSetChanged();
699							}
700						});
701					}
702				}
703				if (activity != null) {
704					activity.runOnUiThread(new Runnable() {
705
706						@Override
707						public void run() {
708							activity.updateConversationList();
709						}
710					});
711				}
712			}
713			return true;
714		}
715
716	}
717
718	public void setText(String text) {
719		this.pastedText = text;
720	}
721}