1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import eu.siacs.conversations.R;
7import eu.siacs.conversations.entities.Contact;
8import eu.siacs.conversations.entities.Conversation;
9import eu.siacs.conversations.entities.Message;
10import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
11import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
12import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
13import eu.siacs.conversations.ui.adapter.ConversationAdapter;
14import eu.siacs.conversations.utils.ExceptionHelper;
15import eu.siacs.conversations.utils.UIHelper;
16import android.net.Uri;
17import android.os.Bundle;
18import android.os.SystemClock;
19import android.provider.MediaStore;
20import android.annotation.SuppressLint;
21import android.app.ActionBar;
22import android.app.AlertDialog;
23import android.app.FragmentTransaction;
24import android.app.PendingIntent;
25import android.content.DialogInterface;
26import android.content.DialogInterface.OnClickListener;
27import android.content.IntentSender.SendIntentException;
28import android.content.Intent;
29import android.support.v4.widget.SlidingPaneLayout;
30import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
31import android.view.KeyEvent;
32import android.view.Menu;
33import android.view.MenuItem;
34import android.view.View;
35import android.widget.AdapterView;
36import android.widget.AdapterView.OnItemClickListener;
37import android.widget.ArrayAdapter;
38import android.widget.CheckBox;
39import android.widget.ListView;
40import android.widget.PopupMenu;
41import android.widget.PopupMenu.OnMenuItemClickListener;
42import android.widget.Toast;
43
44public class ConversationActivity extends XmppActivity implements
45 OnAccountUpdate, OnConversationUpdate, OnRosterUpdate {
46
47 public static final String VIEW_CONVERSATION = "viewConversation";
48 public static final String CONVERSATION = "conversationUuid";
49 public static final String TEXT = "text";
50 public static final String PRESENCE = "eu.siacs.conversations.presence";
51
52 public static final int REQUEST_SEND_MESSAGE = 0x0201;
53 public static final int REQUEST_DECRYPT_PGP = 0x0202;
54 private static final int REQUEST_ATTACH_FILE_DIALOG = 0x0203;
55 private static final int REQUEST_IMAGE_CAPTURE = 0x0204;
56 private static final int REQUEST_RECORD_AUDIO = 0x0205;
57 private static final int REQUEST_SEND_PGP_IMAGE = 0x0206;
58 public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207;
59
60 private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301;
61 private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
62 private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0303;
63
64 protected SlidingPaneLayout spl;
65
66 private List<Conversation> conversationList = new ArrayList<Conversation>();
67 private Conversation selectedConversation = null;
68 private ListView listView;
69
70 private boolean paneShouldBeOpen = true;
71 private ArrayAdapter<Conversation> listAdapter;
72
73 protected ConversationActivity activity = this;
74 private Toast prepareImageToast;
75
76 private Uri pendingImageUri = null;
77
78 public List<Conversation> getConversationList() {
79 return this.conversationList;
80 }
81
82 public Conversation getSelectedConversation() {
83 return this.selectedConversation;
84 }
85
86 public void setSelectedConversation(Conversation conversation) {
87 this.selectedConversation = conversation;
88 }
89
90 public ListView getConversationListView() {
91 return this.listView;
92 }
93
94 public SlidingPaneLayout getSlidingPaneLayout() {
95 return this.spl;
96 }
97
98 public boolean shouldPaneBeOpen() {
99 return paneShouldBeOpen;
100 }
101
102 @Override
103 protected void onCreate(Bundle savedInstanceState) {
104 super.onCreate(savedInstanceState);
105
106 setContentView(R.layout.fragment_conversations_overview);
107
108 listView = (ListView) findViewById(R.id.list);
109
110 getActionBar().setDisplayHomeAsUpEnabled(false);
111 getActionBar().setHomeButtonEnabled(false);
112
113 this.listAdapter = new ConversationAdapter(this, conversationList);
114 listView.setAdapter(this.listAdapter);
115
116 listView.setOnItemClickListener(new OnItemClickListener() {
117
118 @Override
119 public void onItemClick(AdapterView<?> arg0, View clickedView,
120 int position, long arg3) {
121 paneShouldBeOpen = false;
122 if (getSelectedConversation() != conversationList.get(position)) {
123 setSelectedConversation(conversationList.get(position));
124 swapConversationFragment();
125 } else {
126 spl.closePane();
127 }
128 }
129 });
130 spl = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
131 spl.setParallaxDistance(150);
132 spl.setShadowResource(R.drawable.es_slidingpane_shadow);
133 spl.setSliderFadeColor(0);
134 spl.setPanelSlideListener(new PanelSlideListener() {
135
136 @Override
137 public void onPanelOpened(View arg0) {
138 paneShouldBeOpen = true;
139 ActionBar ab = getActionBar();
140 if (ab != null) {
141 ab.setDisplayHomeAsUpEnabled(false);
142 ab.setHomeButtonEnabled(false);
143 ab.setTitle(R.string.app_name);
144 }
145 invalidateOptionsMenu();
146 hideKeyboard();
147 }
148
149 @Override
150 public void onPanelClosed(View arg0) {
151 paneShouldBeOpen = false;
152 if ((conversationList.size() > 0)
153 && (getSelectedConversation() != null)) {
154 ActionBar ab = getActionBar();
155 if (ab != null) {
156 ab.setDisplayHomeAsUpEnabled(true);
157 ab.setHomeButtonEnabled(true);
158 if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE
159 || activity.useSubjectToIdentifyConference()) {
160 ab.setTitle(getSelectedConversation().getName());
161 } else {
162 ab.setTitle(getSelectedConversation()
163 .getContactJid().split("/")[0]);
164 }
165 }
166 invalidateOptionsMenu();
167 if (!getSelectedConversation().isRead()) {
168 xmppConnectionService
169 .markRead(getSelectedConversation());
170 listView.invalidateViews();
171 }
172 }
173 }
174
175 @Override
176 public void onPanelSlide(View arg0, float arg1) {
177 // TODO Auto-generated method stub
178
179 }
180 });
181 }
182
183 @Override
184 public boolean onCreateOptionsMenu(Menu menu) {
185 getMenuInflater().inflate(R.menu.conversations, menu);
186 MenuItem menuSecure = (MenuItem) menu.findItem(R.id.action_security);
187 MenuItem menuArchive = (MenuItem) menu.findItem(R.id.action_archive);
188 MenuItem menuMucDetails = (MenuItem) menu
189 .findItem(R.id.action_muc_details);
190 MenuItem menuContactDetails = (MenuItem) menu
191 .findItem(R.id.action_contact_details);
192 MenuItem menuAttach = (MenuItem) menu.findItem(R.id.action_attach_file);
193 MenuItem menuClearHistory = (MenuItem) menu
194 .findItem(R.id.action_clear_history);
195 MenuItem menuAdd = (MenuItem) menu.findItem(R.id.action_add);
196 MenuItem menuInviteContact = (MenuItem) menu
197 .findItem(R.id.action_invite);
198 MenuItem menuMute = (MenuItem) menu.findItem(R.id.action_mute);
199
200 if ((spl.isOpen() && (spl.isSlideable()))) {
201 menuArchive.setVisible(false);
202 menuMucDetails.setVisible(false);
203 menuContactDetails.setVisible(false);
204 menuSecure.setVisible(false);
205 menuInviteContact.setVisible(false);
206 menuAttach.setVisible(false);
207 menuClearHistory.setVisible(false);
208 menuMute.setVisible(false);
209 } else {
210 menuAdd.setVisible(!spl.isSlideable());
211 if (this.getSelectedConversation() != null) {
212 if (this.getSelectedConversation().getLatestMessage()
213 .getEncryption() != Message.ENCRYPTION_NONE) {
214 menuSecure.setIcon(R.drawable.ic_action_secure);
215 }
216 if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
217 menuContactDetails.setVisible(false);
218 menuAttach.setVisible(false);
219 } else {
220 menuMucDetails.setVisible(false);
221 menuInviteContact.setVisible(false);
222 }
223 }
224 }
225 return true;
226 }
227
228 private void selectPresenceToAttachFile(final int attachmentChoice) {
229 selectPresence(getSelectedConversation(), new OnPresenceSelected() {
230
231 @Override
232 public void onPresenceSelected() {
233 if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) {
234 pendingImageUri = xmppConnectionService.getFileBackend()
235 .getTakePhotoUri();
236 Intent takePictureIntent = new Intent(
237 MediaStore.ACTION_IMAGE_CAPTURE);
238 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
239 pendingImageUri);
240 if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
241 startActivityForResult(takePictureIntent,
242 REQUEST_IMAGE_CAPTURE);
243 }
244 } else if (attachmentChoice == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
245 Intent attachFileIntent = new Intent();
246 attachFileIntent.setType("image/*");
247 attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
248 Intent chooser = Intent.createChooser(attachFileIntent,
249 getString(R.string.attach_file));
250 startActivityForResult(chooser, REQUEST_ATTACH_FILE_DIALOG);
251 } else if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) {
252 Intent intent = new Intent(
253 MediaStore.Audio.Media.RECORD_SOUND_ACTION);
254 startActivityForResult(intent, REQUEST_RECORD_AUDIO);
255 }
256 }
257 });
258 }
259
260 private void attachFile(final int attachmentChoice) {
261 final Conversation conversation = getSelectedConversation();
262 if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
263 if (hasPgp()) {
264 if (conversation.getContact().getPgpKeyId() != 0) {
265 xmppConnectionService.getPgpEngine().hasKey(
266 conversation.getContact(),
267 new UiCallback<Contact>() {
268
269 @Override
270 public void userInputRequried(PendingIntent pi,
271 Contact contact) {
272 ConversationActivity.this.runIntent(pi,
273 attachmentChoice);
274 }
275
276 @Override
277 public void success(Contact contact) {
278 selectPresenceToAttachFile(attachmentChoice);
279 }
280
281 @Override
282 public void error(int error, Contact contact) {
283 displayErrorDialog(error);
284 }
285 });
286 } else {
287 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
288 .findFragmentByTag("conversation");
289 if (fragment != null) {
290 fragment.showNoPGPKeyDialog(false,
291 new OnClickListener() {
292
293 @Override
294 public void onClick(DialogInterface dialog,
295 int which) {
296 conversation
297 .setNextEncryption(Message.ENCRYPTION_NONE);
298 xmppConnectionService.databaseBackend
299 .updateConversation(conversation);
300 selectPresenceToAttachFile(attachmentChoice);
301 }
302 });
303 }
304 }
305 } else {
306 showInstallPgpDialog();
307 }
308 } else if (getSelectedConversation().getNextEncryption(
309 forceEncryption()) == Message.ENCRYPTION_NONE) {
310 selectPresenceToAttachFile(attachmentChoice);
311 } else {
312 selectPresenceToAttachFile(attachmentChoice);
313 }
314 }
315
316 @Override
317 public boolean onOptionsItemSelected(MenuItem item) {
318 if (item.getItemId() == android.R.id.home) {
319 spl.openPane();
320 return true;
321 } else if (item.getItemId() == R.id.action_add) {
322 startActivity(new Intent(this, StartConversationActivity.class));
323 return true;
324 } else if (getSelectedConversation() != null) {
325 switch (item.getItemId()) {
326 case R.id.action_attach_file:
327 attachFileDialog();
328 break;
329 case R.id.action_archive:
330 this.endConversation(getSelectedConversation());
331 break;
332 case R.id.action_contact_details:
333 Contact contact = this.getSelectedConversation().getContact();
334 if (contact.showInRoster()) {
335 switchToContactDetails(contact);
336 } else {
337 showAddToRosterDialog(getSelectedConversation());
338 }
339 break;
340 case R.id.action_muc_details:
341 Intent intent = new Intent(this,
342 ConferenceDetailsActivity.class);
343 intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
344 intent.putExtra("uuid", getSelectedConversation().getUuid());
345 startActivity(intent);
346 break;
347 case R.id.action_invite:
348 inviteToConversation(getSelectedConversation());
349 break;
350 case R.id.action_security:
351 selectEncryptionDialog(getSelectedConversation());
352 break;
353 case R.id.action_clear_history:
354 clearHistoryDialog(getSelectedConversation());
355 break;
356 case R.id.action_mute:
357 muteConversationDialog(getSelectedConversation());
358 break;
359 default:
360 break;
361 }
362 return super.onOptionsItemSelected(item);
363 } else {
364 return super.onOptionsItemSelected(item);
365 }
366 }
367
368 public void endConversation(Conversation conversation) {
369 conversation.setStatus(Conversation.STATUS_ARCHIVED);
370 paneShouldBeOpen = true;
371 spl.openPane();
372 xmppConnectionService.archiveConversation(conversation);
373 if (conversationList.size() > 0) {
374 setSelectedConversation(conversationList.get(0));
375 } else {
376 setSelectedConversation(null);
377 }
378 }
379
380 @SuppressLint("InflateParams")
381 protected void clearHistoryDialog(final Conversation conversation) {
382 AlertDialog.Builder builder = new AlertDialog.Builder(this);
383 builder.setTitle(getString(R.string.clear_conversation_history));
384 View dialogView = getLayoutInflater().inflate(
385 R.layout.dialog_clear_history, null);
386 final CheckBox endConversationCheckBox = (CheckBox) dialogView
387 .findViewById(R.id.end_conversation_checkbox);
388 builder.setView(dialogView);
389 builder.setNegativeButton(getString(R.string.cancel), null);
390 builder.setPositiveButton(getString(R.string.delete_messages),
391 new OnClickListener() {
392
393 @Override
394 public void onClick(DialogInterface dialog, int which) {
395 activity.xmppConnectionService
396 .clearConversationHistory(conversation);
397 if (endConversationCheckBox.isChecked()) {
398 endConversation(conversation);
399 }
400 }
401 });
402 builder.create().show();
403 }
404
405 protected void attachFileDialog() {
406 View menuAttachFile = findViewById(R.id.action_attach_file);
407 if (menuAttachFile == null) {
408 return;
409 }
410 PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile);
411 attachFilePopup.inflate(R.menu.attachment_choices);
412 attachFilePopup
413 .setOnMenuItemClickListener(new OnMenuItemClickListener() {
414
415 @Override
416 public boolean onMenuItemClick(MenuItem item) {
417 switch (item.getItemId()) {
418 case R.id.attach_choose_picture:
419 attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
420 break;
421 case R.id.attach_take_picture:
422 attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
423 break;
424 case R.id.attach_record_voice:
425 attachFile(ATTACHMENT_CHOICE_RECORD_VOICE);
426 break;
427 }
428 return false;
429 }
430 });
431 attachFilePopup.show();
432 }
433
434 protected void selectEncryptionDialog(final Conversation conversation) {
435 View menuItemView = findViewById(R.id.action_security);
436 if (menuItemView == null) {
437 return;
438 }
439 PopupMenu popup = new PopupMenu(this, menuItemView);
440 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
441 .findFragmentByTag("conversation");
442 if (fragment != null) {
443 popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
444
445 @Override
446 public boolean onMenuItemClick(MenuItem item) {
447 switch (item.getItemId()) {
448 case R.id.encryption_choice_none:
449 conversation.setNextEncryption(Message.ENCRYPTION_NONE);
450 item.setChecked(true);
451 break;
452 case R.id.encryption_choice_otr:
453 conversation.setNextEncryption(Message.ENCRYPTION_OTR);
454 item.setChecked(true);
455 break;
456 case R.id.encryption_choice_pgp:
457 if (hasPgp()) {
458 if (conversation.getAccount().getKeys()
459 .has("pgp_signature")) {
460 conversation
461 .setNextEncryption(Message.ENCRYPTION_PGP);
462 item.setChecked(true);
463 } else {
464 announcePgp(conversation.getAccount(),
465 conversation);
466 }
467 } else {
468 showInstallPgpDialog();
469 }
470 break;
471 default:
472 conversation.setNextEncryption(Message.ENCRYPTION_NONE);
473 break;
474 }
475 xmppConnectionService.databaseBackend
476 .updateConversation(conversation);
477 fragment.updateChatMsgHint();
478 return true;
479 }
480 });
481 popup.inflate(R.menu.encryption_choices);
482 MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr);
483 MenuItem none = popup.getMenu().findItem(
484 R.id.encryption_choice_none);
485 if (conversation.getMode() == Conversation.MODE_MULTI) {
486 otr.setEnabled(false);
487 } else {
488 if (forceEncryption()) {
489 none.setVisible(false);
490 }
491 }
492 switch (conversation.getNextEncryption(forceEncryption())) {
493 case Message.ENCRYPTION_NONE:
494 none.setChecked(true);
495 break;
496 case Message.ENCRYPTION_OTR:
497 otr.setChecked(true);
498 break;
499 case Message.ENCRYPTION_PGP:
500 popup.getMenu().findItem(R.id.encryption_choice_pgp)
501 .setChecked(true);
502 break;
503 default:
504 popup.getMenu().findItem(R.id.encryption_choice_none)
505 .setChecked(true);
506 break;
507 }
508 popup.show();
509 }
510 }
511
512 protected void muteConversationDialog(final Conversation conversation) {
513 AlertDialog.Builder builder = new AlertDialog.Builder(this);
514 builder.setTitle(R.string.disable_notifications_for_this_conversation);
515 final int[] durations = getResources().getIntArray(
516 R.array.mute_options_durations);
517 builder.setItems(R.array.mute_options_descriptions,
518 new OnClickListener() {
519
520 @Override
521 public void onClick(DialogInterface dialog, int which) {
522 long till;
523 if (durations[which] == -1) {
524 till = Long.MAX_VALUE;
525 } else {
526 till = SystemClock.elapsedRealtime()
527 + (durations[which] * 1000);
528 }
529 conversation.setMutedTill(till);
530 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
531 .findFragmentByTag("conversation");
532 if (selectedFragment != null) {
533 selectedFragment.updateMessages();
534 }
535 }
536 });
537 builder.create().show();
538 }
539
540 protected ConversationFragment swapConversationFragment() {
541 ConversationFragment selectedFragment = new ConversationFragment();
542 if (!isFinishing()) {
543
544 FragmentTransaction transaction = getFragmentManager()
545 .beginTransaction();
546 transaction.replace(R.id.selected_conversation, selectedFragment,
547 "conversation");
548
549 transaction.commitAllowingStateLoss();
550 }
551 return selectedFragment;
552 }
553
554 @Override
555 public boolean onKeyDown(int keyCode, KeyEvent event) {
556 if (keyCode == KeyEvent.KEYCODE_BACK) {
557 if (!spl.isOpen()) {
558 spl.openPane();
559 return false;
560 }
561 }
562 return super.onKeyDown(keyCode, event);
563 }
564
565 @Override
566 protected void onNewIntent(Intent intent) {
567 if (xmppConnectionServiceBound) {
568 if ((Intent.ACTION_VIEW.equals(intent.getAction()) && (VIEW_CONVERSATION
569 .equals(intent.getType())))) {
570 String convToView = (String) intent.getExtras().get(
571 CONVERSATION);
572 updateConversationList();
573 for (int i = 0; i < conversationList.size(); ++i) {
574 if (conversationList.get(i).getUuid().equals(convToView)) {
575 setSelectedConversation(conversationList.get(i));
576 break;
577 }
578 }
579 paneShouldBeOpen = false;
580 String text = intent.getExtras().getString(TEXT, null);
581 swapConversationFragment().setText(text);
582 }
583 } else {
584 handledViewIntent = false;
585 setIntent(intent);
586 }
587 }
588
589 @Override
590 public void onStart() {
591 super.onStart();
592 if (this.xmppConnectionServiceBound) {
593 this.onBackendConnected();
594 }
595 if (conversationList.size() >= 1) {
596 this.onConversationUpdate();
597 }
598 }
599
600 @Override
601 protected void onStop() {
602 if (xmppConnectionServiceBound) {
603 xmppConnectionService.removeOnConversationListChangedListener();
604 xmppConnectionService.removeOnAccountListChangedListener();
605 xmppConnectionService.removeOnRosterUpdateListener();
606 }
607 super.onStop();
608 }
609
610 @Override
611 void onBackendConnected() {
612 this.registerListener();
613 if (conversationList.size() == 0) {
614 updateConversationList();
615 }
616
617 if (getSelectedConversation() != null && pendingImageUri != null) {
618 attachImageToConversation(getSelectedConversation(),
619 pendingImageUri);
620 pendingImageUri = null;
621 } else {
622 pendingImageUri = null;
623 }
624
625 if ((getIntent().getAction() != null)
626 && (getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) {
627 if (getIntent().getType().equals(
628 ConversationActivity.VIEW_CONVERSATION)) {
629 handledViewIntent = true;
630
631 String convToView = (String) getIntent().getExtras().get(
632 CONVERSATION);
633
634 for (int i = 0; i < conversationList.size(); ++i) {
635 if (conversationList.get(i).getUuid().equals(convToView)) {
636 setSelectedConversation(conversationList.get(i));
637 }
638 }
639 paneShouldBeOpen = false;
640 String text = getIntent().getExtras().getString(TEXT, null);
641 swapConversationFragment().setText(text);
642 }
643 } else {
644 if (xmppConnectionService.getAccounts().size() == 0) {
645 startActivity(new Intent(this, EditAccountActivity.class));
646 } else if (conversationList.size() <= 0) {
647 // add no history
648 startActivity(new Intent(this, StartConversationActivity.class));
649 finish();
650 } else {
651 spl.openPane();
652 // find currently loaded fragment
653 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
654 .findFragmentByTag("conversation");
655 if (selectedFragment != null) {
656 selectedFragment.onBackendConnected();
657 } else {
658 setSelectedConversation(conversationList.get(0));
659 swapConversationFragment();
660 }
661 ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
662 }
663 }
664 }
665
666 public void registerListener() {
667 if (xmppConnectionServiceBound) {
668 xmppConnectionService.setOnConversationListChangedListener(this);
669 xmppConnectionService.setOnAccountListChangedListener(this);
670 xmppConnectionService.setOnRosterUpdateListener(this);
671 }
672 }
673
674 @Override
675 protected void onActivityResult(int requestCode, int resultCode,
676 final Intent data) {
677 super.onActivityResult(requestCode, resultCode, data);
678 if (resultCode == RESULT_OK) {
679 if (requestCode == REQUEST_DECRYPT_PGP) {
680 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
681 .findFragmentByTag("conversation");
682 if (selectedFragment != null) {
683 selectedFragment.hideSnackbar();
684 }
685 } else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) {
686 pendingImageUri = data.getData();
687 if (xmppConnectionServiceBound) {
688 attachImageToConversation(getSelectedConversation(),
689 pendingImageUri);
690 pendingImageUri = null;
691 }
692 } else if (requestCode == REQUEST_SEND_PGP_IMAGE) {
693
694 } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
695 attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
696 } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
697 attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
698 } else if (requestCode == REQUEST_ANNOUNCE_PGP) {
699 announcePgp(getSelectedConversation().getAccount(),
700 getSelectedConversation());
701 } else if (requestCode == REQUEST_ENCRYPT_MESSAGE) {
702 // encryptTextMessage();
703 } else if (requestCode == REQUEST_IMAGE_CAPTURE) {
704 if (xmppConnectionServiceBound) {
705 attachImageToConversation(getSelectedConversation(),
706 pendingImageUri);
707 pendingImageUri = null;
708 }
709 Intent intent = new Intent(
710 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
711 intent.setData(pendingImageUri);
712 sendBroadcast(intent);
713 } else if (requestCode == REQUEST_RECORD_AUDIO) {
714 attachAudioToConversation(getSelectedConversation(),
715 data.getData());
716 }
717 }
718 }
719
720 private void attachAudioToConversation(Conversation conversation, Uri uri) {
721
722 }
723
724 private void attachImageToConversation(Conversation conversation, Uri uri) {
725 prepareImageToast = Toast.makeText(getApplicationContext(),
726 getText(R.string.preparing_image), Toast.LENGTH_LONG);
727 prepareImageToast.show();
728 xmppConnectionService.attachImageToConversation(conversation, uri,
729 new UiCallback<Message>() {
730
731 @Override
732 public void userInputRequried(PendingIntent pi,
733 Message object) {
734 hidePrepareImageToast();
735 ConversationActivity.this.runIntent(pi,
736 ConversationActivity.REQUEST_SEND_PGP_IMAGE);
737 }
738
739 @Override
740 public void success(Message message) {
741 xmppConnectionService.sendMessage(message);
742 }
743
744 @Override
745 public void error(int error, Message message) {
746 hidePrepareImageToast();
747 displayErrorDialog(error);
748 }
749 });
750 }
751
752 private void hidePrepareImageToast() {
753 if (prepareImageToast != null) {
754 runOnUiThread(new Runnable() {
755
756 @Override
757 public void run() {
758 prepareImageToast.cancel();
759 }
760 });
761 }
762 }
763
764 public void updateConversationList() {
765 xmppConnectionService
766 .populateWithOrderedConversations(conversationList);
767 listAdapter.notifyDataSetChanged();
768 }
769
770 public void runIntent(PendingIntent pi, int requestCode) {
771 try {
772 this.startIntentSenderForResult(pi.getIntentSender(), requestCode,
773 null, 0, 0, 0);
774 } catch (SendIntentException e1) {
775 }
776 }
777
778 public void encryptTextMessage(Message message) {
779 xmppConnectionService.getPgpEngine().encrypt(message,
780 new UiCallback<Message>() {
781
782 @Override
783 public void userInputRequried(PendingIntent pi,
784 Message message) {
785 activity.runIntent(pi,
786 ConversationActivity.REQUEST_SEND_MESSAGE);
787 }
788
789 @Override
790 public void success(Message message) {
791 message.setEncryption(Message.ENCRYPTION_DECRYPTED);
792 xmppConnectionService.sendMessage(message);
793 }
794
795 @Override
796 public void error(int error, Message message) {
797
798 }
799 });
800 }
801
802 public boolean forceEncryption() {
803 return getPreferences().getBoolean("force_encryption", false);
804 }
805
806 public boolean useSendButtonToIndicateStatus() {
807 return getPreferences().getBoolean("send_button_status", false);
808 }
809
810 public boolean indicateReceived() {
811 return getPreferences().getBoolean("indicate_received", false);
812 }
813
814 @Override
815 public void onAccountUpdate() {
816 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
817 .findFragmentByTag("conversation");
818 if (fragment != null) {
819 runOnUiThread(new Runnable() {
820
821 @Override
822 public void run() {
823 fragment.updateMessages();
824 }
825 });
826 }
827 }
828
829 @Override
830 public void onConversationUpdate() {
831 runOnUiThread(new Runnable() {
832
833 @Override
834 public void run() {
835 updateConversationList();
836 if (paneShouldBeOpen) {
837 if (conversationList.size() >= 1) {
838 swapConversationFragment();
839 } else {
840 startActivity(new Intent(getApplicationContext(),
841 StartConversationActivity.class));
842 finish();
843 }
844 }
845 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
846 .findFragmentByTag("conversation");
847 if (selectedFragment != null) {
848 selectedFragment.updateMessages();
849 }
850 }
851 });
852 }
853
854 @Override
855 public void onRosterUpdate() {
856 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
857 .findFragmentByTag("conversation");
858 if (fragment != null) {
859 runOnUiThread(new Runnable() {
860
861 @Override
862 public void run() {
863 fragment.updateMessages();
864 }
865 });
866 }
867 }
868}