From 281ce3105fad5f012471cf3e5062a4032dfbc7a6 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Wed, 22 Oct 2014 15:44:55 -0400 Subject: Make conversations the root project --- build.gradle | 8 +- conversations/build.gradle | 28 - conversations/src/main/AndroidManifest.xml | 118 -- .../main/java/eu/siacs/conversations/Config.java | 25 - .../eu/siacs/conversations/crypto/OtrEngine.java | 231 --- .../eu/siacs/conversations/crypto/PgpEngine.java | 385 ---- .../conversations/entities/AbstractEntity.java | 21 - .../eu/siacs/conversations/entities/Account.java | 399 ---- .../eu/siacs/conversations/entities/Bookmark.java | 137 -- .../eu/siacs/conversations/entities/Contact.java | 367 ---- .../siacs/conversations/entities/Conversation.java | 500 ----- .../siacs/conversations/entities/Downloadable.java | 21 - .../conversations/entities/DownloadableFile.java | 154 -- .../eu/siacs/conversations/entities/ListItem.java | 7 - .../eu/siacs/conversations/entities/Message.java | 478 ----- .../siacs/conversations/entities/MucOptions.java | 369 ---- .../eu/siacs/conversations/entities/Presences.java | 76 - .../eu/siacs/conversations/entities/Roster.java | 83 - .../conversations/generator/AbstractGenerator.java | 48 - .../siacs/conversations/generator/IqGenerator.java | 96 - .../conversations/generator/MessageGenerator.java | 178 -- .../conversations/generator/PresenceGenerator.java | 57 - .../siacs/conversations/http/HttpConnection.java | 255 --- .../conversations/http/HttpConnectionManager.java | 28 - .../siacs/conversations/parser/AbstractParser.java | 92 - .../eu/siacs/conversations/parser/IqParser.java | 92 - .../siacs/conversations/parser/MessageParser.java | 517 ------ .../siacs/conversations/parser/PresenceParser.java | 133 -- .../conversations/persistance/DatabaseBackend.java | 335 ---- .../conversations/persistance/FileBackend.java | 480 ----- .../persistance/OnPhoneContactsMerged.java | 5 - .../services/AbstractConnectionManager.java | 23 - .../conversations/services/AvatarService.java | 298 --- .../conversations/services/EventReceiver.java | 24 - .../services/NotificationService.java | 237 --- .../services/XmppConnectionService.java | 1927 -------------------- .../conversations/ui/ChooseContactActivity.java | 145 -- .../ui/ConferenceDetailsActivity.java | 280 --- .../conversations/ui/ContactDetailsActivity.java | 436 ----- .../conversations/ui/ConversationActivity.java | 947 ---------- .../conversations/ui/ConversationFragment.java | 781 -------- .../conversations/ui/EditAccountActivity.java | 423 ----- .../eu/siacs/conversations/ui/EditMessage.java | 39 - .../conversations/ui/ManageAccountActivity.java | 217 --- .../ui/PublishProfilePictureActivity.java | 242 --- .../siacs/conversations/ui/SettingsActivity.java | 74 - .../siacs/conversations/ui/SettingsFragment.java | 15 - .../siacs/conversations/ui/ShareWithActivity.java | 185 -- .../ui/StartConversationActivity.java | 677 ------- .../java/eu/siacs/conversations/ui/UiCallback.java | 11 - .../eu/siacs/conversations/ui/XmppActivity.java | 637 ------- .../conversations/ui/adapter/AccountAdapter.java | 102 -- .../ui/adapter/ConversationAdapter.java | 135 -- .../ui/adapter/KnownHostsAdapter.java | 74 - .../conversations/ui/adapter/ListItemAdapter.java | 44 - .../conversations/ui/adapter/MessageAdapter.java | 560 ------ .../eu/siacs/conversations/utils/CryptoHelper.java | 112 -- .../eu/siacs/conversations/utils/DNSHelper.java | 185 -- .../conversations/utils/ExceptionHandler.java | 44 - .../siacs/conversations/utils/ExceptionHelper.java | 117 -- .../utils/OnPhoneContactsLoadedListener.java | 9 - .../eu/siacs/conversations/utils/PRNGFixes.java | 327 ---- .../eu/siacs/conversations/utils/PhoneHelper.java | 95 - .../eu/siacs/conversations/utils/UIHelper.java | 225 --- .../eu/siacs/conversations/utils/Validator.java | 14 - .../eu/siacs/conversations/utils/XmlHelper.java | 12 - .../conversations/utils/zlib/ZLibInputStream.java | 54 - .../conversations/utils/zlib/ZLibOutputStream.java | 95 - .../java/eu/siacs/conversations/xml/Element.java | 148 -- .../main/java/eu/siacs/conversations/xml/Tag.java | 104 -- .../java/eu/siacs/conversations/xml/TagWriter.java | 114 -- .../java/eu/siacs/conversations/xml/XmlReader.java | 141 -- .../siacs/conversations/xmpp/OnBindListener.java | 7 - .../conversations/xmpp/OnContactStatusChanged.java | 7 - .../conversations/xmpp/OnIqPacketReceived.java | 8 - .../conversations/xmpp/OnMessageAcknowledged.java | 7 - .../xmpp/OnMessagePacketReceived.java | 8 - .../xmpp/OnPresencePacketReceived.java | 8 - .../siacs/conversations/xmpp/OnStatusChanged.java | 7 - .../siacs/conversations/xmpp/PacketReceived.java | 5 - .../siacs/conversations/xmpp/XmppConnection.java | 1130 ------------ .../conversations/xmpp/jingle/JingleCandidate.java | 143 -- .../xmpp/jingle/JingleConnection.java | 910 --------- .../xmpp/jingle/JingleConnectionManager.java | 163 -- .../xmpp/jingle/JingleInbandTransport.java | 191 -- .../xmpp/jingle/JingleSocks5Transport.java | 212 --- .../conversations/xmpp/jingle/JingleTransport.java | 13 - .../jingle/OnFileTransmissionStatusChanged.java | 9 - .../xmpp/jingle/OnJinglePacketReceived.java | 9 - .../xmpp/jingle/OnPrimaryCandidateFound.java | 6 - .../xmpp/jingle/OnTransportConnected.java | 7 - .../conversations/xmpp/jingle/stanzas/Content.java | 102 -- .../xmpp/jingle/stanzas/JinglePacket.java | 95 - .../conversations/xmpp/jingle/stanzas/Reason.java | 13 - .../eu/siacs/conversations/xmpp/pep/Avatar.java | 71 - .../conversations/xmpp/stanzas/AbstractStanza.java | 34 - .../siacs/conversations/xmpp/stanzas/IqPacket.java | 76 - .../conversations/xmpp/stanzas/MessagePacket.java | 66 - .../conversations/xmpp/stanzas/PresencePacket.java | 8 - .../xmpp/stanzas/csi/ActivePacket.java | 10 - .../xmpp/stanzas/csi/InactivePacket.java | 10 - .../xmpp/stanzas/streammgmt/AckPacket.java | 13 - .../xmpp/stanzas/streammgmt/EnablePacket.java | 13 - .../xmpp/stanzas/streammgmt/RequestPacket.java | 12 - .../xmpp/stanzas/streammgmt/ResumePacket.java | 14 - .../main/res/drawable-hdpi/ic_action_add_group.png | Bin 876 -> 0 bytes .../res/drawable-hdpi/ic_action_add_person.png | Bin 616 -> 0 bytes .../src/main/res/drawable-hdpi/ic_action_chat.png | Bin 295 -> 0 bytes .../src/main/res/drawable-hdpi/ic_action_copy.png | Bin 381 -> 0 bytes .../main/res/drawable-hdpi/ic_action_discard.png | Bin 450 -> 0 bytes .../src/main/res/drawable-hdpi/ic_action_edit.png | Bin 765 -> 0 bytes .../main/res/drawable-hdpi/ic_action_edit_dark.png | Bin 884 -> 0 bytes .../src/main/res/drawable-hdpi/ic_action_group.png | Bin 776 -> 0 bytes .../src/main/res/drawable-hdpi/ic_action_new.png | Bin 262 -> 0 bytes .../res/drawable-hdpi/ic_action_new_attachment.png | Bin 587 -> 0 bytes .../res/drawable-hdpi/ic_action_not_secure.png | Bin 367 -> 0 bytes .../main/res/drawable-hdpi/ic_action_refresh.png | Bin 678 -> 0 bytes .../main/res/drawable-hdpi/ic_action_remove.png | Bin 448 -> 0 bytes .../main/res/drawable-hdpi/ic_action_search.png | Bin 650 -> 0 bytes .../main/res/drawable-hdpi/ic_action_secure.png | Bin 384 -> 0 bytes .../res/drawable-hdpi/ic_action_send_now_away.png | Bin 932 -> 0 bytes .../res/drawable-hdpi/ic_action_send_now_dnd.png | Bin 1135 -> 0 bytes .../drawable-hdpi/ic_action_send_now_offline.png | Bin 767 -> 0 bytes .../drawable-hdpi/ic_action_send_now_online.png | Bin 1095 -> 0 bytes .../src/main/res/drawable-hdpi/ic_activity.png | Bin 3040 -> 0 bytes .../src/main/res/drawable-hdpi/ic_indicator.png | Bin 684 -> 0 bytes .../src/main/res/drawable-hdpi/ic_launcher.png | Bin 4416 -> 0 bytes .../src/main/res/drawable-hdpi/ic_notification.png | Bin 1033 -> 0 bytes .../src/main/res/drawable-hdpi/ic_profile.png | Bin 999 -> 0 bytes .../res/drawable-hdpi/ic_received_indicator.png | Bin 686 -> 0 bytes .../main/res/drawable-hdpi/ic_secure_indicator.png | Bin 294 -> 0 bytes .../drawable-hdpi/tab_selected_conversations.9.png | Bin 99 -> 0 bytes .../tab_selected_focused_conversations.9.png | Bin 99 -> 0 bytes .../tab_selected_pressed_conversations.9.png | Bin 105 -> 0 bytes .../tab_unselected_conversations.9.png | Bin 101 -> 0 bytes .../tab_unselected_focused_conversations.9.png | Bin 93 -> 0 bytes .../tab_unselected_pressed_conversations.9.png | Bin 100 -> 0 bytes .../main/res/drawable-mdpi/ic_action_add_group.png | Bin 634 -> 0 bytes .../res/drawable-mdpi/ic_action_add_person.png | Bin 469 -> 0 bytes .../src/main/res/drawable-mdpi/ic_action_chat.png | Bin 261 -> 0 bytes .../src/main/res/drawable-mdpi/ic_action_copy.png | Bin 288 -> 0 bytes .../main/res/drawable-mdpi/ic_action_discard.png | Bin 324 -> 0 bytes .../src/main/res/drawable-mdpi/ic_action_edit.png | Bin 522 -> 0 bytes .../main/res/drawable-mdpi/ic_action_edit_dark.png | Bin 587 -> 0 bytes .../src/main/res/drawable-mdpi/ic_action_group.png | Bin 546 -> 0 bytes .../src/main/res/drawable-mdpi/ic_action_new.png | Bin 185 -> 0 bytes .../res/drawable-mdpi/ic_action_new_attachment.png | Bin 415 -> 0 bytes .../res/drawable-mdpi/ic_action_not_secure.png | Bin 298 -> 0 bytes .../main/res/drawable-mdpi/ic_action_refresh.png | Bin 507 -> 0 bytes .../main/res/drawable-mdpi/ic_action_remove.png | Bin 282 -> 0 bytes .../main/res/drawable-mdpi/ic_action_search.png | Bin 449 -> 0 bytes .../main/res/drawable-mdpi/ic_action_secure.png | Bin 304 -> 0 bytes .../res/drawable-mdpi/ic_action_send_now_away.png | Bin 650 -> 0 bytes .../res/drawable-mdpi/ic_action_send_now_dnd.png | Bin 784 -> 0 bytes .../drawable-mdpi/ic_action_send_now_offline.png | Bin 535 -> 0 bytes .../drawable-mdpi/ic_action_send_now_online.png | Bin 779 -> 0 bytes .../src/main/res/drawable-mdpi/ic_activity.png | Bin 1854 -> 0 bytes .../src/main/res/drawable-mdpi/ic_indicator.png | Bin 490 -> 0 bytes .../src/main/res/drawable-mdpi/ic_launcher.png | Bin 2726 -> 0 bytes .../src/main/res/drawable-mdpi/ic_notification.png | Bin 681 -> 0 bytes .../src/main/res/drawable-mdpi/ic_profile.png | Bin 622 -> 0 bytes .../res/drawable-mdpi/ic_received_indicator.png | Bin 447 -> 0 bytes .../main/res/drawable-mdpi/ic_secure_indicator.png | Bin 295 -> 0 bytes .../drawable-mdpi/tab_selected_conversations.9.png | Bin 96 -> 0 bytes .../tab_selected_focused_conversations.9.png | Bin 96 -> 0 bytes .../tab_selected_pressed_conversations.9.png | Bin 102 -> 0 bytes .../tab_unselected_conversations.9.png | Bin 105 -> 0 bytes .../tab_unselected_focused_conversations.9.png | Bin 90 -> 0 bytes .../tab_unselected_pressed_conversations.9.png | Bin 97 -> 0 bytes .../res/drawable-xhdpi/ic_action_add_group.png | Bin 1122 -> 0 bytes .../res/drawable-xhdpi/ic_action_add_person.png | Bin 798 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_action_chat.png | Bin 310 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_action_copy.png | Bin 353 -> 0 bytes .../main/res/drawable-xhdpi/ic_action_discard.png | Bin 543 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_action_edit.png | Bin 994 -> 0 bytes .../res/drawable-xhdpi/ic_action_edit_dark.png | Bin 1179 -> 0 bytes .../main/res/drawable-xhdpi/ic_action_group.png | Bin 1048 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_action_new.png | Bin 234 -> 0 bytes .../drawable-xhdpi/ic_action_new_attachment.png | Bin 753 -> 0 bytes .../res/drawable-xhdpi/ic_action_not_secure.png | Bin 482 -> 0 bytes .../main/res/drawable-xhdpi/ic_action_refresh.png | Bin 901 -> 0 bytes .../main/res/drawable-xhdpi/ic_action_remove.png | Bin 513 -> 0 bytes .../main/res/drawable-xhdpi/ic_action_search.png | Bin 827 -> 0 bytes .../main/res/drawable-xhdpi/ic_action_secure.png | Bin 468 -> 0 bytes .../res/drawable-xhdpi/ic_action_send_now_away.png | Bin 1180 -> 0 bytes .../res/drawable-xhdpi/ic_action_send_now_dnd.png | Bin 1438 -> 0 bytes .../drawable-xhdpi/ic_action_send_now_offline.png | Bin 968 -> 0 bytes .../drawable-xhdpi/ic_action_send_now_online.png | Bin 1395 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_activity.png | Bin 4349 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_indicator.png | Bin 915 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_launcher.png | Bin 6503 -> 0 bytes .../main/res/drawable-xhdpi/ic_notification.png | Bin 1407 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_profile.png | Bin 1374 -> 0 bytes .../res/drawable-xhdpi/ic_received_indicator.png | Bin 855 -> 0 bytes .../res/drawable-xhdpi/ic_secure_indicator.png | Bin 410 -> 0 bytes .../tab_selected_conversations.9.png | Bin 104 -> 0 bytes .../tab_selected_focused_conversations.9.png | Bin 103 -> 0 bytes .../tab_selected_pressed_conversations.9.png | Bin 110 -> 0 bytes .../tab_unselected_conversations.9.png | Bin 112 -> 0 bytes .../tab_unselected_focused_conversations.9.png | Bin 93 -> 0 bytes .../tab_unselected_pressed_conversations.9.png | Bin 101 -> 0 bytes .../res/drawable-xxhdpi/ic_action_add_group.png | Bin 1643 -> 0 bytes .../res/drawable-xxhdpi/ic_action_add_person.png | Bin 1088 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_chat.png | Bin 383 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_copy.png | Bin 470 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_discard.png | Bin 765 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_edit.png | Bin 1458 -> 0 bytes .../res/drawable-xxhdpi/ic_action_edit_dark.png | Bin 1670 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_group.png | Bin 1475 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_action_new.png | Bin 288 -> 0 bytes .../drawable-xxhdpi/ic_action_new_attachment.png | Bin 1048 -> 0 bytes .../res/drawable-xxhdpi/ic_action_not_secure.png | Bin 593 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_refresh.png | Bin 1274 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_remove.png | Bin 681 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_search.png | Bin 1152 -> 0 bytes .../main/res/drawable-xxhdpi/ic_action_secure.png | Bin 586 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_away.png | Bin 1426 -> 0 bytes .../res/drawable-xxhdpi/ic_action_send_now_dnd.png | Bin 1456 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_offline.png | Bin 1433 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_online.png | Bin 1458 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_activity.png | Bin 7209 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_indicator.png | Bin 1298 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 11054 -> 0 bytes .../main/res/drawable-xxhdpi/ic_notification.png | Bin 2250 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_profile.png | Bin 2137 -> 0 bytes .../res/drawable-xxhdpi/ic_received_indicator.png | Bin 1236 -> 0 bytes .../res/drawable-xxhdpi/ic_secure_indicator.png | Bin 380 -> 0 bytes .../tab_selected_conversations.9.png | Bin 108 -> 0 bytes .../tab_selected_focused_conversations.9.png | Bin 108 -> 0 bytes .../tab_selected_pressed_conversations.9.png | Bin 114 -> 0 bytes .../tab_unselected_conversations.9.png | Bin 109 -> 0 bytes .../tab_unselected_focused_conversations.9.png | Bin 95 -> 0 bytes .../tab_unselected_pressed_conversations.9.png | Bin 102 -> 0 bytes .../main/res/drawable/actionbar_tab_indicator.xml | 21 - .../main/res/drawable/es_slidingpane_shadow.xml | 12 - conversations/src/main/res/drawable/grey.xml | 7 - .../src/main/res/drawable/greybackground.xml | 6 - .../src/main/res/drawable/infocard_border.xml | 19 - .../src/main/res/drawable/message_border.xml | 15 - conversations/src/main/res/drawable/snackbar.xml | 14 - .../fragment_conversations_overview.xml | 30 - .../fragment_conversations_overview.xml | 30 - .../fragment_conversations_overview.xml | 30 - .../fragment_conversations_overview.xml | 32 - conversations/src/main/res/layout/account_row.xml | 43 - .../src/main/res/layout/actionview_search.xml | 19 - .../main/res/layout/activity_choose_contact.xml | 13 - .../main/res/layout/activity_contact_details.xml | 114 -- .../src/main/res/layout/activity_edit_account.xml | 272 --- .../src/main/res/layout/activity_muc_details.xml | 119 -- .../layout/activity_publish_profile_picture.xml | 106 -- .../res/layout/activity_start_conversation.xml | 8 - conversations/src/main/res/layout/contact.xml | 51 - conversations/src/main/res/layout/contact_key.xml | 41 - .../src/main/res/layout/conversation_list_row.xml | 68 - .../src/main/res/layout/create_contact_dialog.xml | 39 - .../src/main/res/layout/dialog_clear_history.xml | 21 - .../src/main/res/layout/dialog_verify_otr.xml | 60 - .../src/main/res/layout/fragment_conversation.xml | 102 -- .../res/layout/fragment_conversations_overview.xml | 30 - .../src/main/res/layout/join_conference_dialog.xml | 47 - .../src/main/res/layout/manage_accounts.xml | 16 - conversations/src/main/res/layout/message_null.xml | 7 - .../src/main/res/layout/message_received.xml | 97 - conversations/src/main/res/layout/message_sent.xml | 108 -- .../src/main/res/layout/message_status.xml | 22 - conversations/src/main/res/layout/quickedit.xml | 19 - conversations/src/main/res/layout/share_with.xml | 13 - .../src/main/res/menu/attachment_choices.xml | 15 - conversations/src/main/res/menu/choose_contact.xml | 11 - .../src/main/res/menu/conference_context.xml | 11 - .../src/main/res/menu/contact_context.xml | 14 - .../src/main/res/menu/contact_details.xml | 27 - conversations/src/main/res/menu/conversations.xml | 63 - .../src/main/res/menu/encryption_choices.xml | 16 - conversations/src/main/res/menu/manageaccounts.xml | 15 - .../src/main/res/menu/manageaccounts_context.xml | 21 - conversations/src/main/res/menu/muc_details.xml | 21 - conversations/src/main/res/menu/share_with.xml | 11 - .../src/main/res/menu/start_conversation.xml | 31 - conversations/src/main/res/values-ca/arrays.xml | 24 - conversations/src/main/res/values-ca/strings.xml | 83 - conversations/src/main/res/values-cs/arrays.xml | 39 - conversations/src/main/res/values-cs/strings.xml | 260 --- conversations/src/main/res/values-de/arrays.xml | 31 - conversations/src/main/res/values-de/strings.xml | 269 --- conversations/src/main/res/values-es/arrays.xml | 39 - conversations/src/main/res/values-es/strings.xml | 269 --- conversations/src/main/res/values-eu/arrays.xml | 39 - conversations/src/main/res/values-eu/strings.xml | 276 --- conversations/src/main/res/values-fr/arrays.xml | 24 - conversations/src/main/res/values-fr/strings.xml | 273 --- conversations/src/main/res/values-gl/arrays.xml | 24 - conversations/src/main/res/values-gl/strings.xml | 130 -- conversations/src/main/res/values-it/arrays.xml | 39 - conversations/src/main/res/values-it/strings.xml | 260 --- conversations/src/main/res/values-iw/arrays.xml | 24 - conversations/src/main/res/values-iw/strings.xml | 224 --- conversations/src/main/res/values-nl/arrays.xml | 24 - conversations/src/main/res/values-nl/strings.xml | 233 --- conversations/src/main/res/values-ru/arrays.xml | 24 - conversations/src/main/res/values-ru/strings.xml | 260 --- conversations/src/main/res/values-sv/arrays.xml | 24 - conversations/src/main/res/values-sv/strings.xml | 260 --- .../src/main/res/values-zh-rCN/arrays.xml | 39 - .../src/main/res/values-zh-rCN/strings.xml | 260 --- .../src/main/res/values-zh-rTW/arrays.xml | 39 - .../src/main/res/values-zh-rTW/strings.xml | 263 --- conversations/src/main/res/values/arrays.xml | 39 - conversations/src/main/res/values/attrs.xml | 8 - conversations/src/main/res/values/colors.xml | 17 - conversations/src/main/res/values/strings.xml | 276 --- conversations/src/main/res/values/styles.xml | 8 - conversations/src/main/res/values/themes.xml | 35 - conversations/src/main/res/xml/preferences.xml | 114 -- src/main/AndroidManifest.xml | 118 ++ src/main/java/eu/siacs/conversations/Config.java | 25 + .../eu/siacs/conversations/crypto/OtrEngine.java | 231 +++ .../eu/siacs/conversations/crypto/PgpEngine.java | 385 ++++ .../conversations/entities/AbstractEntity.java | 21 + .../eu/siacs/conversations/entities/Account.java | 399 ++++ .../eu/siacs/conversations/entities/Bookmark.java | 137 ++ .../eu/siacs/conversations/entities/Contact.java | 367 ++++ .../siacs/conversations/entities/Conversation.java | 500 +++++ .../siacs/conversations/entities/Downloadable.java | 21 + .../conversations/entities/DownloadableFile.java | 154 ++ .../eu/siacs/conversations/entities/ListItem.java | 7 + .../eu/siacs/conversations/entities/Message.java | 478 +++++ .../siacs/conversations/entities/MucOptions.java | 369 ++++ .../eu/siacs/conversations/entities/Presences.java | 76 + .../eu/siacs/conversations/entities/Roster.java | 83 + .../conversations/generator/AbstractGenerator.java | 48 + .../siacs/conversations/generator/IqGenerator.java | 96 + .../conversations/generator/MessageGenerator.java | 178 ++ .../conversations/generator/PresenceGenerator.java | 57 + .../siacs/conversations/http/HttpConnection.java | 255 +++ .../conversations/http/HttpConnectionManager.java | 28 + .../siacs/conversations/parser/AbstractParser.java | 92 + .../eu/siacs/conversations/parser/IqParser.java | 92 + .../siacs/conversations/parser/MessageParser.java | 517 ++++++ .../siacs/conversations/parser/PresenceParser.java | 133 ++ .../conversations/persistance/DatabaseBackend.java | 335 ++++ .../conversations/persistance/FileBackend.java | 480 +++++ .../persistance/OnPhoneContactsMerged.java | 5 + .../services/AbstractConnectionManager.java | 23 + .../conversations/services/AvatarService.java | 298 +++ .../conversations/services/EventReceiver.java | 24 + .../services/NotificationService.java | 237 +++ .../services/XmppConnectionService.java | 1927 ++++++++++++++++++++ .../conversations/ui/ChooseContactActivity.java | 145 ++ .../ui/ConferenceDetailsActivity.java | 280 +++ .../conversations/ui/ContactDetailsActivity.java | 436 +++++ .../conversations/ui/ConversationActivity.java | 947 ++++++++++ .../conversations/ui/ConversationFragment.java | 781 ++++++++ .../conversations/ui/EditAccountActivity.java | 423 +++++ .../eu/siacs/conversations/ui/EditMessage.java | 39 + .../conversations/ui/ManageAccountActivity.java | 217 +++ .../ui/PublishProfilePictureActivity.java | 242 +++ .../siacs/conversations/ui/SettingsActivity.java | 74 + .../siacs/conversations/ui/SettingsFragment.java | 15 + .../siacs/conversations/ui/ShareWithActivity.java | 185 ++ .../ui/StartConversationActivity.java | 677 +++++++ .../java/eu/siacs/conversations/ui/UiCallback.java | 11 + .../eu/siacs/conversations/ui/XmppActivity.java | 637 +++++++ .../conversations/ui/adapter/AccountAdapter.java | 102 ++ .../ui/adapter/ConversationAdapter.java | 135 ++ .../ui/adapter/KnownHostsAdapter.java | 74 + .../conversations/ui/adapter/ListItemAdapter.java | 44 + .../conversations/ui/adapter/MessageAdapter.java | 560 ++++++ .../eu/siacs/conversations/utils/CryptoHelper.java | 112 ++ .../eu/siacs/conversations/utils/DNSHelper.java | 185 ++ .../conversations/utils/ExceptionHandler.java | 44 + .../siacs/conversations/utils/ExceptionHelper.java | 117 ++ .../utils/OnPhoneContactsLoadedListener.java | 9 + .../eu/siacs/conversations/utils/PRNGFixes.java | 327 ++++ .../eu/siacs/conversations/utils/PhoneHelper.java | 95 + .../eu/siacs/conversations/utils/UIHelper.java | 225 +++ .../eu/siacs/conversations/utils/Validator.java | 14 + .../eu/siacs/conversations/utils/XmlHelper.java | 12 + .../conversations/utils/zlib/ZLibInputStream.java | 54 + .../conversations/utils/zlib/ZLibOutputStream.java | 95 + .../java/eu/siacs/conversations/xml/Element.java | 148 ++ src/main/java/eu/siacs/conversations/xml/Tag.java | 104 ++ .../java/eu/siacs/conversations/xml/TagWriter.java | 114 ++ .../java/eu/siacs/conversations/xml/XmlReader.java | 141 ++ .../siacs/conversations/xmpp/OnBindListener.java | 7 + .../conversations/xmpp/OnContactStatusChanged.java | 7 + .../conversations/xmpp/OnIqPacketReceived.java | 8 + .../conversations/xmpp/OnMessageAcknowledged.java | 7 + .../xmpp/OnMessagePacketReceived.java | 8 + .../xmpp/OnPresencePacketReceived.java | 8 + .../siacs/conversations/xmpp/OnStatusChanged.java | 7 + .../siacs/conversations/xmpp/PacketReceived.java | 5 + .../siacs/conversations/xmpp/XmppConnection.java | 1130 ++++++++++++ .../conversations/xmpp/jingle/JingleCandidate.java | 143 ++ .../xmpp/jingle/JingleConnection.java | 910 +++++++++ .../xmpp/jingle/JingleConnectionManager.java | 163 ++ .../xmpp/jingle/JingleInbandTransport.java | 191 ++ .../xmpp/jingle/JingleSocks5Transport.java | 212 +++ .../conversations/xmpp/jingle/JingleTransport.java | 13 + .../jingle/OnFileTransmissionStatusChanged.java | 9 + .../xmpp/jingle/OnJinglePacketReceived.java | 9 + .../xmpp/jingle/OnPrimaryCandidateFound.java | 6 + .../xmpp/jingle/OnTransportConnected.java | 7 + .../conversations/xmpp/jingle/stanzas/Content.java | 102 ++ .../xmpp/jingle/stanzas/JinglePacket.java | 95 + .../conversations/xmpp/jingle/stanzas/Reason.java | 13 + .../eu/siacs/conversations/xmpp/pep/Avatar.java | 71 + .../conversations/xmpp/stanzas/AbstractStanza.java | 34 + .../siacs/conversations/xmpp/stanzas/IqPacket.java | 76 + .../conversations/xmpp/stanzas/MessagePacket.java | 66 + .../conversations/xmpp/stanzas/PresencePacket.java | 8 + .../xmpp/stanzas/csi/ActivePacket.java | 10 + .../xmpp/stanzas/csi/InactivePacket.java | 10 + .../xmpp/stanzas/streammgmt/AckPacket.java | 13 + .../xmpp/stanzas/streammgmt/EnablePacket.java | 13 + .../xmpp/stanzas/streammgmt/RequestPacket.java | 12 + .../xmpp/stanzas/streammgmt/ResumePacket.java | 14 + src/main/res/drawable-hdpi/ic_action_add_group.png | Bin 0 -> 876 bytes .../res/drawable-hdpi/ic_action_add_person.png | Bin 0 -> 616 bytes src/main/res/drawable-hdpi/ic_action_chat.png | Bin 0 -> 295 bytes src/main/res/drawable-hdpi/ic_action_copy.png | Bin 0 -> 381 bytes src/main/res/drawable-hdpi/ic_action_discard.png | Bin 0 -> 450 bytes src/main/res/drawable-hdpi/ic_action_edit.png | Bin 0 -> 765 bytes src/main/res/drawable-hdpi/ic_action_edit_dark.png | Bin 0 -> 884 bytes src/main/res/drawable-hdpi/ic_action_group.png | Bin 0 -> 776 bytes src/main/res/drawable-hdpi/ic_action_new.png | Bin 0 -> 262 bytes .../res/drawable-hdpi/ic_action_new_attachment.png | Bin 0 -> 587 bytes .../res/drawable-hdpi/ic_action_not_secure.png | Bin 0 -> 367 bytes src/main/res/drawable-hdpi/ic_action_refresh.png | Bin 0 -> 678 bytes src/main/res/drawable-hdpi/ic_action_remove.png | Bin 0 -> 448 bytes src/main/res/drawable-hdpi/ic_action_search.png | Bin 0 -> 650 bytes src/main/res/drawable-hdpi/ic_action_secure.png | Bin 0 -> 384 bytes .../res/drawable-hdpi/ic_action_send_now_away.png | Bin 0 -> 932 bytes .../res/drawable-hdpi/ic_action_send_now_dnd.png | Bin 0 -> 1135 bytes .../drawable-hdpi/ic_action_send_now_offline.png | Bin 0 -> 767 bytes .../drawable-hdpi/ic_action_send_now_online.png | Bin 0 -> 1095 bytes src/main/res/drawable-hdpi/ic_activity.png | Bin 0 -> 3040 bytes src/main/res/drawable-hdpi/ic_indicator.png | Bin 0 -> 684 bytes src/main/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 4416 bytes src/main/res/drawable-hdpi/ic_notification.png | Bin 0 -> 1033 bytes src/main/res/drawable-hdpi/ic_profile.png | Bin 0 -> 999 bytes .../res/drawable-hdpi/ic_received_indicator.png | Bin 0 -> 686 bytes src/main/res/drawable-hdpi/ic_secure_indicator.png | Bin 0 -> 294 bytes .../drawable-hdpi/tab_selected_conversations.9.png | Bin 0 -> 99 bytes .../tab_selected_focused_conversations.9.png | Bin 0 -> 99 bytes .../tab_selected_pressed_conversations.9.png | Bin 0 -> 105 bytes .../tab_unselected_conversations.9.png | Bin 0 -> 101 bytes .../tab_unselected_focused_conversations.9.png | Bin 0 -> 93 bytes .../tab_unselected_pressed_conversations.9.png | Bin 0 -> 100 bytes src/main/res/drawable-mdpi/ic_action_add_group.png | Bin 0 -> 634 bytes .../res/drawable-mdpi/ic_action_add_person.png | Bin 0 -> 469 bytes src/main/res/drawable-mdpi/ic_action_chat.png | Bin 0 -> 261 bytes src/main/res/drawable-mdpi/ic_action_copy.png | Bin 0 -> 288 bytes src/main/res/drawable-mdpi/ic_action_discard.png | Bin 0 -> 324 bytes src/main/res/drawable-mdpi/ic_action_edit.png | Bin 0 -> 522 bytes src/main/res/drawable-mdpi/ic_action_edit_dark.png | Bin 0 -> 587 bytes src/main/res/drawable-mdpi/ic_action_group.png | Bin 0 -> 546 bytes src/main/res/drawable-mdpi/ic_action_new.png | Bin 0 -> 185 bytes .../res/drawable-mdpi/ic_action_new_attachment.png | Bin 0 -> 415 bytes .../res/drawable-mdpi/ic_action_not_secure.png | Bin 0 -> 298 bytes src/main/res/drawable-mdpi/ic_action_refresh.png | Bin 0 -> 507 bytes src/main/res/drawable-mdpi/ic_action_remove.png | Bin 0 -> 282 bytes src/main/res/drawable-mdpi/ic_action_search.png | Bin 0 -> 449 bytes src/main/res/drawable-mdpi/ic_action_secure.png | Bin 0 -> 304 bytes .../res/drawable-mdpi/ic_action_send_now_away.png | Bin 0 -> 650 bytes .../res/drawable-mdpi/ic_action_send_now_dnd.png | Bin 0 -> 784 bytes .../drawable-mdpi/ic_action_send_now_offline.png | Bin 0 -> 535 bytes .../drawable-mdpi/ic_action_send_now_online.png | Bin 0 -> 779 bytes src/main/res/drawable-mdpi/ic_activity.png | Bin 0 -> 1854 bytes src/main/res/drawable-mdpi/ic_indicator.png | Bin 0 -> 490 bytes src/main/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2726 bytes src/main/res/drawable-mdpi/ic_notification.png | Bin 0 -> 681 bytes src/main/res/drawable-mdpi/ic_profile.png | Bin 0 -> 622 bytes .../res/drawable-mdpi/ic_received_indicator.png | Bin 0 -> 447 bytes src/main/res/drawable-mdpi/ic_secure_indicator.png | Bin 0 -> 295 bytes .../drawable-mdpi/tab_selected_conversations.9.png | Bin 0 -> 96 bytes .../tab_selected_focused_conversations.9.png | Bin 0 -> 96 bytes .../tab_selected_pressed_conversations.9.png | Bin 0 -> 102 bytes .../tab_unselected_conversations.9.png | Bin 0 -> 105 bytes .../tab_unselected_focused_conversations.9.png | Bin 0 -> 90 bytes .../tab_unselected_pressed_conversations.9.png | Bin 0 -> 97 bytes .../res/drawable-xhdpi/ic_action_add_group.png | Bin 0 -> 1122 bytes .../res/drawable-xhdpi/ic_action_add_person.png | Bin 0 -> 798 bytes src/main/res/drawable-xhdpi/ic_action_chat.png | Bin 0 -> 310 bytes src/main/res/drawable-xhdpi/ic_action_copy.png | Bin 0 -> 353 bytes src/main/res/drawable-xhdpi/ic_action_discard.png | Bin 0 -> 543 bytes src/main/res/drawable-xhdpi/ic_action_edit.png | Bin 0 -> 994 bytes .../res/drawable-xhdpi/ic_action_edit_dark.png | Bin 0 -> 1179 bytes src/main/res/drawable-xhdpi/ic_action_group.png | Bin 0 -> 1048 bytes src/main/res/drawable-xhdpi/ic_action_new.png | Bin 0 -> 234 bytes .../drawable-xhdpi/ic_action_new_attachment.png | Bin 0 -> 753 bytes .../res/drawable-xhdpi/ic_action_not_secure.png | Bin 0 -> 482 bytes src/main/res/drawable-xhdpi/ic_action_refresh.png | Bin 0 -> 901 bytes src/main/res/drawable-xhdpi/ic_action_remove.png | Bin 0 -> 513 bytes src/main/res/drawable-xhdpi/ic_action_search.png | Bin 0 -> 827 bytes src/main/res/drawable-xhdpi/ic_action_secure.png | Bin 0 -> 468 bytes .../res/drawable-xhdpi/ic_action_send_now_away.png | Bin 0 -> 1180 bytes .../res/drawable-xhdpi/ic_action_send_now_dnd.png | Bin 0 -> 1438 bytes .../drawable-xhdpi/ic_action_send_now_offline.png | Bin 0 -> 968 bytes .../drawable-xhdpi/ic_action_send_now_online.png | Bin 0 -> 1395 bytes src/main/res/drawable-xhdpi/ic_activity.png | Bin 0 -> 4349 bytes src/main/res/drawable-xhdpi/ic_indicator.png | Bin 0 -> 915 bytes src/main/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 6503 bytes src/main/res/drawable-xhdpi/ic_notification.png | Bin 0 -> 1407 bytes src/main/res/drawable-xhdpi/ic_profile.png | Bin 0 -> 1374 bytes .../res/drawable-xhdpi/ic_received_indicator.png | Bin 0 -> 855 bytes .../res/drawable-xhdpi/ic_secure_indicator.png | Bin 0 -> 410 bytes .../tab_selected_conversations.9.png | Bin 0 -> 104 bytes .../tab_selected_focused_conversations.9.png | Bin 0 -> 103 bytes .../tab_selected_pressed_conversations.9.png | Bin 0 -> 110 bytes .../tab_unselected_conversations.9.png | Bin 0 -> 112 bytes .../tab_unselected_focused_conversations.9.png | Bin 0 -> 93 bytes .../tab_unselected_pressed_conversations.9.png | Bin 0 -> 101 bytes .../res/drawable-xxhdpi/ic_action_add_group.png | Bin 0 -> 1643 bytes .../res/drawable-xxhdpi/ic_action_add_person.png | Bin 0 -> 1088 bytes src/main/res/drawable-xxhdpi/ic_action_chat.png | Bin 0 -> 383 bytes src/main/res/drawable-xxhdpi/ic_action_copy.png | Bin 0 -> 470 bytes src/main/res/drawable-xxhdpi/ic_action_discard.png | Bin 0 -> 765 bytes src/main/res/drawable-xxhdpi/ic_action_edit.png | Bin 0 -> 1458 bytes .../res/drawable-xxhdpi/ic_action_edit_dark.png | Bin 0 -> 1670 bytes src/main/res/drawable-xxhdpi/ic_action_group.png | Bin 0 -> 1475 bytes src/main/res/drawable-xxhdpi/ic_action_new.png | Bin 0 -> 288 bytes .../drawable-xxhdpi/ic_action_new_attachment.png | Bin 0 -> 1048 bytes .../res/drawable-xxhdpi/ic_action_not_secure.png | Bin 0 -> 593 bytes src/main/res/drawable-xxhdpi/ic_action_refresh.png | Bin 0 -> 1274 bytes src/main/res/drawable-xxhdpi/ic_action_remove.png | Bin 0 -> 681 bytes src/main/res/drawable-xxhdpi/ic_action_search.png | Bin 0 -> 1152 bytes src/main/res/drawable-xxhdpi/ic_action_secure.png | Bin 0 -> 586 bytes .../drawable-xxhdpi/ic_action_send_now_away.png | Bin 0 -> 1426 bytes .../res/drawable-xxhdpi/ic_action_send_now_dnd.png | Bin 0 -> 1456 bytes .../drawable-xxhdpi/ic_action_send_now_offline.png | Bin 0 -> 1433 bytes .../drawable-xxhdpi/ic_action_send_now_online.png | Bin 0 -> 1458 bytes src/main/res/drawable-xxhdpi/ic_activity.png | Bin 0 -> 7209 bytes src/main/res/drawable-xxhdpi/ic_indicator.png | Bin 0 -> 1298 bytes src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 11054 bytes src/main/res/drawable-xxhdpi/ic_notification.png | Bin 0 -> 2250 bytes src/main/res/drawable-xxhdpi/ic_profile.png | Bin 0 -> 2137 bytes .../res/drawable-xxhdpi/ic_received_indicator.png | Bin 0 -> 1236 bytes .../res/drawable-xxhdpi/ic_secure_indicator.png | Bin 0 -> 380 bytes .../tab_selected_conversations.9.png | Bin 0 -> 108 bytes .../tab_selected_focused_conversations.9.png | Bin 0 -> 108 bytes .../tab_selected_pressed_conversations.9.png | Bin 0 -> 114 bytes .../tab_unselected_conversations.9.png | Bin 0 -> 109 bytes .../tab_unselected_focused_conversations.9.png | Bin 0 -> 95 bytes .../tab_unselected_pressed_conversations.9.png | Bin 0 -> 102 bytes src/main/res/drawable/actionbar_tab_indicator.xml | 21 + src/main/res/drawable/es_slidingpane_shadow.xml | 12 + src/main/res/drawable/grey.xml | 7 + src/main/res/drawable/greybackground.xml | 6 + src/main/res/drawable/infocard_border.xml | 19 + src/main/res/drawable/message_border.xml | 15 + src/main/res/drawable/snackbar.xml | 14 + .../fragment_conversations_overview.xml | 30 + .../fragment_conversations_overview.xml | 30 + .../fragment_conversations_overview.xml | 30 + .../fragment_conversations_overview.xml | 32 + src/main/res/layout/account_row.xml | 43 + src/main/res/layout/actionview_search.xml | 19 + src/main/res/layout/activity_choose_contact.xml | 13 + src/main/res/layout/activity_contact_details.xml | 114 ++ src/main/res/layout/activity_edit_account.xml | 272 +++ src/main/res/layout/activity_muc_details.xml | 119 ++ .../layout/activity_publish_profile_picture.xml | 106 ++ .../res/layout/activity_start_conversation.xml | 8 + src/main/res/layout/contact.xml | 51 + src/main/res/layout/contact_key.xml | 41 + src/main/res/layout/conversation_list_row.xml | 68 + src/main/res/layout/create_contact_dialog.xml | 39 + src/main/res/layout/dialog_clear_history.xml | 21 + src/main/res/layout/dialog_verify_otr.xml | 60 + src/main/res/layout/fragment_conversation.xml | 102 ++ .../res/layout/fragment_conversations_overview.xml | 30 + src/main/res/layout/join_conference_dialog.xml | 47 + src/main/res/layout/manage_accounts.xml | 16 + src/main/res/layout/message_null.xml | 7 + src/main/res/layout/message_received.xml | 97 + src/main/res/layout/message_sent.xml | 108 ++ src/main/res/layout/message_status.xml | 22 + src/main/res/layout/quickedit.xml | 19 + src/main/res/layout/share_with.xml | 13 + src/main/res/menu/attachment_choices.xml | 15 + src/main/res/menu/choose_contact.xml | 11 + src/main/res/menu/conference_context.xml | 11 + src/main/res/menu/contact_context.xml | 14 + src/main/res/menu/contact_details.xml | 27 + src/main/res/menu/conversations.xml | 63 + src/main/res/menu/encryption_choices.xml | 16 + src/main/res/menu/manageaccounts.xml | 15 + src/main/res/menu/manageaccounts_context.xml | 21 + src/main/res/menu/muc_details.xml | 21 + src/main/res/menu/share_with.xml | 11 + src/main/res/menu/start_conversation.xml | 31 + src/main/res/values-ca/arrays.xml | 24 + src/main/res/values-ca/strings.xml | 83 + src/main/res/values-cs/arrays.xml | 39 + src/main/res/values-cs/strings.xml | 260 +++ src/main/res/values-de/arrays.xml | 31 + src/main/res/values-de/strings.xml | 269 +++ src/main/res/values-es/arrays.xml | 39 + src/main/res/values-es/strings.xml | 269 +++ src/main/res/values-eu/arrays.xml | 39 + src/main/res/values-eu/strings.xml | 276 +++ src/main/res/values-fr/arrays.xml | 24 + src/main/res/values-fr/strings.xml | 273 +++ src/main/res/values-gl/arrays.xml | 24 + src/main/res/values-gl/strings.xml | 130 ++ src/main/res/values-it/arrays.xml | 39 + src/main/res/values-it/strings.xml | 260 +++ src/main/res/values-iw/arrays.xml | 24 + src/main/res/values-iw/strings.xml | 224 +++ src/main/res/values-nl/arrays.xml | 24 + src/main/res/values-nl/strings.xml | 233 +++ src/main/res/values-ru/arrays.xml | 24 + src/main/res/values-ru/strings.xml | 260 +++ src/main/res/values-sv/arrays.xml | 24 + src/main/res/values-sv/strings.xml | 260 +++ src/main/res/values-zh-rCN/arrays.xml | 39 + src/main/res/values-zh-rCN/strings.xml | 260 +++ src/main/res/values-zh-rTW/arrays.xml | 39 + src/main/res/values-zh-rTW/strings.xml | 263 +++ src/main/res/values/arrays.xml | 39 + src/main/res/values/attrs.xml | 8 + src/main/res/values/colors.xml | 17 + src/main/res/values/strings.xml | 276 +++ src/main/res/values/styles.xml | 8 + src/main/res/values/themes.xml | 35 + src/main/res/xml/preferences.xml | 114 ++ 628 files changed, 25566 insertions(+), 25590 deletions(-) delete mode 100644 conversations/build.gradle delete mode 100644 conversations/src/main/AndroidManifest.xml delete mode 100644 conversations/src/main/java/eu/siacs/conversations/Config.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/AbstractEntity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Account.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Bookmark.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Contact.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Conversation.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Downloadable.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/ListItem.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Message.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/MucOptions.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Presences.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/entities/Roster.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/generator/IqGenerator.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/http/HttpConnection.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/parser/AbstractParser.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/parser/IqParser.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/parser/MessageParser.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/parser/PresenceParser.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/persistance/FileBackend.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/persistance/OnPhoneContactsMerged.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/services/AvatarService.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/services/EventReceiver.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/services/NotificationService.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/EditMessage.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/SettingsFragment.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/UiCallback.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/XmppActivity.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/DNSHelper.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/UIHelper.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/Validator.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/XmlHelper.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibInputStream.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xml/Element.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xml/Tag.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xml/TagWriter.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xml/XmlReader.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnBindListener.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnContactStatusChanged.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnIqPacketReceived.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessageAcknowledged.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessagePacketReceived.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnPresencePacketReceived.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/OnStatusChanged.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/PacketReceived.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnJinglePacketReceived.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnTransportConnected.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Reason.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/PresencePacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/ActivePacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/InactivePacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/AckPacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/EnablePacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/RequestPacket.java delete mode 100644 conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/ResumePacket.java delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_add_group.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_add_person.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_chat.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_copy.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_discard.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_edit.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_edit_dark.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_group.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_new.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_new_attachment.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_not_secure.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_refresh.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_remove.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_search.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_secure.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_send_now_away.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_send_now_offline.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_action_send_now_online.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_activity.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_indicator.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_launcher.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_notification.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_profile.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_received_indicator.png delete mode 100644 conversations/src/main/res/drawable-hdpi/ic_secure_indicator.png delete mode 100644 conversations/src/main/res/drawable-hdpi/tab_selected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-hdpi/tab_selected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-hdpi/tab_selected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-hdpi/tab_unselected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-hdpi/tab_unselected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-hdpi/tab_unselected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_add_group.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_add_person.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_chat.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_copy.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_discard.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_edit.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_edit_dark.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_group.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_new.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_new_attachment.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_not_secure.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_refresh.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_remove.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_search.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_secure.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_send_now_away.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_send_now_offline.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_action_send_now_online.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_activity.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_indicator.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_launcher.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_notification.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_profile.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_received_indicator.png delete mode 100644 conversations/src/main/res/drawable-mdpi/ic_secure_indicator.png delete mode 100644 conversations/src/main/res/drawable-mdpi/tab_selected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-mdpi/tab_selected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-mdpi/tab_selected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-mdpi/tab_unselected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-mdpi/tab_unselected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-mdpi/tab_unselected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_add_group.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_add_person.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_chat.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_copy.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_discard.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_edit.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_edit_dark.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_group.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_new.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_new_attachment.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_not_secure.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_refresh.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_remove.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_search.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_secure.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_send_now_away.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_action_send_now_online.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_activity.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_indicator.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_launcher.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_notification.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_profile.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_received_indicator.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/ic_secure_indicator.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/tab_selected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/tab_selected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/tab_selected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/tab_unselected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/tab_unselected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xhdpi/tab_unselected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_add_group.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_add_person.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_chat.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_copy.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_discard.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_edit.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_edit_dark.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_group.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_new.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_new_attachment.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_not_secure.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_refresh.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_remove.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_search.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_secure.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_activity.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_indicator.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_notification.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_profile.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_received_indicator.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/ic_secure_indicator.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/tab_selected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/tab_selected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/tab_selected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/tab_unselected_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/tab_unselected_focused_conversations.9.png delete mode 100644 conversations/src/main/res/drawable-xxhdpi/tab_unselected_pressed_conversations.9.png delete mode 100644 conversations/src/main/res/drawable/actionbar_tab_indicator.xml delete mode 100644 conversations/src/main/res/drawable/es_slidingpane_shadow.xml delete mode 100644 conversations/src/main/res/drawable/grey.xml delete mode 100644 conversations/src/main/res/drawable/greybackground.xml delete mode 100644 conversations/src/main/res/drawable/infocard_border.xml delete mode 100644 conversations/src/main/res/drawable/message_border.xml delete mode 100644 conversations/src/main/res/drawable/snackbar.xml delete mode 100644 conversations/src/main/res/layout-w360dp/fragment_conversations_overview.xml delete mode 100644 conversations/src/main/res/layout-w384dp/fragment_conversations_overview.xml delete mode 100644 conversations/src/main/res/layout-w600dp/fragment_conversations_overview.xml delete mode 100644 conversations/src/main/res/layout-w960dp/fragment_conversations_overview.xml delete mode 100644 conversations/src/main/res/layout/account_row.xml delete mode 100644 conversations/src/main/res/layout/actionview_search.xml delete mode 100644 conversations/src/main/res/layout/activity_choose_contact.xml delete mode 100644 conversations/src/main/res/layout/activity_contact_details.xml delete mode 100644 conversations/src/main/res/layout/activity_edit_account.xml delete mode 100644 conversations/src/main/res/layout/activity_muc_details.xml delete mode 100644 conversations/src/main/res/layout/activity_publish_profile_picture.xml delete mode 100644 conversations/src/main/res/layout/activity_start_conversation.xml delete mode 100644 conversations/src/main/res/layout/contact.xml delete mode 100644 conversations/src/main/res/layout/contact_key.xml delete mode 100644 conversations/src/main/res/layout/conversation_list_row.xml delete mode 100644 conversations/src/main/res/layout/create_contact_dialog.xml delete mode 100644 conversations/src/main/res/layout/dialog_clear_history.xml delete mode 100644 conversations/src/main/res/layout/dialog_verify_otr.xml delete mode 100644 conversations/src/main/res/layout/fragment_conversation.xml delete mode 100644 conversations/src/main/res/layout/fragment_conversations_overview.xml delete mode 100644 conversations/src/main/res/layout/join_conference_dialog.xml delete mode 100644 conversations/src/main/res/layout/manage_accounts.xml delete mode 100644 conversations/src/main/res/layout/message_null.xml delete mode 100644 conversations/src/main/res/layout/message_received.xml delete mode 100644 conversations/src/main/res/layout/message_sent.xml delete mode 100644 conversations/src/main/res/layout/message_status.xml delete mode 100644 conversations/src/main/res/layout/quickedit.xml delete mode 100644 conversations/src/main/res/layout/share_with.xml delete mode 100644 conversations/src/main/res/menu/attachment_choices.xml delete mode 100644 conversations/src/main/res/menu/choose_contact.xml delete mode 100644 conversations/src/main/res/menu/conference_context.xml delete mode 100644 conversations/src/main/res/menu/contact_context.xml delete mode 100644 conversations/src/main/res/menu/contact_details.xml delete mode 100644 conversations/src/main/res/menu/conversations.xml delete mode 100644 conversations/src/main/res/menu/encryption_choices.xml delete mode 100644 conversations/src/main/res/menu/manageaccounts.xml delete mode 100644 conversations/src/main/res/menu/manageaccounts_context.xml delete mode 100644 conversations/src/main/res/menu/muc_details.xml delete mode 100644 conversations/src/main/res/menu/share_with.xml delete mode 100644 conversations/src/main/res/menu/start_conversation.xml delete mode 100644 conversations/src/main/res/values-ca/arrays.xml delete mode 100644 conversations/src/main/res/values-ca/strings.xml delete mode 100644 conversations/src/main/res/values-cs/arrays.xml delete mode 100644 conversations/src/main/res/values-cs/strings.xml delete mode 100644 conversations/src/main/res/values-de/arrays.xml delete mode 100644 conversations/src/main/res/values-de/strings.xml delete mode 100644 conversations/src/main/res/values-es/arrays.xml delete mode 100644 conversations/src/main/res/values-es/strings.xml delete mode 100644 conversations/src/main/res/values-eu/arrays.xml delete mode 100644 conversations/src/main/res/values-eu/strings.xml delete mode 100644 conversations/src/main/res/values-fr/arrays.xml delete mode 100644 conversations/src/main/res/values-fr/strings.xml delete mode 100644 conversations/src/main/res/values-gl/arrays.xml delete mode 100644 conversations/src/main/res/values-gl/strings.xml delete mode 100644 conversations/src/main/res/values-it/arrays.xml delete mode 100644 conversations/src/main/res/values-it/strings.xml delete mode 100644 conversations/src/main/res/values-iw/arrays.xml delete mode 100644 conversations/src/main/res/values-iw/strings.xml delete mode 100644 conversations/src/main/res/values-nl/arrays.xml delete mode 100644 conversations/src/main/res/values-nl/strings.xml delete mode 100644 conversations/src/main/res/values-ru/arrays.xml delete mode 100644 conversations/src/main/res/values-ru/strings.xml delete mode 100644 conversations/src/main/res/values-sv/arrays.xml delete mode 100644 conversations/src/main/res/values-sv/strings.xml delete mode 100644 conversations/src/main/res/values-zh-rCN/arrays.xml delete mode 100644 conversations/src/main/res/values-zh-rCN/strings.xml delete mode 100644 conversations/src/main/res/values-zh-rTW/arrays.xml delete mode 100644 conversations/src/main/res/values-zh-rTW/strings.xml delete mode 100644 conversations/src/main/res/values/arrays.xml delete mode 100644 conversations/src/main/res/values/attrs.xml delete mode 100644 conversations/src/main/res/values/colors.xml delete mode 100644 conversations/src/main/res/values/strings.xml delete mode 100644 conversations/src/main/res/values/styles.xml delete mode 100644 conversations/src/main/res/values/themes.xml delete mode 100644 conversations/src/main/res/xml/preferences.xml create mode 100644 src/main/AndroidManifest.xml create mode 100644 src/main/java/eu/siacs/conversations/Config.java create mode 100644 src/main/java/eu/siacs/conversations/crypto/OtrEngine.java create mode 100644 src/main/java/eu/siacs/conversations/crypto/PgpEngine.java create mode 100644 src/main/java/eu/siacs/conversations/entities/AbstractEntity.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Account.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Bookmark.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Contact.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Conversation.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Downloadable.java create mode 100644 src/main/java/eu/siacs/conversations/entities/DownloadableFile.java create mode 100644 src/main/java/eu/siacs/conversations/entities/ListItem.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Message.java create mode 100644 src/main/java/eu/siacs/conversations/entities/MucOptions.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Presences.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Roster.java create mode 100644 src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java create mode 100644 src/main/java/eu/siacs/conversations/generator/IqGenerator.java create mode 100644 src/main/java/eu/siacs/conversations/generator/MessageGenerator.java create mode 100644 src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java create mode 100644 src/main/java/eu/siacs/conversations/http/HttpConnection.java create mode 100644 src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java create mode 100644 src/main/java/eu/siacs/conversations/parser/AbstractParser.java create mode 100644 src/main/java/eu/siacs/conversations/parser/IqParser.java create mode 100644 src/main/java/eu/siacs/conversations/parser/MessageParser.java create mode 100644 src/main/java/eu/siacs/conversations/parser/PresenceParser.java create mode 100644 src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java create mode 100644 src/main/java/eu/siacs/conversations/persistance/FileBackend.java create mode 100644 src/main/java/eu/siacs/conversations/persistance/OnPhoneContactsMerged.java create mode 100644 src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java create mode 100644 src/main/java/eu/siacs/conversations/services/AvatarService.java create mode 100644 src/main/java/eu/siacs/conversations/services/EventReceiver.java create mode 100644 src/main/java/eu/siacs/conversations/services/NotificationService.java create mode 100644 src/main/java/eu/siacs/conversations/services/XmppConnectionService.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ConversationActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ConversationFragment.java create mode 100644 src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/EditMessage.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/SettingsActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/SettingsFragment.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/UiCallback.java create mode 100644 src/main/java/eu/siacs/conversations/ui/XmppActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java create mode 100644 src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java create mode 100644 src/main/java/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java create mode 100644 src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java create mode 100644 src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java create mode 100644 src/main/java/eu/siacs/conversations/utils/CryptoHelper.java create mode 100644 src/main/java/eu/siacs/conversations/utils/DNSHelper.java create mode 100644 src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java create mode 100644 src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java create mode 100644 src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java create mode 100644 src/main/java/eu/siacs/conversations/utils/PRNGFixes.java create mode 100644 src/main/java/eu/siacs/conversations/utils/PhoneHelper.java create mode 100644 src/main/java/eu/siacs/conversations/utils/UIHelper.java create mode 100644 src/main/java/eu/siacs/conversations/utils/Validator.java create mode 100644 src/main/java/eu/siacs/conversations/utils/XmlHelper.java create mode 100644 src/main/java/eu/siacs/conversations/utils/zlib/ZLibInputStream.java create mode 100644 src/main/java/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java create mode 100644 src/main/java/eu/siacs/conversations/xml/Element.java create mode 100644 src/main/java/eu/siacs/conversations/xml/Tag.java create mode 100644 src/main/java/eu/siacs/conversations/xml/TagWriter.java create mode 100644 src/main/java/eu/siacs/conversations/xml/XmlReader.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnBindListener.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnContactStatusChanged.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnIqPacketReceived.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnMessageAcknowledged.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnMessagePacketReceived.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnPresencePacketReceived.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnStatusChanged.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/PacketReceived.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/OnJinglePacketReceived.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/OnTransportConnected.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Reason.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/PresencePacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/ActivePacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/InactivePacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/AckPacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/EnablePacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/RequestPacket.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/ResumePacket.java create mode 100644 src/main/res/drawable-hdpi/ic_action_add_group.png create mode 100644 src/main/res/drawable-hdpi/ic_action_add_person.png create mode 100644 src/main/res/drawable-hdpi/ic_action_chat.png create mode 100644 src/main/res/drawable-hdpi/ic_action_copy.png create mode 100644 src/main/res/drawable-hdpi/ic_action_discard.png create mode 100644 src/main/res/drawable-hdpi/ic_action_edit.png create mode 100644 src/main/res/drawable-hdpi/ic_action_edit_dark.png create mode 100644 src/main/res/drawable-hdpi/ic_action_group.png create mode 100644 src/main/res/drawable-hdpi/ic_action_new.png create mode 100644 src/main/res/drawable-hdpi/ic_action_new_attachment.png create mode 100644 src/main/res/drawable-hdpi/ic_action_not_secure.png create mode 100644 src/main/res/drawable-hdpi/ic_action_refresh.png create mode 100644 src/main/res/drawable-hdpi/ic_action_remove.png create mode 100644 src/main/res/drawable-hdpi/ic_action_search.png create mode 100644 src/main/res/drawable-hdpi/ic_action_secure.png create mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_away.png create mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-hdpi/ic_activity.png create mode 100644 src/main/res/drawable-hdpi/ic_indicator.png create mode 100644 src/main/res/drawable-hdpi/ic_launcher.png create mode 100644 src/main/res/drawable-hdpi/ic_notification.png create mode 100644 src/main/res/drawable-hdpi/ic_profile.png create mode 100644 src/main/res/drawable-hdpi/ic_received_indicator.png create mode 100644 src/main/res/drawable-hdpi/ic_secure_indicator.png create mode 100644 src/main/res/drawable-hdpi/tab_selected_conversations.9.png create mode 100644 src/main/res/drawable-hdpi/tab_selected_focused_conversations.9.png create mode 100644 src/main/res/drawable-hdpi/tab_selected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-hdpi/tab_unselected_conversations.9.png create mode 100644 src/main/res/drawable-hdpi/tab_unselected_focused_conversations.9.png create mode 100644 src/main/res/drawable-hdpi/tab_unselected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-mdpi/ic_action_add_group.png create mode 100644 src/main/res/drawable-mdpi/ic_action_add_person.png create mode 100644 src/main/res/drawable-mdpi/ic_action_chat.png create mode 100644 src/main/res/drawable-mdpi/ic_action_copy.png create mode 100644 src/main/res/drawable-mdpi/ic_action_discard.png create mode 100644 src/main/res/drawable-mdpi/ic_action_edit.png create mode 100644 src/main/res/drawable-mdpi/ic_action_edit_dark.png create mode 100644 src/main/res/drawable-mdpi/ic_action_group.png create mode 100644 src/main/res/drawable-mdpi/ic_action_new.png create mode 100644 src/main/res/drawable-mdpi/ic_action_new_attachment.png create mode 100644 src/main/res/drawable-mdpi/ic_action_not_secure.png create mode 100644 src/main/res/drawable-mdpi/ic_action_refresh.png create mode 100644 src/main/res/drawable-mdpi/ic_action_remove.png create mode 100644 src/main/res/drawable-mdpi/ic_action_search.png create mode 100644 src/main/res/drawable-mdpi/ic_action_secure.png create mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_away.png create mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-mdpi/ic_activity.png create mode 100644 src/main/res/drawable-mdpi/ic_indicator.png create mode 100644 src/main/res/drawable-mdpi/ic_launcher.png create mode 100644 src/main/res/drawable-mdpi/ic_notification.png create mode 100644 src/main/res/drawable-mdpi/ic_profile.png create mode 100644 src/main/res/drawable-mdpi/ic_received_indicator.png create mode 100644 src/main/res/drawable-mdpi/ic_secure_indicator.png create mode 100644 src/main/res/drawable-mdpi/tab_selected_conversations.9.png create mode 100644 src/main/res/drawable-mdpi/tab_selected_focused_conversations.9.png create mode 100644 src/main/res/drawable-mdpi/tab_selected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-mdpi/tab_unselected_conversations.9.png create mode 100644 src/main/res/drawable-mdpi/tab_unselected_focused_conversations.9.png create mode 100644 src/main/res/drawable-mdpi/tab_unselected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_add_group.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_add_person.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_chat.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_copy.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_discard.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_edit.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_edit_dark.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_group.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_new.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_new_attachment.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_not_secure.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_refresh.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_remove.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_search.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_secure.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_activity.png create mode 100644 src/main/res/drawable-xhdpi/ic_indicator.png create mode 100644 src/main/res/drawable-xhdpi/ic_launcher.png create mode 100644 src/main/res/drawable-xhdpi/ic_notification.png create mode 100644 src/main/res/drawable-xhdpi/ic_profile.png create mode 100644 src/main/res/drawable-xhdpi/ic_received_indicator.png create mode 100644 src/main/res/drawable-xhdpi/ic_secure_indicator.png create mode 100644 src/main/res/drawable-xhdpi/tab_selected_conversations.9.png create mode 100644 src/main/res/drawable-xhdpi/tab_selected_focused_conversations.9.png create mode 100644 src/main/res/drawable-xhdpi/tab_selected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-xhdpi/tab_unselected_conversations.9.png create mode 100644 src/main/res/drawable-xhdpi/tab_unselected_focused_conversations.9.png create mode 100644 src/main/res/drawable-xhdpi/tab_unselected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_add_group.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_add_person.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_chat.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_copy.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_discard.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_edit.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_edit_dark.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_group.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_new.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_new_attachment.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_not_secure.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_refresh.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_remove.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_search.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_secure.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_activity.png create mode 100644 src/main/res/drawable-xxhdpi/ic_indicator.png create mode 100644 src/main/res/drawable-xxhdpi/ic_launcher.png create mode 100644 src/main/res/drawable-xxhdpi/ic_notification.png create mode 100644 src/main/res/drawable-xxhdpi/ic_profile.png create mode 100644 src/main/res/drawable-xxhdpi/ic_received_indicator.png create mode 100644 src/main/res/drawable-xxhdpi/ic_secure_indicator.png create mode 100644 src/main/res/drawable-xxhdpi/tab_selected_conversations.9.png create mode 100644 src/main/res/drawable-xxhdpi/tab_selected_focused_conversations.9.png create mode 100644 src/main/res/drawable-xxhdpi/tab_selected_pressed_conversations.9.png create mode 100644 src/main/res/drawable-xxhdpi/tab_unselected_conversations.9.png create mode 100644 src/main/res/drawable-xxhdpi/tab_unselected_focused_conversations.9.png create mode 100644 src/main/res/drawable-xxhdpi/tab_unselected_pressed_conversations.9.png create mode 100644 src/main/res/drawable/actionbar_tab_indicator.xml create mode 100644 src/main/res/drawable/es_slidingpane_shadow.xml create mode 100644 src/main/res/drawable/grey.xml create mode 100644 src/main/res/drawable/greybackground.xml create mode 100644 src/main/res/drawable/infocard_border.xml create mode 100644 src/main/res/drawable/message_border.xml create mode 100644 src/main/res/drawable/snackbar.xml create mode 100644 src/main/res/layout-w360dp/fragment_conversations_overview.xml create mode 100644 src/main/res/layout-w384dp/fragment_conversations_overview.xml create mode 100644 src/main/res/layout-w600dp/fragment_conversations_overview.xml create mode 100644 src/main/res/layout-w960dp/fragment_conversations_overview.xml create mode 100644 src/main/res/layout/account_row.xml create mode 100644 src/main/res/layout/actionview_search.xml create mode 100644 src/main/res/layout/activity_choose_contact.xml create mode 100644 src/main/res/layout/activity_contact_details.xml create mode 100644 src/main/res/layout/activity_edit_account.xml create mode 100644 src/main/res/layout/activity_muc_details.xml create mode 100644 src/main/res/layout/activity_publish_profile_picture.xml create mode 100644 src/main/res/layout/activity_start_conversation.xml create mode 100644 src/main/res/layout/contact.xml create mode 100644 src/main/res/layout/contact_key.xml create mode 100644 src/main/res/layout/conversation_list_row.xml create mode 100644 src/main/res/layout/create_contact_dialog.xml create mode 100644 src/main/res/layout/dialog_clear_history.xml create mode 100644 src/main/res/layout/dialog_verify_otr.xml create mode 100644 src/main/res/layout/fragment_conversation.xml create mode 100644 src/main/res/layout/fragment_conversations_overview.xml create mode 100644 src/main/res/layout/join_conference_dialog.xml create mode 100644 src/main/res/layout/manage_accounts.xml create mode 100644 src/main/res/layout/message_null.xml create mode 100644 src/main/res/layout/message_received.xml create mode 100644 src/main/res/layout/message_sent.xml create mode 100644 src/main/res/layout/message_status.xml create mode 100644 src/main/res/layout/quickedit.xml create mode 100644 src/main/res/layout/share_with.xml create mode 100644 src/main/res/menu/attachment_choices.xml create mode 100644 src/main/res/menu/choose_contact.xml create mode 100644 src/main/res/menu/conference_context.xml create mode 100644 src/main/res/menu/contact_context.xml create mode 100644 src/main/res/menu/contact_details.xml create mode 100644 src/main/res/menu/conversations.xml create mode 100644 src/main/res/menu/encryption_choices.xml create mode 100644 src/main/res/menu/manageaccounts.xml create mode 100644 src/main/res/menu/manageaccounts_context.xml create mode 100644 src/main/res/menu/muc_details.xml create mode 100644 src/main/res/menu/share_with.xml create mode 100644 src/main/res/menu/start_conversation.xml create mode 100644 src/main/res/values-ca/arrays.xml create mode 100644 src/main/res/values-ca/strings.xml create mode 100644 src/main/res/values-cs/arrays.xml create mode 100644 src/main/res/values-cs/strings.xml create mode 100644 src/main/res/values-de/arrays.xml create mode 100644 src/main/res/values-de/strings.xml create mode 100644 src/main/res/values-es/arrays.xml create mode 100644 src/main/res/values-es/strings.xml create mode 100644 src/main/res/values-eu/arrays.xml create mode 100644 src/main/res/values-eu/strings.xml create mode 100644 src/main/res/values-fr/arrays.xml create mode 100644 src/main/res/values-fr/strings.xml create mode 100644 src/main/res/values-gl/arrays.xml create mode 100644 src/main/res/values-gl/strings.xml create mode 100644 src/main/res/values-it/arrays.xml create mode 100644 src/main/res/values-it/strings.xml create mode 100644 src/main/res/values-iw/arrays.xml create mode 100644 src/main/res/values-iw/strings.xml create mode 100644 src/main/res/values-nl/arrays.xml create mode 100644 src/main/res/values-nl/strings.xml create mode 100644 src/main/res/values-ru/arrays.xml create mode 100644 src/main/res/values-ru/strings.xml create mode 100644 src/main/res/values-sv/arrays.xml create mode 100644 src/main/res/values-sv/strings.xml create mode 100644 src/main/res/values-zh-rCN/arrays.xml create mode 100644 src/main/res/values-zh-rCN/strings.xml create mode 100644 src/main/res/values-zh-rTW/arrays.xml create mode 100644 src/main/res/values-zh-rTW/strings.xml create mode 100644 src/main/res/values/arrays.xml create mode 100644 src/main/res/values/attrs.xml create mode 100644 src/main/res/values/colors.xml create mode 100644 src/main/res/values/strings.xml create mode 100644 src/main/res/values/styles.xml create mode 100644 src/main/res/values/themes.xml create mode 100644 src/main/res/xml/preferences.xml diff --git a/build.gradle b/build.gradle index ab032571..2352b116 100644 --- a/build.gradle +++ b/build.gradle @@ -51,7 +51,11 @@ android { } dependencies { - // ToDo: Move libs here if possible (instead of including the jars) - "compile 'com.android.support:support-v13:19.1.0'" + compile project(':minidns') + compile project(':openpgpapilib') + compile project(':memorizingTrustManager') + compile 'com.android.support:support-v13:19.1.0' + // compile files('libs/bcprov-jdk15on-150.jar') + // compile files('libs/otr4j-0.10.jar') compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/conversations/build.gradle b/conversations/build.gradle deleted file mode 100644 index 08060e59..00000000 --- a/conversations/build.gradle +++ /dev/null @@ -1,28 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 19 - buildToolsVersion "20.0.0" - - defaultConfig { - applicationId "eu.siacs.conversations" - minSdkVersion 14 - targetSdkVersion 19 - } - - buildTypes { - release { - runProguard false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' - } - } -} - -dependencies { - compile project(':minidns') - compile project(':openpgpapilib') - compile project(':memorizingTrustManager') - compile files('libs/android-support-v13.jar') - compile files('libs/bcprov-jdk15on-150.jar') - compile files('libs/otr4j-0.10.jar') -} diff --git a/conversations/src/main/AndroidManifest.xml b/conversations/src/main/AndroidManifest.xml deleted file mode 100644 index 7bde645f..00000000 --- a/conversations/src/main/AndroidManifest.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conversations/src/main/java/eu/siacs/conversations/Config.java b/conversations/src/main/java/eu/siacs/conversations/Config.java deleted file mode 100644 index 1725eca6..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/Config.java +++ /dev/null @@ -1,25 +0,0 @@ -package eu.siacs.conversations; - -import android.graphics.Bitmap; - -public final class Config { - - public static final String LOGTAG = "conversations"; - - public static final int PING_MAX_INTERVAL = 300; - public static final int PING_MIN_INTERVAL = 30; - public static final int PING_TIMEOUT = 10; - public static final int CONNECT_TIMEOUT = 90; - public static final int CARBON_GRACE_PERIOD = 60; - - public static final int AVATAR_SIZE = 192; - public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP; - - public static final int MESSAGE_MERGE_WINDOW = 20; - - public static final boolean PARSE_EMOTICONS = false; - - private Config() { - - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/conversations/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java deleted file mode 100644 index e0bd0e79..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ /dev/null @@ -1,231 +0,0 @@ -package eu.siacs.conversations.crypto; - -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.InvalidKeySpecException; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.util.Log; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; - -import net.java.otr4j.OtrEngineHost; -import net.java.otr4j.OtrException; -import net.java.otr4j.OtrPolicy; -import net.java.otr4j.OtrPolicyImpl; -import net.java.otr4j.session.InstanceTag; -import net.java.otr4j.session.SessionID; - -public class OtrEngine implements OtrEngineHost { - - private Account account; - private OtrPolicy otrPolicy; - private KeyPair keyPair; - private XmppConnectionService mXmppConnectionService; - - public OtrEngine(XmppConnectionService service, Account account) { - this.account = account; - this.otrPolicy = new OtrPolicyImpl(); - this.otrPolicy.setAllowV1(false); - this.otrPolicy.setAllowV2(true); - this.otrPolicy.setAllowV3(true); - this.keyPair = loadKey(account.getKeys()); - this.mXmppConnectionService = service; - } - - private KeyPair loadKey(JSONObject keys) { - if (keys == null) { - return null; - } - try { - BigInteger x = new BigInteger(keys.getString("otr_x"), 16); - BigInteger y = new BigInteger(keys.getString("otr_y"), 16); - BigInteger p = new BigInteger(keys.getString("otr_p"), 16); - BigInteger q = new BigInteger(keys.getString("otr_q"), 16); - BigInteger g = new BigInteger(keys.getString("otr_g"), 16); - KeyFactory keyFactory = KeyFactory.getInstance("DSA"); - DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(y, p, q, g); - DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g); - PublicKey publicKey = keyFactory.generatePublic(pubKeySpec); - PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); - return new KeyPair(publicKey, privateKey); - } catch (JSONException e) { - return null; - } catch (NoSuchAlgorithmException e) { - return null; - } catch (InvalidKeySpecException e) { - return null; - } - } - - private void saveKey() { - PublicKey publicKey = keyPair.getPublic(); - PrivateKey privateKey = keyPair.getPrivate(); - KeyFactory keyFactory; - try { - keyFactory = KeyFactory.getInstance("DSA"); - DSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec( - privateKey, DSAPrivateKeySpec.class); - DSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, - DSAPublicKeySpec.class); - this.account.setKey("otr_x", privateKeySpec.getX().toString(16)); - this.account.setKey("otr_g", privateKeySpec.getG().toString(16)); - this.account.setKey("otr_p", privateKeySpec.getP().toString(16)); - this.account.setKey("otr_q", privateKeySpec.getQ().toString(16)); - this.account.setKey("otr_y", publicKeySpec.getY().toString(16)); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (InvalidKeySpecException e) { - e.printStackTrace(); - } - - } - - @Override - public void askForSecret(SessionID arg0, InstanceTag arg1, String arg2) { - // TODO Auto-generated method stub - - } - - @Override - public void finishedSessionMessage(SessionID arg0, String arg1) - throws OtrException { - - } - - @Override - public String getFallbackMessage(SessionID arg0) { - return "I would like to start a private (OTR encrypted) conversation but your client doesn’t seem to support that"; - } - - @Override - public byte[] getLocalFingerprintRaw(SessionID arg0) { - // TODO Auto-generated method stub - return null; - } - - public PublicKey getPublicKey() { - if (this.keyPair == null) { - return null; - } - return this.keyPair.getPublic(); - } - - @Override - public KeyPair getLocalKeyPair(SessionID arg0) throws OtrException { - if (this.keyPair == null) { - KeyPairGenerator kg; - try { - kg = KeyPairGenerator.getInstance("DSA"); - this.keyPair = kg.genKeyPair(); - this.saveKey(); - mXmppConnectionService.databaseBackend.updateAccount(account); - } catch (NoSuchAlgorithmException e) { - Log.d(Config.LOGTAG, - "error generating key pair " + e.getMessage()); - } - } - return this.keyPair; - } - - @Override - public String getReplyForUnreadableMessage(SessionID arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public OtrPolicy getSessionPolicy(SessionID arg0) { - return otrPolicy; - } - - @Override - public void injectMessage(SessionID session, String body) - throws OtrException { - MessagePacket packet = new MessagePacket(); - packet.setFrom(account.getFullJid()); - if (session.getUserID().isEmpty()) { - packet.setTo(session.getAccountID()); - } else { - packet.setTo(session.getAccountID() + "/" + session.getUserID()); - } - packet.setBody(body); - packet.addChild("private", "urn:xmpp:carbons:2"); - packet.addChild("no-copy", "urn:xmpp:hints"); - packet.setType(MessagePacket.TYPE_CHAT); - account.getXmppConnection().sendMessagePacket(packet); - } - - @Override - public void messageFromAnotherInstanceReceived(SessionID id) { - Log.d(Config.LOGTAG, - "unreadable message received from " + id.getAccountID()); - } - - @Override - public void multipleInstancesDetected(SessionID arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void requireEncryptedMessage(SessionID arg0, String arg1) - throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void showError(SessionID arg0, String arg1) throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void smpAborted(SessionID arg0) throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void smpError(SessionID arg0, int arg1, boolean arg2) - throws OtrException { - throw new OtrException(new Exception("smp error")); - } - - @Override - public void unencryptedMessageReceived(SessionID arg0, String arg1) - throws OtrException { - throw new OtrException(new Exception("unencrypted message received")); - } - - @Override - public void unreadableMessageReceived(SessionID arg0) throws OtrException { - throw new OtrException(new Exception("unreadable message received")); - } - - @Override - public void unverify(SessionID arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void verify(SessionID arg0, String arg1, boolean arg2) { - // TODO Auto-generated method stub - - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/conversations/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java deleted file mode 100644 index 2696c7d2..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ /dev/null @@ -1,385 +0,0 @@ -package eu.siacs.conversations.crypto; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.openintents.openpgp.OpenPgpError; -import org.openintents.openpgp.OpenPgpSignatureResult; -import org.openintents.openpgp.util.OpenPgpApi; -import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.ui.UiCallback; -import android.app.PendingIntent; -import android.content.Intent; -import android.graphics.BitmapFactory; -import android.util.Log; - -public class PgpEngine { - private OpenPgpApi api; - private XmppConnectionService mXmppConnectionService; - - public PgpEngine(OpenPgpApi api, XmppConnectionService service) { - this.api = api; - this.mXmppConnectionService = service; - } - - public void decrypt(final Message message, - final UiCallback callback) { - Log.d(Config.LOGTAG, "decrypting message " + message.getUuid()); - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message - .getConversation().getAccount().getJid()); - if (message.getType() == Message.TYPE_TEXT) { - InputStream is = new ByteArrayInputStream(message.getBody() - .getBytes()); - final OutputStream os = new ByteArrayOutputStream(); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - try { - os.flush(); - if (message.getEncryption() == Message.ENCRYPTION_PGP) { - message.setBody(os.toString()); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - callback.success(message); - } - } catch (IOException e) { - callback.error(R.string.openpgp_error, message); - return; - } - - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT), - message); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - OpenPgpError error = result - .getParcelableExtra(OpenPgpApi.RESULT_ERROR); - Log.d(Config.LOGTAG, - "openpgp error: " + error.getMessage()); - callback.error(R.string.openpgp_error, message); - return; - default: - return; - } - } - }); - } else if (message.getType() == Message.TYPE_IMAGE) { - try { - final DownloadableFile inputFile = this.mXmppConnectionService - .getFileBackend().getFile(message, false); - final DownloadableFile outputFile = this.mXmppConnectionService - .getFileBackend().getFile(message, true); - outputFile.createNewFile(); - InputStream is = new FileInputStream(inputFile); - OutputStream os = new FileOutputStream(outputFile); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile( - outputFile.getAbsolutePath(), options); - int imageHeight = options.outHeight; - int imageWidth = options.outWidth; - message.setBody(Long.toString(outputFile.getSize()) - + ',' + imageWidth + ',' + imageHeight); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - PgpEngine.this.mXmppConnectionService - .updateMessage(message); - ; - callback.success(message); - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried( - (PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT), - message); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error(R.string.openpgp_error, message); - return; - default: - return; - } - } - }); - } catch (FileNotFoundException e) { - callback.error(R.string.error_decrypting_file, message); - } catch (IOException e) { - callback.error(R.string.error_decrypting_file, message); - } - - } - } - - public void encrypt(final Message message, - final UiCallback callback) { - - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_ENCRYPT); - if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { - long[] keys = { message.getConversation().getContact() - .getPgpKeyId() }; - params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keys); - } else { - params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, message.getConversation() - .getMucOptions().getPgpKeyIds()); - } - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message - .getConversation().getAccount().getJid()); - - if (message.getType() == Message.TYPE_TEXT) { - params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - - InputStream is = new ByteArrayInputStream(message.getBody() - .getBytes()); - final OutputStream os = new ByteArrayOutputStream(); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - try { - os.flush(); - StringBuilder encryptedMessageBody = new StringBuilder(); - String[] lines = os.toString().split("\n"); - for (int i = 2; i < lines.length - 1; ++i) { - if (!lines[i].contains("Version")) { - encryptedMessageBody.append(lines[i].trim()); - } - } - message.setEncryptedBody(encryptedMessageBody - .toString()); - callback.success(message); - } catch (IOException e) { - callback.error(R.string.openpgp_error, message); - } - - break; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT), - message); - break; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error(R.string.openpgp_error, message); - break; - } - } - }); - } else if (message.getType() == Message.TYPE_IMAGE) { - try { - DownloadableFile inputFile = this.mXmppConnectionService - .getFileBackend().getFile(message, true); - DownloadableFile outputFile = this.mXmppConnectionService - .getFileBackend().getFile(message, false); - outputFile.createNewFile(); - InputStream is = new FileInputStream(inputFile); - OutputStream os = new FileOutputStream(outputFile); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - callback.success(message); - break; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried( - (PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT), - message); - break; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error(R.string.openpgp_error, message); - break; - } - } - }); - } catch (FileNotFoundException e) { - Log.d(Config.LOGTAG, "file not found: " + e.getMessage()); - } catch (IOException e) { - Log.d(Config.LOGTAG, "io exception during file encrypt"); - } - } - } - - public long fetchKeyId(Account account, String status, String signature) { - if ((signature == null) || (api == null)) { - return 0; - } - if (status == null) { - status = ""; - } - StringBuilder pgpSig = new StringBuilder(); - pgpSig.append("-----BEGIN PGP SIGNED MESSAGE-----"); - pgpSig.append('\n'); - pgpSig.append('\n'); - pgpSig.append(status); - pgpSig.append('\n'); - pgpSig.append("-----BEGIN PGP SIGNATURE-----"); - pgpSig.append('\n'); - pgpSig.append('\n'); - pgpSig.append(signature.replace("\n", "").trim()); - pgpSig.append('\n'); - pgpSig.append("-----END PGP SIGNATURE-----"); - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); - params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); - InputStream is = new ByteArrayInputStream(pgpSig.toString().getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Intent result = api.executeApi(params, is, os); - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - OpenPgpSignatureResult sigResult = result - .getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE); - if (sigResult != null) { - return sigResult.getKeyId(); - } else { - return 0; - } - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - return 0; - case OpenPgpApi.RESULT_CODE_ERROR: - Log.d(Config.LOGTAG, - "openpgp error: " - + ((OpenPgpError) result - .getParcelableExtra(OpenPgpApi.RESULT_ERROR)) - .getMessage()); - return 0; - } - return 0; - } - - public void generateSignature(final Account account, String status, - final UiCallback callback) { - Intent params = new Intent(); - params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - params.setAction(OpenPgpApi.ACTION_SIGN); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); - InputStream is = new ByteArrayInputStream(status.getBytes()); - final OutputStream os = new ByteArrayOutputStream(); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - StringBuilder signatureBuilder = new StringBuilder(); - try { - os.flush(); - String[] lines = os.toString().split("\n"); - boolean sig = false; - for (String line : lines) { - if (sig) { - if (line.contains("END PGP SIGNATURE")) { - sig = false; - } else { - if (!line.contains("Version")) { - signatureBuilder.append(line.trim()); - } - } - } - if (line.contains("BEGIN PGP SIGNATURE")) { - sig = true; - } - } - } catch (IOException e) { - callback.error(R.string.openpgp_error, account); - return; - } - account.setKey("pgp_signature", signatureBuilder.toString()); - callback.success(account); - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT), - account); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error(R.string.openpgp_error, account); - return; - } - } - }); - } - - public void hasKey(final Contact contact, final UiCallback callback) { - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_GET_KEY); - params.putExtra(OpenPgpApi.EXTRA_KEY_ID, contact.getPgpKeyId()); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, contact.getAccount() - .getJid()); - api.executeApiAsync(params, null, null, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - callback.success(contact); - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT), - contact); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error(R.string.openpgp_error, contact); - return; - } - } - }); - } - - public PendingIntent getIntentForKey(Contact contact) { - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_GET_KEY); - params.putExtra(OpenPgpApi.EXTRA_KEY_ID, contact.getPgpKeyId()); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, contact.getAccount() - .getJid()); - Intent result = api.executeApi(params, null, null); - return (PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT); - } - - public PendingIntent getIntentForKey(Account account, long pgpKeyId) { - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_GET_KEY); - params.putExtra(OpenPgpApi.EXTRA_KEY_ID, pgpKeyId); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); - Intent result = api.executeApi(params, null, null); - return (PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/AbstractEntity.java b/conversations/src/main/java/eu/siacs/conversations/entities/AbstractEntity.java deleted file mode 100644 index 92b8a729..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/AbstractEntity.java +++ /dev/null @@ -1,21 +0,0 @@ -package eu.siacs.conversations.entities; - -import android.content.ContentValues; - -public abstract class AbstractEntity { - - public static final String UUID = "uuid"; - - protected String uuid; - - public String getUuid() { - return this.uuid; - } - - public abstract ContentValues getContentValues(); - - public boolean equals(AbstractEntity entity) { - return this.getUuid().equals(entity.getUuid()); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Account.java b/conversations/src/main/java/eu/siacs/conversations/entities/Account.java deleted file mode 100644 index 80a9d62f..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Account.java +++ /dev/null @@ -1,399 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.security.interfaces.DSAPublicKey; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.CopyOnWriteArrayList; - -import net.java.otr4j.crypto.OtrCryptoEngineImpl; -import net.java.otr4j.crypto.OtrCryptoException; - -import org.json.JSONException; -import org.json.JSONObject; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.OtrEngine; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xmpp.XmppConnection; -import android.content.ContentValues; -import android.database.Cursor; -import android.os.SystemClock; - -public class Account extends AbstractEntity { - - public static final String TABLENAME = "accounts"; - - public static final String USERNAME = "username"; - public static final String SERVER = "server"; - public static final String PASSWORD = "password"; - public static final String OPTIONS = "options"; - public static final String ROSTERVERSION = "rosterversion"; - public static final String KEYS = "keys"; - public static final String AVATAR = "avatar"; - - public static final int OPTION_USETLS = 0; - public static final int OPTION_DISABLED = 1; - public static final int OPTION_REGISTER = 2; - public static final int OPTION_USECOMPRESSION = 3; - - public static final int STATUS_CONNECTING = 0; - public static final int STATUS_DISABLED = -2; - public static final int STATUS_OFFLINE = -1; - public static final int STATUS_ONLINE = 1; - public static final int STATUS_NO_INTERNET = 2; - public static final int STATUS_UNAUTHORIZED = 3; - public static final int STATUS_SERVER_NOT_FOUND = 5; - - public static final int STATUS_REGISTRATION_FAILED = 7; - public static final int STATUS_REGISTRATION_CONFLICT = 8; - public static final int STATUS_REGISTRATION_SUCCESSFULL = 9; - public static final int STATUS_REGISTRATION_NOT_SUPPORTED = 10; - - protected String username; - protected String server; - protected String password; - protected int options = 0; - protected String rosterVersion; - protected String resource = "mobile"; - protected int status = -1; - protected JSONObject keys = new JSONObject(); - protected String avatar; - - protected boolean online = false; - - private OtrEngine otrEngine = null; - private XmppConnection xmppConnection = null; - private Presences presences = new Presences(); - private long mEndGracePeriod = 0L; - private String otrFingerprint; - private Roster roster = null; - - private List bookmarks = new CopyOnWriteArrayList(); - public List pendingConferenceJoins = new CopyOnWriteArrayList(); - public List pendingConferenceLeaves = new CopyOnWriteArrayList(); - - public Account() { - this.uuid = "0"; - } - - public Account(String username, String server, String password) { - this(java.util.UUID.randomUUID().toString(), username, server, - password, 0, null, "", null); - } - - public Account(String uuid, String username, String server, - String password, int options, String rosterVersion, String keys, - String avatar) { - this.uuid = uuid; - this.username = username; - this.server = server; - this.password = password; - this.options = options; - this.rosterVersion = rosterVersion; - try { - this.keys = new JSONObject(keys); - } catch (JSONException e) { - - } - this.avatar = avatar; - } - - public boolean isOptionSet(int option) { - return ((options & (1 << option)) != 0); - } - - public void setOption(int option, boolean value) { - if (value) { - this.options |= 1 << option; - } else { - this.options &= ~(1 << option); - } - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setStatus(int status) { - this.status = status; - } - - public int getStatus() { - if (isOptionSet(OPTION_DISABLED)) { - return STATUS_DISABLED; - } else { - return this.status; - } - } - - public boolean errorStatus() { - int s = getStatus(); - return (s == STATUS_REGISTRATION_FAILED - || s == STATUS_REGISTRATION_CONFLICT - || s == STATUS_REGISTRATION_NOT_SUPPORTED - || s == STATUS_SERVER_NOT_FOUND || s == STATUS_UNAUTHORIZED); - } - - public boolean hasErrorStatus() { - if (getXmppConnection() == null) { - return false; - } else { - return getStatus() > STATUS_NO_INTERNET - && (getXmppConnection().getAttempt() >= 2); - } - } - - public void setResource(String resource) { - this.resource = resource; - } - - public String getResource() { - return this.resource; - } - - public String getJid() { - return username.toLowerCase(Locale.getDefault()) + "@" - + server.toLowerCase(Locale.getDefault()); - } - - public JSONObject getKeys() { - return keys; - } - - public String getSSLFingerprint() { - if (keys.has("ssl_cert")) { - try { - return keys.getString("ssl_cert"); - } catch (JSONException e) { - return null; - } - } else { - return null; - } - } - - public void setSSLCertFingerprint(String fingerprint) { - this.setKey("ssl_cert", fingerprint); - } - - public boolean setKey(String keyName, String keyValue) { - try { - this.keys.put(keyName, keyValue); - return true; - } catch (JSONException e) { - return false; - } - } - - @Override - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(USERNAME, username); - values.put(SERVER, server); - values.put(PASSWORD, password); - values.put(OPTIONS, options); - values.put(KEYS, this.keys.toString()); - values.put(ROSTERVERSION, rosterVersion); - values.put(AVATAR, avatar); - return values; - } - - public static Account fromCursor(Cursor cursor) { - return new Account(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(USERNAME)), - cursor.getString(cursor.getColumnIndex(SERVER)), - cursor.getString(cursor.getColumnIndex(PASSWORD)), - cursor.getInt(cursor.getColumnIndex(OPTIONS)), - cursor.getString(cursor.getColumnIndex(ROSTERVERSION)), - cursor.getString(cursor.getColumnIndex(KEYS)), - cursor.getString(cursor.getColumnIndex(AVATAR))); - } - - public OtrEngine getOtrEngine(XmppConnectionService context) { - if (otrEngine == null) { - otrEngine = new OtrEngine(context, this); - } - return this.otrEngine; - } - - public XmppConnection getXmppConnection() { - return this.xmppConnection; - } - - public void setXmppConnection(XmppConnection connection) { - this.xmppConnection = connection; - } - - public String getFullJid() { - return this.getJid() + "/" + this.resource; - } - - public String getOtrFingerprint() { - if (this.otrFingerprint == null) { - try { - DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine - .getPublicKey(); - if (pubkey == null) { - return null; - } - StringBuilder builder = new StringBuilder( - new OtrCryptoEngineImpl().getFingerprint(pubkey)); - builder.insert(8, " "); - builder.insert(17, " "); - builder.insert(26, " "); - builder.insert(35, " "); - this.otrFingerprint = builder.toString(); - } catch (OtrCryptoException e) { - - } - } - return this.otrFingerprint; - } - - public String getRosterVersion() { - if (this.rosterVersion == null) { - return ""; - } else { - return this.rosterVersion; - } - } - - public void setRosterVersion(String version) { - this.rosterVersion = version; - } - - public String getOtrFingerprint(XmppConnectionService service) { - this.getOtrEngine(service); - return this.getOtrFingerprint(); - } - - public void updatePresence(String resource, int status) { - this.presences.updatePresence(resource, status); - } - - public void removePresence(String resource) { - this.presences.removePresence(resource); - } - - public void clearPresences() { - this.presences = new Presences(); - } - - public int countPresences() { - return this.presences.size(); - } - - public String getPgpSignature() { - if (keys.has("pgp_signature")) { - try { - return keys.getString("pgp_signature"); - } catch (JSONException e) { - return null; - } - } else { - return null; - } - } - - public Roster getRoster() { - if (this.roster == null) { - this.roster = new Roster(this); - } - return this.roster; - } - - public void setBookmarks(List bookmarks) { - this.bookmarks = bookmarks; - } - - public List getBookmarks() { - return this.bookmarks; - } - - public boolean hasBookmarkFor(String conferenceJid) { - for (Bookmark bmark : this.bookmarks) { - if (bmark.getJid().equals(conferenceJid)) { - return true; - } - } - return false; - } - - public boolean setAvatar(String filename) { - if (this.avatar != null && this.avatar.equals(filename)) { - return false; - } else { - this.avatar = filename; - return true; - } - } - - public String getAvatar() { - return this.avatar; - } - - public int getReadableStatusId() { - switch (getStatus()) { - - case Account.STATUS_DISABLED: - return R.string.account_status_disabled; - case Account.STATUS_ONLINE: - return R.string.account_status_online; - case Account.STATUS_CONNECTING: - return R.string.account_status_connecting; - case Account.STATUS_OFFLINE: - return R.string.account_status_offline; - case Account.STATUS_UNAUTHORIZED: - return R.string.account_status_unauthorized; - case Account.STATUS_SERVER_NOT_FOUND: - return R.string.account_status_not_found; - case Account.STATUS_NO_INTERNET: - return R.string.account_status_no_internet; - case Account.STATUS_REGISTRATION_FAILED: - return R.string.account_status_regis_fail; - case Account.STATUS_REGISTRATION_CONFLICT: - return R.string.account_status_regis_conflict; - case Account.STATUS_REGISTRATION_SUCCESSFULL: - return R.string.account_status_regis_success; - case Account.STATUS_REGISTRATION_NOT_SUPPORTED: - return R.string.account_status_regis_not_sup; - default: - return R.string.account_status_unknown; - } - } - - public void activateGracePeriod() { - this.mEndGracePeriod = SystemClock.elapsedRealtime() - + (Config.CARBON_GRACE_PERIOD * 1000); - } - - public void deactivateGracePeriod() { - this.mEndGracePeriod = 0L; - } - - public boolean inGracePeriod() { - return SystemClock.elapsedRealtime() < this.mEndGracePeriod; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Bookmark.java b/conversations/src/main/java/eu/siacs/conversations/entities/Bookmark.java deleted file mode 100644 index dd9e805c..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Bookmark.java +++ /dev/null @@ -1,137 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.util.Locale; - -import eu.siacs.conversations.xml.Element; - -public class Bookmark extends Element implements ListItem { - - private Account account; - private Conversation mJoinedConversation; - - public Bookmark(Account account, String jid) { - super("conference"); - this.setAttribute("jid", jid); - this.account = account; - } - - private Bookmark(Account account) { - super("conference"); - this.account = account; - } - - public static Bookmark parse(Element element, Account account) { - Bookmark bookmark = new Bookmark(account); - bookmark.setAttributes(element.getAttributes()); - bookmark.setChildren(element.getChildren()); - return bookmark; - } - - public void setAutojoin(boolean autojoin) { - if (autojoin) { - this.setAttribute("autojoin", "true"); - } else { - this.setAttribute("autojoin", "false"); - } - } - - public void setName(String name) { - this.name = name; - } - - public void setNick(String nick) { - Element element = this.findChild("nick"); - if (element == null) { - element = this.addChild("nick"); - } - element.setContent(nick); - } - - public void setPassword(String password) { - Element element = this.findChild("password"); - if (element != null) { - element.setContent(password); - } - } - - @Override - public int compareTo(ListItem another) { - return this.getDisplayName().compareToIgnoreCase( - another.getDisplayName()); - } - - @Override - public String getDisplayName() { - if (this.mJoinedConversation != null - && (this.mJoinedConversation.getMucOptions().getSubject() != null)) { - return this.mJoinedConversation.getMucOptions().getSubject(); - } else if (getName() != null) { - return getName(); - } else { - return this.getJid().split("@")[0]; - } - } - - @Override - public String getJid() { - String jid = this.getAttribute("jid"); - if (jid != null) { - return jid.toLowerCase(Locale.US); - } else { - return null; - } - } - - public String getNick() { - Element nick = this.findChild("nick"); - if (nick != null) { - return nick.getContent(); - } else { - return null; - } - } - - public boolean autojoin() { - String autojoin = this.getAttribute("autojoin"); - return (autojoin != null && (autojoin.equalsIgnoreCase("true") || autojoin - .equalsIgnoreCase("1"))); - } - - public String getPassword() { - Element password = this.findChild("password"); - if (password != null) { - return password.getContent(); - } else { - return null; - } - } - - public boolean match(String needle) { - return needle == null - || getJid().contains(needle.toLowerCase(Locale.US)) - || getDisplayName().toLowerCase(Locale.US).contains( - needle.toLowerCase(Locale.US)); - } - - public Account getAccount() { - return this.account; - } - - public void setConversation(Conversation conversation) { - this.mJoinedConversation = conversation; - } - - public Conversation getConversation() { - return this.mJoinedConversation; - } - - public String getName() { - return this.getAttribute("name"); - } - - public void unregisterConversation() { - if (this.mJoinedConversation != null) { - this.mJoinedConversation.deregisterWithBookmark(); - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Contact.java b/conversations/src/main/java/eu/siacs/conversations/entities/Contact.java deleted file mode 100644 index 60c31a42..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Contact.java +++ /dev/null @@ -1,367 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import eu.siacs.conversations.xml.Element; -import android.content.ContentValues; -import android.database.Cursor; - -public class Contact implements ListItem { - public static final String TABLENAME = "contacts"; - - public static final String SYSTEMNAME = "systemname"; - public static final String SERVERNAME = "servername"; - public static final String JID = "jid"; - public static final String OPTIONS = "options"; - public static final String SYSTEMACCOUNT = "systemaccount"; - public static final String PHOTOURI = "photouri"; - public static final String KEYS = "pgpkey"; - public static final String ACCOUNT = "accountUuid"; - public static final String AVATAR = "avatar"; - - protected String accountUuid; - protected String systemName; - protected String serverName; - protected String presenceName; - protected String jid; - protected int subscription = 0; - protected String systemAccount; - protected String photoUri; - protected String avatar; - protected JSONObject keys = new JSONObject(); - protected Presences presences = new Presences(); - - protected Account account; - - protected boolean inRoster = true; - - public Lastseen lastseen = new Lastseen(); - - public Contact(String account, String systemName, String serverName, - String jid, int subscription, String photoUri, - String systemAccount, String keys, String avatar) { - this.accountUuid = account; - this.systemName = systemName; - this.serverName = serverName; - this.jid = jid; - this.subscription = subscription; - this.photoUri = photoUri; - this.systemAccount = systemAccount; - if (keys == null) { - keys = ""; - } - try { - this.keys = new JSONObject(keys); - } catch (JSONException e) { - this.keys = new JSONObject(); - } - this.avatar = avatar; - } - - public Contact(String jid) { - this.jid = jid; - } - - public String getDisplayName() { - if (this.systemName != null) { - return this.systemName; - } else if (this.serverName != null) { - return this.serverName; - } else if (this.presenceName != null) { - return this.presenceName; - } else { - return this.jid.split("@")[0]; - } - } - - public String getProfilePhoto() { - return this.photoUri; - } - - public String getJid() { - return this.jid.toLowerCase(Locale.getDefault()); - } - - public boolean match(String needle) { - return needle == null - || jid.contains(needle.toLowerCase()) - || getDisplayName().toLowerCase() - .contains(needle.toLowerCase()); - } - - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(ACCOUNT, accountUuid); - values.put(SYSTEMNAME, systemName); - values.put(SERVERNAME, serverName); - values.put(JID, jid); - values.put(OPTIONS, subscription); - values.put(SYSTEMACCOUNT, systemAccount); - values.put(PHOTOURI, photoUri); - values.put(KEYS, keys.toString()); - values.put(AVATAR, avatar); - return values; - } - - public static Contact fromCursor(Cursor cursor) { - return new Contact(cursor.getString(cursor.getColumnIndex(ACCOUNT)), - cursor.getString(cursor.getColumnIndex(SYSTEMNAME)), - cursor.getString(cursor.getColumnIndex(SERVERNAME)), - cursor.getString(cursor.getColumnIndex(JID)), - cursor.getInt(cursor.getColumnIndex(OPTIONS)), - cursor.getString(cursor.getColumnIndex(PHOTOURI)), - cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)), - cursor.getString(cursor.getColumnIndex(KEYS)), - cursor.getString(cursor.getColumnIndex(AVATAR))); - } - - public int getSubscription() { - return this.subscription; - } - - public void setSystemAccount(String account) { - this.systemAccount = account; - } - - public void setAccount(Account account) { - this.account = account; - this.accountUuid = account.getUuid(); - } - - public Account getAccount() { - return this.account; - } - - public Presences getPresences() { - return this.presences; - } - - public void updatePresence(String resource, int status) { - this.presences.updatePresence(resource, status); - } - - public void removePresence(String resource) { - this.presences.removePresence(resource); - } - - public void clearPresences() { - this.presences.clearPresences(); - this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST); - } - - public int getMostAvailableStatus() { - return this.presences.getMostAvailableStatus(); - } - - public void setPresences(Presences pres) { - this.presences = pres; - } - - public void setPhotoUri(String uri) { - this.photoUri = uri; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - public void setSystemName(String systemName) { - this.systemName = systemName; - } - - public void setPresenceName(String presenceName) { - this.presenceName = presenceName; - } - - public String getSystemAccount() { - return systemAccount; - } - - public Set getOtrFingerprints() { - Set set = new HashSet(); - try { - if (this.keys.has("otr_fingerprints")) { - JSONArray fingerprints = this.keys - .getJSONArray("otr_fingerprints"); - for (int i = 0; i < fingerprints.length(); ++i) { - set.add(fingerprints.getString(i)); - } - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return set; - } - - public void addOtrFingerprint(String print) { - try { - JSONArray fingerprints; - if (!this.keys.has("otr_fingerprints")) { - fingerprints = new JSONArray(); - - } else { - fingerprints = this.keys.getJSONArray("otr_fingerprints"); - } - fingerprints.put(print); - this.keys.put("otr_fingerprints", fingerprints); - } catch (JSONException e) { - - } - } - - public void setPgpKeyId(long keyId) { - try { - this.keys.put("pgp_keyid", keyId); - } catch (JSONException e) { - - } - } - - public long getPgpKeyId() { - if (this.keys.has("pgp_keyid")) { - try { - return this.keys.getLong("pgp_keyid"); - } catch (JSONException e) { - return 0; - } - } else { - return 0; - } - } - - public void setOption(int option) { - this.subscription |= 1 << option; - } - - public void resetOption(int option) { - this.subscription &= ~(1 << option); - } - - public boolean getOption(int option) { - return ((this.subscription & (1 << option)) != 0); - } - - public boolean showInRoster() { - return (this.getOption(Contact.Options.IN_ROSTER) && (!this - .getOption(Contact.Options.DIRTY_DELETE))) - || (this.getOption(Contact.Options.DIRTY_PUSH)); - } - - public void parseSubscriptionFromElement(Element item) { - String ask = item.getAttribute("ask"); - String subscription = item.getAttribute("subscription"); - - if (subscription != null) { - if (subscription.equals("to")) { - this.resetOption(Contact.Options.FROM); - this.setOption(Contact.Options.TO); - } else if (subscription.equals("from")) { - this.resetOption(Contact.Options.TO); - this.setOption(Contact.Options.FROM); - this.resetOption(Contact.Options.PREEMPTIVE_GRANT); - } else if (subscription.equals("both")) { - this.setOption(Contact.Options.TO); - this.setOption(Contact.Options.FROM); - this.resetOption(Contact.Options.PREEMPTIVE_GRANT); - } else if (subscription.equals("none")) { - this.resetOption(Contact.Options.FROM); - this.resetOption(Contact.Options.TO); - } - } - - // do NOT override asking if pending push request - if (!this.getOption(Contact.Options.DIRTY_PUSH)) { - if ((ask != null) && (ask.equals("subscribe"))) { - this.setOption(Contact.Options.ASKING); - } else { - this.resetOption(Contact.Options.ASKING); - } - } - } - - public Element asElement() { - Element item = new Element("item"); - item.setAttribute("jid", this.jid); - if (this.serverName != null) { - item.setAttribute("name", this.serverName); - } - return item; - } - - public class Options { - public static final int TO = 0; - public static final int FROM = 1; - public static final int ASKING = 2; - public static final int PREEMPTIVE_GRANT = 3; - public static final int IN_ROSTER = 4; - public static final int PENDING_SUBSCRIPTION_REQUEST = 5; - public static final int DIRTY_PUSH = 6; - public static final int DIRTY_DELETE = 7; - } - - public class Lastseen { - public long time = 0; - public String presence = null; - } - - @Override - public int compareTo(ListItem another) { - return this.getDisplayName().compareToIgnoreCase( - another.getDisplayName()); - } - - public String getServer() { - String[] split = getJid().split("@"); - if (split.length >= 2) { - return split[1]; - } else { - return null; - } - } - - public boolean setAvatar(String filename) { - if (this.avatar != null && this.avatar.equals(filename)) { - return false; - } else { - this.avatar = filename; - return true; - } - } - - public String getAvatar() { - return this.avatar; - } - - public boolean deleteOtrFingerprint(String fingerprint) { - boolean success = false; - try { - if (this.keys.has("otr_fingerprints")) { - JSONArray newPrints = new JSONArray(); - JSONArray oldPrints = this.keys - .getJSONArray("otr_fingerprints"); - for (int i = 0; i < oldPrints.length(); ++i) { - if (!oldPrints.getString(i).equals(fingerprint)) { - newPrints.put(oldPrints.getString(i)); - } else { - success = true; - } - } - this.keys.put("otr_fingerprints", newPrints); - } - return success; - } catch (JSONException e) { - return false; - } - } - - public boolean trusted() { - return getOption(Options.FROM) && getOption(Options.TO); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Conversation.java b/conversations/src/main/java/eu/siacs/conversations/entities/Conversation.java deleted file mode 100644 index 9d4c36db..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ /dev/null @@ -1,500 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.security.interfaces.DSAPublicKey; -import java.util.ArrayList; -import java.util.List; - -import org.json.JSONException; -import org.json.JSONObject; - -import eu.siacs.conversations.services.XmppConnectionService; - -import net.java.otr4j.OtrException; -import net.java.otr4j.crypto.OtrCryptoEngineImpl; -import net.java.otr4j.crypto.OtrCryptoException; -import net.java.otr4j.session.SessionID; -import net.java.otr4j.session.SessionImpl; -import net.java.otr4j.session.SessionStatus; -import android.content.ContentValues; -import android.database.Cursor; -import android.os.SystemClock; - -public class Conversation extends AbstractEntity { - public static final String TABLENAME = "conversations"; - - public static final int STATUS_AVAILABLE = 0; - public static final int STATUS_ARCHIVED = 1; - public static final int STATUS_DELETED = 2; - - public static final int MODE_MULTI = 1; - public static final int MODE_SINGLE = 0; - - public static final String NAME = "name"; - public static final String ACCOUNT = "accountUuid"; - public static final String CONTACT = "contactUuid"; - public static final String CONTACTJID = "contactJid"; - public static final String STATUS = "status"; - public static final String CREATED = "created"; - public static final String MODE = "mode"; - public static final String ATTRIBUTES = "attributes"; - - public static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption"; - public static final String ATTRIBUTE_MUC_PASSWORD = "muc_password"; - public static final String ATTRIBUTE_MUTED_TILL = "muted_till"; - - private String name; - private String contactUuid; - private String accountUuid; - private String contactJid; - private int status; - private long created; - private int mode; - - private JSONObject attributes = new JSONObject(); - - private String nextPresence; - - protected ArrayList messages = new ArrayList(); - protected Account account = null; - - private transient SessionImpl otrSession; - - private transient String otrFingerprint = null; - - private String nextMessage; - - private transient MucOptions mucOptions = null; - - // private transient String latestMarkableMessageId; - - private byte[] symmetricKey; - - private Bookmark bookmark; - - public Conversation(String name, Account account, String contactJid, - int mode) { - this(java.util.UUID.randomUUID().toString(), name, null, account - .getUuid(), contactJid, System.currentTimeMillis(), - STATUS_AVAILABLE, mode, ""); - this.account = account; - } - - public Conversation(String uuid, String name, String contactUuid, - String accountUuid, String contactJid, long created, int status, - int mode, String attributes) { - this.uuid = uuid; - this.name = name; - this.contactUuid = contactUuid; - this.accountUuid = accountUuid; - this.contactJid = contactJid; - this.created = created; - this.status = status; - this.mode = mode; - try { - if (attributes == null) { - attributes = new String(); - } - this.attributes = new JSONObject(attributes); - } catch (JSONException e) { - this.attributes = new JSONObject(); - } - } - - public List getMessages() { - return messages; - } - - public boolean isRead() { - if ((this.messages == null) || (this.messages.size() == 0)) - return true; - return this.messages.get(this.messages.size() - 1).isRead(); - } - - public void markRead() { - if (this.messages == null) { - return; - } - for (int i = this.messages.size() - 1; i >= 0; --i) { - if (messages.get(i).isRead()) { - break; - } - this.messages.get(i).markRead(); - } - } - - public String getLatestMarkableMessageId() { - if (this.messages == null) { - return null; - } - for (int i = this.messages.size() - 1; i >= 0; --i) { - if (this.messages.get(i).getStatus() <= Message.STATUS_RECEIVED - && this.messages.get(i).markable) { - if (this.messages.get(i).isRead()) { - return null; - } else { - return this.messages.get(i).getRemoteMsgId(); - } - } - } - return null; - } - - public Message getLatestMessage() { - if ((this.messages == null) || (this.messages.size() == 0)) { - Message message = new Message(this, "", Message.ENCRYPTION_NONE); - message.setTime(getCreated()); - return message; - } else { - Message message = this.messages.get(this.messages.size() - 1); - message.setConversation(this); - return message; - } - } - - public void setMessages(ArrayList msgs) { - this.messages = msgs; - } - - public String getName() { - if (getMode() == MODE_MULTI && getMucOptions().getSubject() != null) { - return getMucOptions().getSubject(); - } else if (getMode() == MODE_MULTI && bookmark != null - && bookmark.getName() != null) { - return bookmark.getName(); - } else { - return this.getContact().getDisplayName(); - } - } - - public String getProfilePhotoString() { - return this.getContact().getProfilePhoto(); - } - - public String getAccountUuid() { - return this.accountUuid; - } - - public Account getAccount() { - return this.account; - } - - public Contact getContact() { - return this.account.getRoster().getContact(this.contactJid); - } - - public void setAccount(Account account) { - this.account = account; - } - - public String getContactJid() { - return this.contactJid; - } - - public int getStatus() { - return this.status; - } - - public long getCreated() { - return this.created; - } - - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(NAME, name); - values.put(CONTACT, contactUuid); - values.put(ACCOUNT, accountUuid); - values.put(CONTACTJID, contactJid); - values.put(CREATED, created); - values.put(STATUS, status); - values.put(MODE, mode); - values.put(ATTRIBUTES, attributes.toString()); - return values; - } - - public static Conversation fromCursor(Cursor cursor) { - return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(NAME)), - cursor.getString(cursor.getColumnIndex(CONTACT)), - cursor.getString(cursor.getColumnIndex(ACCOUNT)), - cursor.getString(cursor.getColumnIndex(CONTACTJID)), - cursor.getLong(cursor.getColumnIndex(CREATED)), - cursor.getInt(cursor.getColumnIndex(STATUS)), - cursor.getInt(cursor.getColumnIndex(MODE)), - cursor.getString(cursor.getColumnIndex(ATTRIBUTES))); - } - - public void setStatus(int status) { - this.status = status; - } - - public int getMode() { - return this.mode; - } - - public void setMode(int mode) { - this.mode = mode; - } - - public SessionImpl startOtrSession(XmppConnectionService service, - String presence, boolean sendStart) { - if (this.otrSession != null) { - return this.otrSession; - } else { - SessionID sessionId = new SessionID(this.getContactJid().split("/", - 2)[0], presence, "xmpp"); - this.otrSession = new SessionImpl(sessionId, getAccount() - .getOtrEngine(service)); - try { - if (sendStart) { - this.otrSession.startSession(); - return this.otrSession; - } - return this.otrSession; - } catch (OtrException e) { - return null; - } - } - - } - - public SessionImpl getOtrSession() { - return this.otrSession; - } - - public void resetOtrSession() { - this.otrFingerprint = null; - this.otrSession = null; - } - - public void startOtrIfNeeded() { - if (this.otrSession != null - && this.otrSession.getSessionStatus() != SessionStatus.ENCRYPTED) { - try { - this.otrSession.startSession(); - } catch (OtrException e) { - this.resetOtrSession(); - } - } - } - - public boolean endOtrIfNeeded() { - if (this.otrSession != null) { - if (this.otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) { - try { - this.otrSession.endSession(); - this.resetOtrSession(); - return true; - } catch (OtrException e) { - this.resetOtrSession(); - return false; - } - } else { - this.resetOtrSession(); - return false; - } - } else { - return false; - } - } - - public boolean hasValidOtrSession() { - return this.otrSession != null; - } - - public String getOtrFingerprint() { - if (this.otrFingerprint == null) { - try { - if (getOtrSession() == null) { - return ""; - } - DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession() - .getRemotePublicKey(); - StringBuilder builder = new StringBuilder( - new OtrCryptoEngineImpl().getFingerprint(remotePubKey)); - builder.insert(8, " "); - builder.insert(17, " "); - builder.insert(26, " "); - builder.insert(35, " "); - this.otrFingerprint = builder.toString(); - } catch (OtrCryptoException e) { - - } - } - return this.otrFingerprint; - } - - public synchronized MucOptions getMucOptions() { - if (this.mucOptions == null) { - this.mucOptions = new MucOptions(this); - } - return this.mucOptions; - } - - public void resetMucOptions() { - this.mucOptions = null; - } - - public void setContactJid(String jid) { - this.contactJid = jid; - } - - public void setNextPresence(String presence) { - this.nextPresence = presence; - } - - public String getNextPresence() { - return this.nextPresence; - } - - public int getLatestEncryption() { - int latestEncryption = this.getLatestMessage().getEncryption(); - if ((latestEncryption == Message.ENCRYPTION_DECRYPTED) - || (latestEncryption == Message.ENCRYPTION_DECRYPTION_FAILED)) { - return Message.ENCRYPTION_PGP; - } else { - return latestEncryption; - } - } - - public int getNextEncryption(boolean force) { - int next = this.getIntAttribute(ATTRIBUTE_NEXT_ENCRYPTION, -1); - if (next == -1) { - int latest = this.getLatestEncryption(); - if (latest == Message.ENCRYPTION_NONE) { - if (force && getMode() == MODE_SINGLE) { - return Message.ENCRYPTION_OTR; - } else if (getContact().getPresences().size() == 1) { - if (getContact().getOtrFingerprints().size() >= 1) { - return Message.ENCRYPTION_OTR; - } else { - return latest; - } - } else { - return latest; - } - } else { - return latest; - } - } - if (next == Message.ENCRYPTION_NONE && force - && getMode() == MODE_SINGLE) { - return Message.ENCRYPTION_OTR; - } else { - return next; - } - } - - public void setNextEncryption(int encryption) { - this.setAttribute(ATTRIBUTE_NEXT_ENCRYPTION, String.valueOf(encryption)); - } - - public String getNextMessage() { - if (this.nextMessage == null) { - return ""; - } else { - return this.nextMessage; - } - } - - public void setNextMessage(String message) { - this.nextMessage = message; - } - - public void setSymmetricKey(byte[] key) { - this.symmetricKey = key; - } - - public byte[] getSymmetricKey() { - return this.symmetricKey; - } - - public void setBookmark(Bookmark bookmark) { - this.bookmark = bookmark; - this.bookmark.setConversation(this); - } - - public void deregisterWithBookmark() { - if (this.bookmark != null) { - this.bookmark.setConversation(null); - } - } - - public Bookmark getBookmark() { - return this.bookmark; - } - - public boolean hasDuplicateMessage(Message message) { - for (int i = this.getMessages().size() - 1; i >= 0; --i) { - if (this.messages.get(i).equals(message)) { - return true; - } - } - return false; - } - - public void setMutedTill(long value) { - this.setAttribute(ATTRIBUTE_MUTED_TILL, String.valueOf(value)); - } - - public boolean isMuted() { - return SystemClock.elapsedRealtime() < this.getLongAttribute( - ATTRIBUTE_MUTED_TILL, 0); - } - - public boolean setAttribute(String key, String value) { - try { - this.attributes.put(key, value); - return true; - } catch (JSONException e) { - return false; - } - } - - public String getAttribute(String key) { - try { - return this.attributes.getString(key); - } catch (JSONException e) { - return null; - } - } - - public int getIntAttribute(String key, int defaultValue) { - String value = this.getAttribute(key); - if (value == null) { - return defaultValue; - } else { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - } - - public long getLongAttribute(String key, long defaultValue) { - String value = this.getAttribute(key); - if (value == null) { - return defaultValue; - } else { - try { - return Long.parseLong(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - } - - public void add(Message message) { - message.setConversation(this); - synchronized (this.messages) { - this.messages.add(message); - } - } - - public void addAll(int index, List messages) { - synchronized (this.messages) { - this.messages.addAll(index, messages); - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Downloadable.java b/conversations/src/main/java/eu/siacs/conversations/entities/Downloadable.java deleted file mode 100644 index 70516b20..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Downloadable.java +++ /dev/null @@ -1,21 +0,0 @@ -package eu.siacs.conversations.entities; - -public interface Downloadable { - - public final String[] VALID_EXTENSIONS = { "webp", "jpeg", "jpg", "png" }; - public final String[] VALID_CRYPTO_EXTENSIONS = { "pgp", "gpg", "otr" }; - - public static final int STATUS_UNKNOWN = 0x200; - public static final int STATUS_CHECKING = 0x201; - public static final int STATUS_FAILED = 0x202; - public static final int STATUS_OFFER = 0x203; - public static final int STATUS_DOWNLOADING = 0x204; - public static final int STATUS_DELETED = 0x205; - public static final int STATUS_OFFER_CHECK_FILESIZE = 0x206; - - public boolean start(); - - public int getStatus(); - - public long getFileSize(); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java b/conversations/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java deleted file mode 100644 index 1605c75b..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java +++ /dev/null @@ -1,154 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import eu.siacs.conversations.Config; -import android.util.Log; - -public class DownloadableFile extends File { - - private static final long serialVersionUID = 2247012619505115863L; - - private long expectedSize = 0; - private String sha1sum; - private Key aeskey; - - private byte[] iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf }; - - public DownloadableFile(String path) { - super(path); - } - - public long getSize() { - return super.length(); - } - - public long getExpectedSize() { - if (this.aeskey != null) { - if (this.expectedSize == 0) { - return 0; - } else { - return (this.expectedSize / 16 + 1) * 16; - } - } else { - return this.expectedSize; - } - } - - public void setExpectedSize(long size) { - this.expectedSize = size; - } - - public String getSha1Sum() { - return this.sha1sum; - } - - public void setSha1Sum(String sum) { - this.sha1sum = sum; - } - - public void setKey(byte[] key) { - if (key.length == 48) { - byte[] secretKey = new byte[32]; - byte[] iv = new byte[16]; - System.arraycopy(key, 0, iv, 0, 16); - System.arraycopy(key, 16, secretKey, 0, 32); - this.aeskey = new SecretKeySpec(secretKey, "AES"); - this.iv = iv; - } else if (key.length >= 32) { - byte[] secretKey = new byte[32]; - System.arraycopy(key, 0, secretKey, 0, 32); - this.aeskey = new SecretKeySpec(secretKey, "AES"); - } else if (key.length >= 16) { - byte[] secretKey = new byte[16]; - System.arraycopy(key, 0, secretKey, 0, 16); - this.aeskey = new SecretKeySpec(secretKey, "AES"); - } - } - - public Key getKey() { - return this.aeskey; - } - - public InputStream createInputStream() { - if (this.getKey() == null) { - try { - return new FileInputStream(this); - } catch (FileNotFoundException e) { - return null; - } - } else { - try { - IvParameterSpec ips = new IvParameterSpec(iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.ENCRYPT_MODE, this.getKey(), ips); - Log.d(Config.LOGTAG, "opening encrypted input stream"); - return new CipherInputStream(new FileInputStream(this), cipher); - } catch (NoSuchAlgorithmException e) { - Log.d(Config.LOGTAG, "no such algo: " + e.getMessage()); - return null; - } catch (NoSuchPaddingException e) { - Log.d(Config.LOGTAG, "no such padding: " + e.getMessage()); - return null; - } catch (InvalidKeyException e) { - Log.d(Config.LOGTAG, "invalid key: " + e.getMessage()); - return null; - } catch (InvalidAlgorithmParameterException e) { - Log.d(Config.LOGTAG, "invavid iv:" + e.getMessage()); - return null; - } catch (FileNotFoundException e) { - return null; - } - } - } - - public OutputStream createOutputStream() { - if (this.getKey() == null) { - try { - return new FileOutputStream(this); - } catch (FileNotFoundException e) { - return null; - } - } else { - try { - IvParameterSpec ips = new IvParameterSpec(this.iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.DECRYPT_MODE, this.getKey(), ips); - Log.d(Config.LOGTAG, "opening encrypted output stream"); - return new CipherOutputStream(new FileOutputStream(this), - cipher); - } catch (NoSuchAlgorithmException e) { - Log.d(Config.LOGTAG, "no such algo: " + e.getMessage()); - return null; - } catch (NoSuchPaddingException e) { - Log.d(Config.LOGTAG, "no such padding: " + e.getMessage()); - return null; - } catch (InvalidKeyException e) { - Log.d(Config.LOGTAG, "invalid key: " + e.getMessage()); - return null; - } catch (InvalidAlgorithmParameterException e) { - Log.d(Config.LOGTAG, "invavid iv:" + e.getMessage()); - return null; - } catch (FileNotFoundException e) { - return null; - } - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/ListItem.java b/conversations/src/main/java/eu/siacs/conversations/entities/ListItem.java deleted file mode 100644 index a1872d2f..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/ListItem.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.siacs.conversations.entities; - -public interface ListItem extends Comparable { - public String getDisplayName(); - - public String getJid(); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Message.java b/conversations/src/main/java/eu/siacs/conversations/entities/Message.java deleted file mode 100644 index a390c7ca..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Message.java +++ /dev/null @@ -1,478 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; - -public class Message extends AbstractEntity { - - public static final String TABLENAME = "messages"; - - public static final int STATUS_RECEIVED = 0; - public static final int STATUS_UNSEND = 1; - public static final int STATUS_SEND = 2; - public static final int STATUS_SEND_FAILED = 3; - public static final int STATUS_SEND_REJECTED = 4; - public static final int STATUS_WAITING = 5; - public static final int STATUS_OFFERED = 6; - public static final int STATUS_SEND_RECEIVED = 7; - public static final int STATUS_SEND_DISPLAYED = 8; - - public static final int ENCRYPTION_NONE = 0; - public static final int ENCRYPTION_PGP = 1; - public static final int ENCRYPTION_OTR = 2; - public static final int ENCRYPTION_DECRYPTED = 3; - public static final int ENCRYPTION_DECRYPTION_FAILED = 4; - - public static final int TYPE_TEXT = 0; - public static final int TYPE_IMAGE = 1; - public static final int TYPE_AUDIO = 2; - public static final int TYPE_STATUS = 3; - public static final int TYPE_PRIVATE = 4; - - public static String CONVERSATION = "conversationUuid"; - public static String COUNTERPART = "counterpart"; - public static String TRUE_COUNTERPART = "trueCounterpart"; - public static String BODY = "body"; - public static String TIME_SENT = "timeSent"; - public static String ENCRYPTION = "encryption"; - public static String STATUS = "status"; - public static String TYPE = "type"; - public static String REMOTE_MSG_ID = "remoteMsgId"; - - protected String conversationUuid; - protected String counterpart; - protected String trueCounterpart; - protected String body; - protected String encryptedBody; - protected long timeSent; - protected int encryption; - protected int status; - protected int type; - protected boolean read = true; - protected String remoteMsgId = null; - - protected Conversation conversation = null; - protected Downloadable downloadable = null; - public boolean markable = false; - - private Message mNextMessage = null; - private Message mPreviousMessage = null; - - private Message() { - - } - - public Message(Conversation conversation, String body, int encryption) { - this(java.util.UUID.randomUUID().toString(), conversation.getUuid(), - conversation.getContactJid(), null, body, System - .currentTimeMillis(), encryption, - Message.STATUS_UNSEND, TYPE_TEXT, null); - this.conversation = conversation; - } - - public Message(Conversation conversation, String counterpart, String body, - int encryption, int status) { - this(java.util.UUID.randomUUID().toString(), conversation.getUuid(), - counterpart, null, body, System.currentTimeMillis(), - encryption, status, TYPE_TEXT, null); - this.conversation = conversation; - } - - public Message(String uuid, String conversationUUid, String counterpart, - String trueCounterpart, String body, long timeSent, int encryption, - int status, int type, String remoteMsgId) { - this.uuid = uuid; - this.conversationUuid = conversationUUid; - this.counterpart = counterpart; - this.trueCounterpart = trueCounterpart; - this.body = body; - this.timeSent = timeSent; - this.encryption = encryption; - this.status = status; - this.type = type; - this.remoteMsgId = remoteMsgId; - } - - @Override - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(CONVERSATION, conversationUuid); - values.put(COUNTERPART, counterpart); - values.put(TRUE_COUNTERPART, trueCounterpart); - values.put(BODY, body); - values.put(TIME_SENT, timeSent); - values.put(ENCRYPTION, encryption); - values.put(STATUS, status); - values.put(TYPE, type); - values.put(REMOTE_MSG_ID, remoteMsgId); - return values; - } - - public String getConversationUuid() { - return conversationUuid; - } - - public Conversation getConversation() { - return this.conversation; - } - - public String getCounterpart() { - return counterpart; - } - - public Contact getContact() { - if (this.conversation.getMode() == Conversation.MODE_SINGLE) { - return this.conversation.getContact(); - } else { - if (this.trueCounterpart == null) { - return null; - } else { - return this.conversation.getAccount().getRoster() - .getContactFromRoster(this.trueCounterpart); - } - } - } - - public String getBody() { - return body; - } - - public String getReadableBody(Context context) { - if (encryption == ENCRYPTION_PGP) { - return context.getText(R.string.encrypted_message_received) - .toString(); - } else if (encryption == ENCRYPTION_DECRYPTION_FAILED) { - return context.getText(R.string.decryption_failed).toString(); - } else if (type == TYPE_IMAGE) { - return context.getText(R.string.image_file).toString(); - } else { - return body.trim(); - } - } - - public long getTimeSent() { - return timeSent; - } - - public int getEncryption() { - return encryption; - } - - public int getStatus() { - return status; - } - - public String getRemoteMsgId() { - return this.remoteMsgId; - } - - public void setRemoteMsgId(String id) { - this.remoteMsgId = id; - } - - public static Message fromCursor(Cursor cursor) { - return new Message(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(CONVERSATION)), - cursor.getString(cursor.getColumnIndex(COUNTERPART)), - cursor.getString(cursor.getColumnIndex(TRUE_COUNTERPART)), - cursor.getString(cursor.getColumnIndex(BODY)), - cursor.getLong(cursor.getColumnIndex(TIME_SENT)), - cursor.getInt(cursor.getColumnIndex(ENCRYPTION)), - cursor.getInt(cursor.getColumnIndex(STATUS)), - cursor.getInt(cursor.getColumnIndex(TYPE)), - cursor.getString(cursor.getColumnIndex(REMOTE_MSG_ID))); - } - - public void setConversation(Conversation conv) { - this.conversation = conv; - } - - public void setStatus(int status) { - this.status = status; - } - - public boolean isRead() { - return this.read; - } - - public void markRead() { - this.read = true; - } - - public void markUnread() { - this.read = false; - } - - public void setTime(long time) { - this.timeSent = time; - } - - public void setEncryption(int encryption) { - this.encryption = encryption; - } - - public void setBody(String body) { - this.body = body; - } - - public String getEncryptedBody() { - return this.encryptedBody; - } - - public void setEncryptedBody(String body) { - this.encryptedBody = body; - } - - public void setType(int type) { - this.type = type; - } - - public int getType() { - return this.type; - } - - public void setPresence(String presence) { - if (presence == null) { - this.counterpart = this.counterpart.split("/", 2)[0]; - } else { - this.counterpart = this.counterpart.split("/", 2)[0] + "/" - + presence; - } - } - - public void setTrueCounterpart(String trueCounterpart) { - this.trueCounterpart = trueCounterpart; - } - - public String getPresence() { - String[] counterparts = this.counterpart.split("/", 2); - if (counterparts.length == 2) { - return counterparts[1]; - } else { - if (this.counterpart.contains("/")) { - return ""; - } else { - return null; - } - } - } - - public void setDownloadable(Downloadable downloadable) { - this.downloadable = downloadable; - } - - public Downloadable getDownloadable() { - return this.downloadable; - } - - public static Message createStatusMessage(Conversation conversation) { - Message message = new Message(); - message.setType(Message.TYPE_STATUS); - message.setConversation(conversation); - return message; - } - - public void setCounterpart(String counterpart) { - this.counterpart = counterpart; - } - - public boolean equals(Message message) { - if ((this.remoteMsgId != null) && (this.body != null) - && (this.counterpart != null)) { - return this.remoteMsgId.equals(message.getRemoteMsgId()) - && this.body.equals(message.getBody()) - && this.counterpart.equals(message.getCounterpart()); - } else { - return false; - } - } - - public Message next() { - if (this.mNextMessage == null) { - synchronized (this.conversation.messages) { - int index = this.conversation.messages.indexOf(this); - if (index < 0 - || index >= this.conversation.getMessages().size() - 1) { - this.mNextMessage = null; - } else { - this.mNextMessage = this.conversation.messages - .get(index + 1); - } - } - } - return this.mNextMessage; - } - - public Message prev() { - if (this.mPreviousMessage == null) { - synchronized (this.conversation.messages) { - int index = this.conversation.messages.indexOf(this); - if (index <= 0 || index > this.conversation.messages.size()) { - this.mPreviousMessage = null; - } else { - this.mPreviousMessage = this.conversation.messages - .get(index - 1); - } - } - } - return this.mPreviousMessage; - } - - public boolean mergable(Message message) { - if (message == null) { - return false; - } - return (message.getType() == Message.TYPE_TEXT - && this.getDownloadable() == null - && message.getDownloadable() == null - && message.getEncryption() != Message.ENCRYPTION_PGP - && this.getType() == message.getType() - && this.getEncryption() == message.getEncryption() - && this.getCounterpart().equals(message.getCounterpart()) - && (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && ((this - .getStatus() == message.getStatus() || ((this.getStatus() == Message.STATUS_SEND || this - .getStatus() == Message.STATUS_SEND_RECEIVED) && (message - .getStatus() == Message.STATUS_UNSEND - || message.getStatus() == Message.STATUS_SEND || message - .getStatus() == Message.STATUS_SEND_DISPLAYED))))); - } - - public String getMergedBody() { - Message next = this.next(); - if (this.mergable(next)) { - return body.trim() + '\n' + next.getMergedBody(); - } - return body.trim(); - } - - public int getMergedStatus() { - Message next = this.next(); - if (this.mergable(next)) { - return next.getMergedStatus(); - } else { - return getStatus(); - } - } - - public long getMergedTimeSent() { - Message next = this.next(); - if (this.mergable(next)) { - return next.getMergedTimeSent(); - } else { - return getTimeSent(); - } - } - - public boolean wasMergedIntoPrevious() { - Message prev = this.prev(); - if (prev == null) { - return false; - } else { - return prev.mergable(this); - } - } - - public boolean bodyContainsDownloadable() { - Contact contact = this.getContact(); - if (status <= STATUS_RECEIVED - && (contact == null || !contact.trusted())) { - return false; - } - try { - URL url = new URL(this.getBody()); - if (!url.getProtocol().equalsIgnoreCase("http") - && !url.getProtocol().equalsIgnoreCase("https")) { - return false; - } - if (url.getPath() == null) { - return false; - } - String[] pathParts = url.getPath().split("/"); - String filename = pathParts[pathParts.length - 1]; - String[] extensionParts = filename.split("\\."); - if (extensionParts.length == 2 - && Arrays.asList(Downloadable.VALID_EXTENSIONS).contains( - extensionParts[extensionParts.length - 1])) { - return true; - } else if (extensionParts.length == 3 - && Arrays - .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) - .contains(extensionParts[extensionParts.length - 1]) - && Arrays.asList(Downloadable.VALID_EXTENSIONS).contains( - extensionParts[extensionParts.length - 2])) { - return true; - } else { - return false; - } - } catch (MalformedURLException e) { - return false; - } - } - - public ImageParams getImageParams() { - ImageParams params = new ImageParams(); - if (this.downloadable != null) { - params.size = this.downloadable.getFileSize(); - } - if (body == null) { - return params; - } - String parts[] = body.split(","); - if (parts.length == 1) { - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - params.origin = parts[0]; - } - } else if (parts.length == 3) { - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - params.size = 0; - } - try { - params.width = Integer.parseInt(parts[1]); - } catch (NumberFormatException e) { - params.width = 0; - } - try { - params.height = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - params.height = 0; - } - } else if (parts.length == 4) { - params.origin = parts[0]; - try { - params.size = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - params.size = 0; - } - try { - params.width = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - params.width = 0; - } - try { - params.height = Integer.parseInt(parts[3]); - } catch (NumberFormatException e) { - params.height = 0; - } - } - return params; - } - - public class ImageParams { - public long size = 0; - public int width = 0; - public int height = 0; - public String origin; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/conversations/src/main/java/eu/siacs/conversations/entities/MucOptions.java deleted file mode 100644 index d7407cd5..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ /dev/null @@ -1,369 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.stanzas.PresencePacket; -import android.annotation.SuppressLint; - -@SuppressLint("DefaultLocale") -public class MucOptions { - public static final int ERROR_NO_ERROR = 0; - public static final int ERROR_NICK_IN_USE = 1; - public static final int ERROR_ROOM_NOT_FOUND = 2; - public static final int ERROR_PASSWORD_REQUIRED = 3; - public static final int ERROR_BANNED = 4; - public static final int ERROR_MEMBERS_ONLY = 5; - - public static final int KICKED_FROM_ROOM = 9; - - public static final String STATUS_CODE_BANNED = "301"; - public static final String STATUS_CODE_KICKED = "307"; - - public interface OnRenameListener { - public void onRename(boolean success); - } - - public class User { - public static final int ROLE_MODERATOR = 3; - public static final int ROLE_NONE = 0; - public static final int ROLE_PARTICIPANT = 2; - public static final int ROLE_VISITOR = 1; - public static final int AFFILIATION_ADMIN = 4; - public static final int AFFILIATION_OWNER = 3; - public static final int AFFILIATION_MEMBER = 2; - public static final int AFFILIATION_OUTCAST = 1; - public static final int AFFILIATION_NONE = 0; - - private int role; - private int affiliation; - private String name; - private String jid; - private long pgpKeyId = 0; - - public String getName() { - return name; - } - - public void setName(String user) { - this.name = user; - } - - public void setJid(String jid) { - this.jid = jid; - } - - public String getJid() { - return this.jid; - } - - public int getRole() { - return this.role; - } - - public void setRole(String role) { - role = role.toLowerCase(); - if (role.equals("moderator")) { - this.role = ROLE_MODERATOR; - } else if (role.equals("participant")) { - this.role = ROLE_PARTICIPANT; - } else if (role.equals("visitor")) { - this.role = ROLE_VISITOR; - } else { - this.role = ROLE_NONE; - } - } - - public int getAffiliation() { - return this.affiliation; - } - - public void setAffiliation(String affiliation) { - if (affiliation.equalsIgnoreCase("admin")) { - this.affiliation = AFFILIATION_ADMIN; - } else if (affiliation.equalsIgnoreCase("owner")) { - this.affiliation = AFFILIATION_OWNER; - } else if (affiliation.equalsIgnoreCase("member")) { - this.affiliation = AFFILIATION_MEMBER; - } else if (affiliation.equalsIgnoreCase("outcast")) { - this.affiliation = AFFILIATION_OUTCAST; - } else { - this.affiliation = AFFILIATION_NONE; - } - } - - public void setPgpKeyId(long id) { - this.pgpKeyId = id; - } - - public long getPgpKeyId() { - return this.pgpKeyId; - } - - public Contact getContact() { - return account.getRoster().getContactFromRoster(getJid()); - } - } - - private Account account; - private List users = new CopyOnWriteArrayList(); - private Conversation conversation; - private boolean isOnline = false; - private int error = ERROR_ROOM_NOT_FOUND; - private OnRenameListener renameListener = null; - private boolean aboutToRename = false; - private User self = new User(); - private String subject = null; - private String joinnick; - private String password = null; - - public MucOptions(Conversation conversation) { - this.account = conversation.getAccount(); - this.conversation = conversation; - } - - public void deleteUser(String name) { - for (int i = 0; i < users.size(); ++i) { - if (users.get(i).getName().equals(name)) { - users.remove(i); - return; - } - } - } - - public void addUser(User user) { - for (int i = 0; i < users.size(); ++i) { - if (users.get(i).getName().equals(user.getName())) { - users.set(i, user); - return; - } - } - users.add(user); - } - - public void processPacket(PresencePacket packet, PgpEngine pgp) { - String[] fromParts = packet.getFrom().split("/", 2); - if (fromParts.length >= 2) { - String name = fromParts[1]; - String type = packet.getAttribute("type"); - if (type == null) { - User user = new User(); - Element item = packet.findChild("x", - "http://jabber.org/protocol/muc#user") - .findChild("item"); - user.setName(name); - user.setAffiliation(item.getAttribute("affiliation")); - user.setRole(item.getAttribute("role")); - user.setJid(item.getAttribute("jid")); - user.setName(name); - if (name.equals(this.joinnick)) { - this.isOnline = true; - this.error = ERROR_NO_ERROR; - self = user; - if (aboutToRename) { - if (renameListener != null) { - renameListener.onRename(true); - } - aboutToRename = false; - } - } else { - addUser(user); - } - if (pgp != null) { - Element x = packet.findChild("x", "jabber:x:signed"); - if (x != null) { - Element status = packet.findChild("status"); - String msg; - if (status != null) { - msg = status.getContent(); - } else { - msg = ""; - } - user.setPgpKeyId(pgp.fetchKeyId(account, msg, - x.getContent())); - } - } - } else if (type.equals("unavailable") && name.equals(this.joinnick)) { - Element x = packet.findChild("x", - "http://jabber.org/protocol/muc#user"); - if (x != null) { - Element status = x.findChild("status"); - if (status != null) { - String code = status.getAttribute("code"); - if (STATUS_CODE_KICKED.equals(code)) { - this.isOnline = false; - this.error = KICKED_FROM_ROOM; - } else if (STATUS_CODE_BANNED.equals(code)) { - this.isOnline = false; - this.error = ERROR_BANNED; - } - } - } - } else if (type.equals("unavailable")) { - deleteUser(packet.getAttribute("from").split("/", 2)[1]); - } else if (type.equals("error")) { - Element error = packet.findChild("error"); - if (error != null && error.hasChild("conflict")) { - if (aboutToRename) { - if (renameListener != null) { - renameListener.onRename(false); - } - aboutToRename = false; - this.setJoinNick(getActualNick()); - } else { - this.error = ERROR_NICK_IN_USE; - } - } else if (error != null && error.hasChild("not-authorized")) { - this.error = ERROR_PASSWORD_REQUIRED; - } else if (error != null && error.hasChild("forbidden")) { - this.error = ERROR_BANNED; - } else if (error != null - && error.hasChild("registration-required")) { - this.error = ERROR_MEMBERS_ONLY; - } - } - } - } - - public List getUsers() { - return this.users; - } - - public String getProposedNick() { - String[] mucParts = conversation.getContactJid().split("/", 2); - if (conversation.getBookmark() != null - && conversation.getBookmark().getNick() != null) { - return conversation.getBookmark().getNick(); - } else { - if (mucParts.length == 2) { - return mucParts[1]; - } else { - return account.getUsername(); - } - } - } - - public String getActualNick() { - if (this.self.getName() != null) { - return this.self.getName(); - } else { - return this.getProposedNick(); - } - } - - public void setJoinNick(String nick) { - this.joinnick = nick; - } - - public boolean online() { - return this.isOnline; - } - - public int getError() { - return this.error; - } - - public void setOnRenameListener(OnRenameListener listener) { - this.renameListener = listener; - } - - public OnRenameListener getOnRenameListener() { - return this.renameListener; - } - - public void setOffline() { - this.users.clear(); - this.error = 0; - this.isOnline = false; - } - - public User getSelf() { - return self; - } - - public void setSubject(String content) { - this.subject = content; - } - - public String getSubject() { - return this.subject; - } - - public void flagAboutToRename() { - this.aboutToRename = true; - } - - public long[] getPgpKeyIds() { - List ids = new ArrayList(); - for (User user : getUsers()) { - if (user.getPgpKeyId() != 0) { - ids.add(user.getPgpKeyId()); - } - } - long[] primitivLongArray = new long[ids.size()]; - for (int i = 0; i < ids.size(); ++i) { - primitivLongArray[i] = ids.get(i); - } - return primitivLongArray; - } - - public boolean pgpKeysInUse() { - for (User user : getUsers()) { - if (user.getPgpKeyId() != 0) { - return true; - } - } - return false; - } - - public boolean everybodyHasKeys() { - for (User user : getUsers()) { - if (user.getPgpKeyId() == 0) { - return false; - } - } - return true; - } - - public String getJoinJid() { - return this.conversation.getContactJid().split("/", 2)[0] + "/" - + this.joinnick; - } - - public String getTrueCounterpart(String counterpart) { - for (User user : this.getUsers()) { - if (user.getName().equals(counterpart)) { - return user.getJid(); - } - } - return null; - } - - public String getPassword() { - this.password = conversation - .getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); - if (this.password == null && conversation.getBookmark() != null - && conversation.getBookmark().getPassword() != null) { - return conversation.getBookmark().getPassword(); - } else { - return this.password; - } - } - - public void setPassword(String password) { - if (conversation.getBookmark() != null) { - conversation.getBookmark().setPassword(password); - } else { - this.password = password; - } - conversation - .setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); - } - - public Conversation getConversation() { - return this.conversation; - } -} \ No newline at end of file diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Presences.java b/conversations/src/main/java/eu/siacs/conversations/entities/Presences.java deleted file mode 100644 index b5899847..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Presences.java +++ /dev/null @@ -1,76 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map.Entry; - -import eu.siacs.conversations.xml.Element; - -public class Presences { - - public static final int CHAT = -1; - public static final int ONLINE = 0; - public static final int AWAY = 1; - public static final int XA = 2; - public static final int DND = 3; - public static final int OFFLINE = 4; - - private Hashtable presences = new Hashtable(); - - public Hashtable getPresences() { - return this.presences; - } - - public void updatePresence(String resource, int status) { - this.presences.put(resource, status); - } - - public void removePresence(String resource) { - this.presences.remove(resource); - } - - public void clearPresences() { - this.presences.clear(); - } - - public int getMostAvailableStatus() { - int status = OFFLINE; - Iterator> it = presences.entrySet().iterator(); - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getValue() < status) - status = entry.getValue(); - } - return status; - } - - public static int parseShow(Element show) { - if ((show == null) || (show.getContent() == null)) { - return Presences.ONLINE; - } else if (show.getContent().equals("away")) { - return Presences.AWAY; - } else if (show.getContent().equals("xa")) { - return Presences.XA; - } else if (show.getContent().equals("chat")) { - return Presences.CHAT; - } else if (show.getContent().equals("dnd")) { - return Presences.DND; - } else { - return Presences.OFFLINE; - } - } - - public int size() { - return presences.size(); - } - - public String[] asStringArray() { - final String[] presencesArray = new String[presences.size()]; - presences.keySet().toArray(presencesArray); - return presencesArray; - } - - public boolean has(String presence) { - return presences.containsKey(presence); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/entities/Roster.java b/conversations/src/main/java/eu/siacs/conversations/entities/Roster.java deleted file mode 100644 index 3267b15a..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/entities/Roster.java +++ /dev/null @@ -1,83 +0,0 @@ -package eu.siacs.conversations.entities; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.ConcurrentHashMap; - -public class Roster { - Account account; - ConcurrentHashMap contacts = new ConcurrentHashMap(); - private String version = null; - - public Roster(Account account) { - this.account = account; - } - - public Contact getContactFromRoster(String jid) { - if (jid == null) { - return null; - } - String cleanJid = jid.split("/", 2)[0]; - Contact contact = contacts.get(cleanJid); - if (contact != null && contact.showInRoster()) { - return contact; - } else { - return null; - } - } - - public Contact getContact(String jid) { - String cleanJid = jid.split("/", 2)[0].toLowerCase(Locale.getDefault()); - if (contacts.containsKey(cleanJid)) { - return contacts.get(cleanJid); - } else { - Contact contact = new Contact(cleanJid); - contact.setAccount(account); - contacts.put(cleanJid, contact); - return contact; - } - } - - public void clearPresences() { - for (Contact contact : getContacts()) { - contact.clearPresences(); - } - } - - public void markAllAsNotInRoster() { - for (Contact contact : getContacts()) { - contact.resetOption(Contact.Options.IN_ROSTER); - } - } - - public void clearSystemAccounts() { - for (Contact contact : getContacts()) { - contact.setPhotoUri(null); - contact.setSystemName(null); - contact.setSystemAccount(null); - } - } - - public List getContacts() { - return new ArrayList(this.contacts.values()); - } - - public void initContact(Contact contact) { - contact.setAccount(account); - contact.setOption(Contact.Options.IN_ROSTER); - contacts.put(contact.getJid(), contact); - } - - public void setVersion(String version) { - this.version = version; - } - - public String getVersion() { - return this.version; - } - - public Account getAccount() { - return this.account; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/conversations/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java deleted file mode 100644 index c96d116d..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ /dev/null @@ -1,48 +0,0 @@ -package eu.siacs.conversations.generator; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import eu.siacs.conversations.services.XmppConnectionService; - -import android.util.Base64; - -public abstract class AbstractGenerator { - public final String[] FEATURES = { "urn:xmpp:jingle:1", - "urn:xmpp:jingle:apps:file-transfer:3", - "urn:xmpp:jingle:transports:s5b:1", - "urn:xmpp:jingle:transports:ibb:1", "urn:xmpp:receipts", - "urn:xmpp:chat-markers:0", "http://jabber.org/protocol/muc", - "jabber:x:conference", "http://jabber.org/protocol/caps", - "http://jabber.org/protocol/disco#info", - "urn:xmpp:avatar:metadata+notify" }; - public final String IDENTITY_NAME = "Conversations 0.7"; - public final String IDENTITY_TYPE = "phone"; - - protected XmppConnectionService mXmppConnectionService; - - protected AbstractGenerator(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - public String getCapHash() { - StringBuilder s = new StringBuilder(); - s.append("client/" + IDENTITY_TYPE + "//" + IDENTITY_NAME + "<"); - MessageDigest md = null; - try { - md = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException e) { - return null; - } - List features = Arrays.asList(FEATURES); - Collections.sort(features); - for (String feature : features) { - s.append(feature + "<"); - } - byte[] sha1 = md.digest(s.toString().getBytes()); - return new String(Base64.encode(sha1, Base64.DEFAULT)).trim(); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/conversations/src/main/java/eu/siacs/conversations/generator/IqGenerator.java deleted file mode 100644 index d44bf0ca..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ /dev/null @@ -1,96 +0,0 @@ -package eu.siacs.conversations.generator; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.pep.Avatar; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public class IqGenerator extends AbstractGenerator { - - public IqGenerator(XmppConnectionService service) { - super(service); - } - - public IqPacket discoResponse(IqPacket request) { - IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT); - packet.setId(request.getId()); - packet.setTo(request.getFrom()); - Element query = packet.addChild("query", - "http://jabber.org/protocol/disco#info"); - query.setAttribute("node", request.query().getAttribute("node")); - Element identity = query.addChild("identity"); - identity.setAttribute("category", "client"); - identity.setAttribute("type", this.IDENTITY_TYPE); - identity.setAttribute("name", IDENTITY_NAME); - List features = Arrays.asList(FEATURES); - Collections.sort(features); - for (String feature : features) { - query.addChild("feature").setAttribute("var", feature); - } - return packet; - } - - protected IqPacket publish(String node, Element item) { - IqPacket packet = new IqPacket(IqPacket.TYPE_SET); - Element pubsub = packet.addChild("pubsub", - "http://jabber.org/protocol/pubsub"); - Element publish = pubsub.addChild("publish"); - publish.setAttribute("node", node); - publish.addChild(item); - return packet; - } - - protected IqPacket retrieve(String node, Element item) { - IqPacket packet = new IqPacket(IqPacket.TYPE_GET); - Element pubsub = packet.addChild("pubsub", - "http://jabber.org/protocol/pubsub"); - Element items = pubsub.addChild("items"); - items.setAttribute("node", node); - if (item != null) { - items.addChild(item); - } - return packet; - } - - public IqPacket publishAvatar(Avatar avatar) { - Element item = new Element("item"); - item.setAttribute("id", avatar.sha1sum); - Element data = item.addChild("data", "urn:xmpp:avatar:data"); - data.setContent(avatar.image); - return publish("urn:xmpp:avatar:data", item); - } - - public IqPacket publishAvatarMetadata(Avatar avatar) { - Element item = new Element("item"); - item.setAttribute("id", avatar.sha1sum); - Element metadata = item - .addChild("metadata", "urn:xmpp:avatar:metadata"); - Element info = metadata.addChild("info"); - info.setAttribute("bytes", avatar.size); - info.setAttribute("id", avatar.sha1sum); - info.setAttribute("height", avatar.height); - info.setAttribute("width", avatar.height); - info.setAttribute("type", avatar.type); - return publish("urn:xmpp:avatar:metadata", item); - } - - public IqPacket retrieveAvatar(Avatar avatar) { - Element item = new Element("item"); - item.setAttribute("id", avatar.sha1sum); - IqPacket packet = retrieve("urn:xmpp:avatar:data", item); - packet.setTo(avatar.owner); - return packet; - } - - public IqPacket retrieveAvatarMetaData(String to) { - IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null); - if (to != null) { - packet.setTo(to); - } - return packet; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/conversations/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java deleted file mode 100644 index dd833e56..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ /dev/null @@ -1,178 +0,0 @@ -package eu.siacs.conversations.generator; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -import net.java.otr4j.OtrException; -import net.java.otr4j.session.Session; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; - -public class MessageGenerator extends AbstractGenerator { - public MessageGenerator(XmppConnectionService service) { - super(service); - } - - private MessagePacket preparePacket(Message message, boolean addDelay) { - Conversation conversation = message.getConversation(); - Account account = conversation.getAccount(); - MessagePacket packet = new MessagePacket(); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - packet.setTo(message.getCounterpart()); - packet.setType(MessagePacket.TYPE_CHAT); - packet.addChild("markable", "urn:xmpp:chat-markers:0"); - if (this.mXmppConnectionService.indicateReceived()) { - packet.addChild("request", "urn:xmpp:receipts"); - } - } else if (message.getType() == Message.TYPE_PRIVATE) { - packet.setTo(message.getCounterpart()); - packet.setType(MessagePacket.TYPE_CHAT); - } else { - packet.setTo(message.getCounterpart().split("/", 2)[0]); - packet.setType(MessagePacket.TYPE_GROUPCHAT); - } - packet.setFrom(account.getFullJid()); - packet.setId(message.getUuid()); - if (addDelay) { - addDelay(packet, message.getTimeSent()); - } - return packet; - } - - private void addDelay(MessagePacket packet, long timestamp) { - final SimpleDateFormat mDateFormat = new SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); - mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - Element delay = packet.addChild("delay", "urn:xmpp:delay"); - Date date = new Date(timestamp); - delay.setAttribute("stamp", mDateFormat.format(date)); - } - - public MessagePacket generateOtrChat(Message message) { - return generateOtrChat(message, false); - } - - public MessagePacket generateOtrChat(Message message, boolean addDelay) { - Session otrSession = message.getConversation().getOtrSession(); - if (otrSession == null) { - return null; - } - MessagePacket packet = preparePacket(message, addDelay); - packet.addChild("private", "urn:xmpp:carbons:2"); - packet.addChild("no-copy", "urn:xmpp:hints"); - try { - packet.setBody(otrSession.transformSending(message.getBody())); - return packet; - } catch (OtrException e) { - return null; - } - } - - public MessagePacket generateChat(Message message) { - return generateChat(message, false); - } - - public MessagePacket generateChat(Message message, boolean addDelay) { - MessagePacket packet = preparePacket(message, addDelay); - packet.setBody(message.getBody()); - return packet; - } - - public MessagePacket generatePgpChat(Message message) { - return generatePgpChat(message, false); - } - - public MessagePacket generatePgpChat(Message message, boolean addDelay) { - MessagePacket packet = preparePacket(message, addDelay); - packet.setBody("This is an XEP-0027 encryted message"); - if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - packet.addChild("x", "jabber:x:encrypted").setContent( - message.getEncryptedBody()); - } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - packet.addChild("x", "jabber:x:encrypted").setContent( - message.getBody()); - } - return packet; - } - - public MessagePacket generateNotAcceptable(MessagePacket origin) { - MessagePacket packet = generateError(origin); - Element error = packet.addChild("error"); - error.setAttribute("type", "modify"); - error.setAttribute("code", "406"); - error.addChild("not-acceptable"); - return packet; - } - - private MessagePacket generateError(MessagePacket origin) { - MessagePacket packet = new MessagePacket(); - packet.setId(origin.getId()); - packet.setTo(origin.getFrom()); - packet.setBody(origin.getBody()); - packet.setType(MessagePacket.TYPE_ERROR); - return packet; - } - - public MessagePacket confirm(Account account, String to, String id) { - MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_NORMAL); - packet.setTo(to); - packet.setFrom(account.getFullJid()); - Element received = packet.addChild("displayed", - "urn:xmpp:chat-markers:0"); - received.setAttribute("id", id); - return packet; - } - - public MessagePacket conferenceSubject(Conversation conversation, - String subject) { - MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_GROUPCHAT); - packet.setTo(conversation.getContactJid().split("/", 2)[0]); - Element subjectChild = new Element("subject"); - subjectChild.setContent(subject); - packet.addChild(subjectChild); - packet.setFrom(conversation.getAccount().getJid()); - return packet; - } - - public MessagePacket directInvite(Conversation conversation, String contact) { - MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_NORMAL); - packet.setTo(contact); - packet.setFrom(conversation.getAccount().getFullJid()); - Element x = packet.addChild("x", "jabber:x:conference"); - x.setAttribute("jid", conversation.getContactJid().split("/", 2)[0]); - return packet; - } - - public MessagePacket invite(Conversation conversation, String contact) { - MessagePacket packet = new MessagePacket(); - packet.setTo(conversation.getContactJid().split("/", 2)[0]); - packet.setFrom(conversation.getAccount().getFullJid()); - Element x = new Element("x"); - x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user"); - Element invite = new Element("invite"); - invite.setAttribute("to", contact); - x.addChild(invite); - packet.addChild(x); - return packet; - } - - public MessagePacket received(Account account, - MessagePacket originalMessage, String namespace) { - MessagePacket receivedPacket = new MessagePacket(); - receivedPacket.setType(MessagePacket.TYPE_NORMAL); - receivedPacket.setTo(originalMessage.getFrom()); - receivedPacket.setFrom(account.getFullJid()); - Element received = receivedPacket.addChild("received", namespace); - received.setAttribute("id", originalMessage.getId()); - return receivedPacket; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/conversations/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java deleted file mode 100644 index d896dd00..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java +++ /dev/null @@ -1,57 +0,0 @@ -package eu.siacs.conversations.generator; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.stanzas.PresencePacket; - -public class PresenceGenerator extends AbstractGenerator { - - public PresenceGenerator(XmppConnectionService service) { - super(service); - } - - private PresencePacket subscription(String type, Contact contact) { - PresencePacket packet = new PresencePacket(); - packet.setAttribute("type", type); - packet.setAttribute("to", contact.getJid()); - packet.setAttribute("from", contact.getAccount().getJid()); - return packet; - } - - public PresencePacket requestPresenceUpdatesFrom(Contact contact) { - return subscription("subscribe", contact); - } - - public PresencePacket stopPresenceUpdatesFrom(Contact contact) { - return subscription("unsubscribe", contact); - } - - public PresencePacket stopPresenceUpdatesTo(Contact contact) { - return subscription("unsubscribed", contact); - } - - public PresencePacket sendPresenceUpdatesTo(Contact contact) { - return subscription("subscribed", contact); - } - - public PresencePacket sendPresence(Account account) { - PresencePacket packet = new PresencePacket(); - packet.setAttribute("from", account.getFullJid()); - String sig = account.getPgpSignature(); - if (sig != null) { - packet.addChild("status").setContent("online"); - packet.addChild("x", "jabber:x:signed").setContent(sig); - } - String capHash = getCapHash(); - if (capHash != null) { - Element cap = packet.addChild("c", - "http://jabber.org/protocol/caps"); - cap.setAttribute("hash", "sha-1"); - cap.setAttribute("node", "http://conversions.siacs.eu"); - cap.setAttribute("ver", capHash); - } - return packet; - } -} \ No newline at end of file diff --git a/conversations/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/conversations/src/main/java/eu/siacs/conversations/http/HttpConnection.java deleted file mode 100644 index 407a13d9..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ /dev/null @@ -1,255 +0,0 @@ -package eu.siacs.conversations.http; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.X509TrustManager; - -import org.apache.http.conn.ssl.StrictHostnameVerifier; - -import android.content.Intent; -import android.graphics.BitmapFactory; -import android.net.Uri; -import android.util.Log; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; - -public class HttpConnection implements Downloadable { - - private HttpConnectionManager mHttpConnectionManager; - private XmppConnectionService mXmppConnectionService; - - private URL mUrl; - private Message message; - private DownloadableFile file; - private int mStatus = Downloadable.STATUS_UNKNOWN; - - public HttpConnection(HttpConnectionManager manager) { - this.mHttpConnectionManager = manager; - this.mXmppConnectionService = manager.getXmppConnectionService(); - } - - @Override - public boolean start() { - if (mXmppConnectionService.hasInternetConnection()) { - if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) { - checkFileSize(true); - } else { - new Thread(new FileDownloader(true)).start(); - } - return true; - } else { - return false; - } - } - - public void init(Message message) { - this.message = message; - this.message.setDownloadable(this); - try { - mUrl = new URL(message.getBody()); - this.file = mXmppConnectionService.getFileBackend().getFile( - message, false); - String reference = mUrl.getRef(); - if (reference != null && reference.length() == 96) { - this.file.setKey(CryptoHelper.hexToBytes(reference)); - } - if (this.message.getEncryption() == Message.ENCRYPTION_OTR - && this.file.getKey() == null) { - this.message.setEncryption(Message.ENCRYPTION_NONE); - } - checkFileSize(false); - } catch (MalformedURLException e) { - this.cancel(); - } - } - - private void checkFileSize(boolean interactive) { - new Thread(new FileSizeChecker(interactive)).start(); - } - - public void cancel() { - mHttpConnectionManager.finishConnection(this); - message.setDownloadable(null); - mXmppConnectionService.updateConversationUi(); - } - - private void finish() { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(Uri.fromFile(file)); - mXmppConnectionService.sendBroadcast(intent); - message.setDownloadable(null); - mHttpConnectionManager.finishConnection(this); - } - - private void changeStatus(int status) { - this.mStatus = status; - mXmppConnectionService.updateConversationUi(); - } - - private void setupTrustManager(HttpsURLConnection connection, - boolean interactive) { - X509TrustManager trustManager; - HostnameVerifier hostnameVerifier; - if (interactive) { - trustManager = mXmppConnectionService.getMemorizingTrustManager(); - hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager().wrapHostnameVerifier( - new StrictHostnameVerifier()); - } else { - trustManager = mXmppConnectionService.getMemorizingTrustManager() - .getNonInteractive(); - hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager() - .wrapHostnameVerifierNonInteractive( - new StrictHostnameVerifier()); - } - try { - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, new X509TrustManager[] { trustManager }, - mXmppConnectionService.getRNG()); - connection.setSSLSocketFactory(sc.getSocketFactory()); - connection.setHostnameVerifier(hostnameVerifier); - } catch (KeyManagementException e) { - return; - } catch (NoSuchAlgorithmException e) { - return; - } - } - - private class FileSizeChecker implements Runnable { - - private boolean interactive = false; - - public FileSizeChecker(boolean interactive) { - this.interactive = interactive; - } - - @Override - public void run() { - long size; - try { - size = retrieveFileSize(); - } catch (SSLHandshakeException e) { - changeStatus(STATUS_OFFER_CHECK_FILESIZE); - return; - } catch (IOException e) { - cancel(); - return; - } - file.setExpectedSize(size); - if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) { - new Thread(new FileDownloader(interactive)).start(); - } else { - changeStatus(STATUS_OFFER); - } - } - - private long retrieveFileSize() throws IOException, - SSLHandshakeException { - changeStatus(STATUS_CHECKING); - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); - connection.setRequestMethod("HEAD"); - if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - if (contentLength == null) { - throw new IOException(); - } - try { - return Long.parseLong(contentLength, 10); - } catch (NumberFormatException e) { - throw new IOException(); - } - } - - } - - private class FileDownloader implements Runnable { - - private boolean interactive = false; - - public FileDownloader(boolean interactive) { - this.interactive = interactive; - } - - @Override - public void run() { - try { - changeStatus(STATUS_DOWNLOADING); - download(); - updateImageBounds(); - finish(); - } catch (SSLHandshakeException e) { - changeStatus(STATUS_OFFER); - } catch (IOException e) { - cancel(); - } - } - - private void download() throws SSLHandshakeException, IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); - if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - BufferedInputStream is = new BufferedInputStream( - connection.getInputStream()); - OutputStream os = file.createOutputStream(); - int count = -1; - byte[] buffer = new byte[1024]; - while ((count = is.read(buffer)) != -1) { - os.write(buffer, 0, count); - } - os.flush(); - os.close(); - is.close(); - } - - private void updateImageBounds() { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(file.getAbsolutePath(), options); - int imageHeight = options.outHeight; - int imageWidth = options.outWidth; - message.setBody(mUrl.toString() + "," + file.getSize() + ',' - + imageWidth + ',' + imageHeight); - message.setType(Message.TYPE_IMAGE); - mXmppConnectionService.updateMessage(message); - } - - } - - @Override - public int getStatus() { - return this.mStatus; - } - - @Override - public long getFileSize() { - if (this.file != null) { - return this.file.getExpectedSize(); - } else { - return 0; - } - } -} \ No newline at end of file diff --git a/conversations/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/conversations/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java deleted file mode 100644 index 9a2a2405..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ /dev/null @@ -1,28 +0,0 @@ -package eu.siacs.conversations.http; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.AbstractConnectionManager; -import eu.siacs.conversations.services.XmppConnectionService; - -public class HttpConnectionManager extends AbstractConnectionManager { - - public HttpConnectionManager(XmppConnectionService service) { - super(service); - } - - private List connections = new CopyOnWriteArrayList(); - - public HttpConnection createNewConnection(Message message) { - HttpConnection connection = new HttpConnection(this); - connection.init(message); - this.connections.add(connection); - return connection; - } - - public void finishConnection(HttpConnection connection) { - this.connections.remove(connection); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/conversations/src/main/java/eu/siacs/conversations/parser/AbstractParser.java deleted file mode 100644 index 5541c1c6..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ /dev/null @@ -1,92 +0,0 @@ -package eu.siacs.conversations.parser; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.Locale; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; - -public abstract class AbstractParser { - - protected XmppConnectionService mXmppConnectionService; - - protected AbstractParser(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - protected long getTimestamp(Element packet) { - long now = System.currentTimeMillis(); - ArrayList stamps = new ArrayList(); - for (Element child : packet.getChildren()) { - if (child.getName().equals("delay")) { - stamps.add(child.getAttribute("stamp").replace("Z", "+0000")); - } - } - Collections.sort(stamps); - if (stamps.size() >= 1) { - try { - String stamp = stamps.get(stamps.size() - 1); - if (stamp.contains(".")) { - Date date = new SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US) - .parse(stamp); - if (now < date.getTime()) { - return now; - } else { - return date.getTime(); - } - } else { - Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", - Locale.US).parse(stamp); - if (now < date.getTime()) { - return now; - } else { - return date.getTime(); - } - } - } catch (ParseException e) { - return now; - } - } else { - return now; - } - } - - protected void updateLastseen(Element packet, Account account, - boolean presenceOverwrite) { - String[] fromParts = packet.getAttribute("from").split("/", 2); - String from = fromParts[0]; - String presence = null; - if (fromParts.length >= 2) { - presence = fromParts[1]; - } else { - presence = ""; - } - Contact contact = account.getRoster().getContact(from); - long timestamp = getTimestamp(packet); - if (timestamp >= contact.lastseen.time) { - contact.lastseen.time = timestamp; - if ((presence != null) && (presenceOverwrite)) { - contact.lastseen.presence = presence; - } - } - } - - protected String avatarData(Element items) { - Element item = items.findChild("item"); - if (item == null) { - return null; - } - Element data = item.findChild("data", "urn:xmpp:avatar:data"); - if (data == null) { - return null; - } - return data.getContent(); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/parser/IqParser.java b/conversations/src/main/java/eu/siacs/conversations/parser/IqParser.java deleted file mode 100644 index df6754f2..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ /dev/null @@ -1,92 +0,0 @@ -package eu.siacs.conversations.parser; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public class IqParser extends AbstractParser implements OnIqPacketReceived { - - public IqParser(XmppConnectionService service) { - super(service); - } - - public void rosterItems(Account account, Element query) { - String version = query.getAttribute("ver"); - if (version != null) { - account.getRoster().setVersion(version); - } - for (Element item : query.getChildren()) { - if (item.getName().equals("item")) { - String jid = item.getAttribute("jid"); - String name = item.getAttribute("name"); - String subscription = item.getAttribute("subscription"); - Contact contact = account.getRoster().getContact(jid); - if (!contact.getOption(Contact.Options.DIRTY_PUSH)) { - contact.setServerName(name); - } - if (subscription != null) { - if (subscription.equals("remove")) { - contact.resetOption(Contact.Options.IN_ROSTER); - contact.resetOption(Contact.Options.DIRTY_DELETE); - contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); - } else { - contact.setOption(Contact.Options.IN_ROSTER); - contact.resetOption(Contact.Options.DIRTY_PUSH); - contact.parseSubscriptionFromElement(item); - } - } - } - } - mXmppConnectionService.updateRosterUi(); - } - - public String avatarData(IqPacket packet) { - Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); - if (pubsub == null) { - return null; - } - Element items = pubsub.findChild("items"); - if (items == null) { - return null; - } - return super.avatarData(items); - } - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.hasChild("query", "jabber:iq:roster")) { - String from = packet.getFrom(); - if ((from == null) || (from.equals(account.getJid()))) { - Element query = packet.findChild("query"); - this.rosterItems(account, query); - } - } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb") - || packet.hasChild("data", "http://jabber.org/protocol/ibb")) { - mXmppConnectionService.getJingleConnectionManager() - .deliverIbbPacket(account, packet); - } else if (packet.hasChild("query", - "http://jabber.org/protocol/disco#info")) { - IqPacket response = mXmppConnectionService.getIqGenerator() - .discoResponse(packet); - account.getXmppConnection().sendIqPacket(response, null); - } else if (packet.hasChild("ping", "urn:xmpp:ping")) { - IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT); - mXmppConnectionService.sendIqPacket(account, response, null); - } else { - if ((packet.getType() == IqPacket.TYPE_GET) - || (packet.getType() == IqPacket.TYPE_SET)) { - IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR); - Element error = response.addChild("error"); - error.setAttribute("type", "cancel"); - error.addChild("feature-not-implemented", - "urn:ietf:params:xml:ns:xmpp-stanzas"); - account.getXmppConnection().sendIqPacket(response, null); - } - } - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/conversations/src/main/java/eu/siacs/conversations/parser/MessageParser.java deleted file mode 100644 index b5e14305..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ /dev/null @@ -1,517 +0,0 @@ -package eu.siacs.conversations.parser; - -import net.java.otr4j.session.Session; -import net.java.otr4j.session.SessionStatus; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.NotificationService; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnMessagePacketReceived; -import eu.siacs.conversations.xmpp.pep.Avatar; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; - -public class MessageParser extends AbstractParser implements - OnMessagePacketReceived { - public MessageParser(XmppConnectionService service) { - super(service); - } - - private Message parseChat(MessagePacket packet, Account account) { - String[] fromParts = packet.getFrom().split("/", 2); - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, fromParts[0], false); - updateLastseen(packet, account, true); - String pgpBody = getPgpBody(packet); - Message finishedMessage; - if (pgpBody != null) { - finishedMessage = new Message(conversation, packet.getFrom(), - pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECEIVED); - } else { - finishedMessage = new Message(conversation, packet.getFrom(), - packet.getBody(), Message.ENCRYPTION_NONE, - Message.STATUS_RECEIVED); - } - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - if (conversation.getMode() == Conversation.MODE_MULTI - && fromParts.length >= 2) { - finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setPresence(fromParts[1]); - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(fromParts[1])); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - - } - finishedMessage.setTime(getTimestamp(packet)); - return finishedMessage; - } - - private Message parseOtrChat(MessagePacket packet, Account account) { - boolean properlyAddressed = (packet.getTo().split("/", 2).length == 2) - || (account.countPresences() == 1); - String[] fromParts = packet.getFrom().split("/", 2); - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, fromParts[0], false); - String presence; - if (fromParts.length >= 2) { - presence = fromParts[1]; - } else { - presence = ""; - } - updateLastseen(packet, account, true); - String body = packet.getBody(); - if (body.matches("^\\?OTRv\\d*\\?")) { - conversation.endOtrIfNeeded(); - } - if (!conversation.hasValidOtrSession()) { - if (properlyAddressed) { - conversation.startOtrSession(mXmppConnectionService, presence, - false); - } else { - return null; - } - } else { - String foreignPresence = conversation.getOtrSession() - .getSessionID().getUserID(); - if (!foreignPresence.equals(presence)) { - conversation.endOtrIfNeeded(); - if (properlyAddressed) { - conversation.startOtrSession(mXmppConnectionService, - presence, false); - } else { - return null; - } - } - } - try { - Session otrSession = conversation.getOtrSession(); - SessionStatus before = otrSession.getSessionStatus(); - body = otrSession.transformReceiving(body); - SessionStatus after = otrSession.getSessionStatus(); - if ((before != after) && (after == SessionStatus.ENCRYPTED)) { - mXmppConnectionService.onOtrSessionEstablished(conversation); - } else if ((before != after) && (after == SessionStatus.FINISHED)) { - conversation.resetOtrSession(); - mXmppConnectionService.updateConversationUi(); - } - if ((body == null) || (body.isEmpty())) { - return null; - } - if (body.startsWith(CryptoHelper.FILETRANSFER)) { - String key = body.substring(CryptoHelper.FILETRANSFER.length()); - conversation.setSymmetricKey(CryptoHelper.hexToBytes(key)); - return null; - } - Message finishedMessage = new Message(conversation, - packet.getFrom(), body, Message.ENCRYPTION_OTR, - Message.STATUS_RECEIVED); - finishedMessage.setTime(getTimestamp(packet)); - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - return finishedMessage; - } catch (Exception e) { - String receivedId = packet.getId(); - if (receivedId != null) { - mXmppConnectionService.replyWithNotAcceptable(account, packet); - } - conversation.resetOtrSession(); - return null; - } - } - - private Message parseGroupchat(MessagePacket packet, Account account) { - int status; - String[] fromParts = packet.getFrom().split("/", 2); - if (mXmppConnectionService.find(account.pendingConferenceLeaves, - account, fromParts[0]) != null) { - return null; - } - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, fromParts[0], true); - if (packet.hasChild("subject")) { - conversation.getMucOptions().setSubject( - packet.findChild("subject").getContent()); - mXmppConnectionService.updateConversationUi(); - return null; - } - if ((fromParts.length == 1)) { - return null; - } - String counterPart = fromParts[1]; - if (counterPart.equals(conversation.getMucOptions().getActualNick())) { - if (mXmppConnectionService.markMessage(conversation, - packet.getId(), Message.STATUS_SEND)) { - return null; - } else { - status = Message.STATUS_SEND; - } - } else { - status = Message.STATUS_RECEIVED; - } - String pgpBody = getPgpBody(packet); - Message finishedMessage; - if (pgpBody == null) { - finishedMessage = new Message(conversation, counterPart, - packet.getBody(), Message.ENCRYPTION_NONE, status); - } else { - finishedMessage = new Message(conversation, counterPart, pgpBody, - Message.ENCRYPTION_PGP, status); - } - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - if (status == Message.STATUS_RECEIVED) { - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(counterPart)); - } - if (packet.hasChild("delay") - && conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - finishedMessage.setTime(getTimestamp(packet)); - return finishedMessage; - } - - private Message parseCarbonMessage(MessagePacket packet, Account account) { - int status; - String fullJid; - Element forwarded; - if (packet.hasChild("received", "urn:xmpp:carbons:2")) { - forwarded = packet.findChild("received", "urn:xmpp:carbons:2") - .findChild("forwarded", "urn:xmpp:forward:0"); - status = Message.STATUS_RECEIVED; - } else if (packet.hasChild("sent", "urn:xmpp:carbons:2")) { - forwarded = packet.findChild("sent", "urn:xmpp:carbons:2") - .findChild("forwarded", "urn:xmpp:forward:0"); - status = Message.STATUS_SEND; - } else { - return null; - } - if (forwarded == null) { - return null; - } - Element message = forwarded.findChild("message"); - if (message == null) { - return null; - } - if (!message.hasChild("body")) { - if (status == Message.STATUS_RECEIVED - && message.getAttribute("from") != null) { - parseNonMessage(message, account); - } else if (status == Message.STATUS_SEND - && message.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - String to = message.getAttribute("to"); - if (to != null) { - Conversation conversation = mXmppConnectionService.find( - mXmppConnectionService.getConversations(), account, - to.split("/")[0]); - if (conversation != null) { - mXmppConnectionService.markRead(conversation, false); - } - } - } - return null; - } - if (status == Message.STATUS_RECEIVED) { - fullJid = message.getAttribute("from"); - if (fullJid == null) { - return null; - } else { - updateLastseen(message, account, true); - } - } else { - fullJid = message.getAttribute("to"); - if (fullJid == null) { - return null; - } - } - String[] parts = fullJid.split("/", 2); - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, parts[0], false); - String pgpBody = getPgpBody(message); - Message finishedMessage; - if (pgpBody != null) { - finishedMessage = new Message(conversation, fullJid, pgpBody, - Message.ENCRYPTION_PGP, status); - } else { - String body = message.findChild("body").getContent(); - finishedMessage = new Message(conversation, fullJid, body, - Message.ENCRYPTION_NONE, status); - } - finishedMessage.setTime(getTimestamp(message)); - finishedMessage.setRemoteMsgId(message.getAttribute("id")); - finishedMessage.markable = isMarkable(message); - if (conversation.getMode() == Conversation.MODE_MULTI - && parts.length >= 2) { - finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setPresence(parts[1]); - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(parts[1])); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - } - - return finishedMessage; - } - - private void parseError(MessagePacket packet, Account account) { - String[] fromParts = packet.getFrom().split("/", 2); - mXmppConnectionService.markMessage(account, fromParts[0], - packet.getId(), Message.STATUS_SEND_FAILED); - } - - private void parseNonMessage(Element packet, Account account) { - String from = packet.getAttribute("from"); - if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { - Element event = packet.findChild("event", - "http://jabber.org/protocol/pubsub#event"); - parseEvent(event, packet.getAttribute("from"), account); - } else if (from != null - && packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - String id = packet - .findChild("displayed", "urn:xmpp:chat-markers:0") - .getAttribute("id"); - updateLastseen(packet, account, true); - mXmppConnectionService.markMessage(account, from.split("/", 2)[0], - id, Message.STATUS_SEND_DISPLAYED); - } else if (from != null - && packet.hasChild("received", "urn:xmpp:chat-markers:0")) { - String id = packet.findChild("received", "urn:xmpp:chat-markers:0") - .getAttribute("id"); - updateLastseen(packet, account, false); - mXmppConnectionService.markMessage(account, from.split("/", 2)[0], - id, Message.STATUS_SEND_RECEIVED); - } else if (from != null - && packet.hasChild("received", "urn:xmpp:receipts")) { - String id = packet.findChild("received", "urn:xmpp:receipts") - .getAttribute("id"); - updateLastseen(packet, account, false); - mXmppConnectionService.markMessage(account, from.split("/", 2)[0], - id, Message.STATUS_SEND_RECEIVED); - } else if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) { - Element x = packet.findChild("x", - "http://jabber.org/protocol/muc#user"); - if (x.hasChild("invite")) { - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, - packet.getAttribute("from"), true); - if (!conversation.getMucOptions().online()) { - if (x.hasChild("password")) { - Element password = x.findChild("password"); - conversation.getMucOptions().setPassword( - password.getContent()); - mXmppConnectionService.databaseBackend - .updateConversation(conversation); - } - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } - } - } else if (packet.hasChild("x", "jabber:x:conference")) { - Element x = packet.findChild("x", "jabber:x:conference"); - String jid = x.getAttribute("jid"); - String password = x.getAttribute("password"); - if (jid != null) { - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, jid, true); - if (!conversation.getMucOptions().online()) { - if (password != null) { - conversation.getMucOptions().setPassword(password); - mXmppConnectionService.databaseBackend - .updateConversation(conversation); - } - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } - } - } - } - - private void parseEvent(Element event, String from, Account account) { - Element items = event.findChild("items"); - String node = items.getAttribute("node"); - if (node != null) { - if (node.equals("urn:xmpp:avatar:metadata")) { - Avatar avatar = Avatar.parseMetadata(items); - if (avatar != null) { - avatar.owner = from; - if (mXmppConnectionService.getFileBackend().isAvatarCached( - avatar)) { - if (account.getJid().equals(from)) { - if (account.setAvatar(avatar.getFilename())) { - mXmppConnectionService.databaseBackend - .updateAccount(account); - } - mXmppConnectionService.getAvatarService().clear( - account); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateAccountUi(); - } else { - Contact contact = account.getRoster().getContact( - from); - contact.setAvatar(avatar.getFilename()); - mXmppConnectionService.getAvatarService().clear( - contact); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateRosterUi(); - } - } else { - mXmppConnectionService.fetchAvatar(account, avatar); - } - } - } else if (node.equals("http://jabber.org/protocol/nick")) { - Element item = items.findChild("item"); - if (item != null) { - Element nick = item.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - if (from != null) { - Contact contact = account.getRoster().getContact( - from); - contact.setPresenceName(nick.getContent()); - } - } - } - } - } - } - - private String getPgpBody(Element message) { - Element child = message.findChild("x", "jabber:x:encrypted"); - if (child == null) { - return null; - } else { - return child.getContent(); - } - } - - private boolean isMarkable(Element message) { - return message.hasChild("markable", "urn:xmpp:chat-markers:0"); - } - - @Override - public void onMessagePacketReceived(Account account, MessagePacket packet) { - Message message = null; - boolean notify = mXmppConnectionService.getPreferences().getBoolean( - "show_notification", true); - boolean alwaysNotifyInConference = notify - && mXmppConnectionService.getPreferences().getBoolean( - "always_notify_in_conference", false); - - this.parseNick(packet, account); - - if ((packet.getType() == MessagePacket.TYPE_CHAT || packet.getType() == MessagePacket.TYPE_NORMAL)) { - if ((packet.getBody() != null) - && (packet.getBody().startsWith("?OTR"))) { - message = this.parseOtrChat(packet, account); - if (message != null) { - message.markUnread(); - } - } else if (packet.hasChild("body") - && !(packet.hasChild("x", - "http://jabber.org/protocol/muc#user"))) { - message = this.parseChat(packet, account); - if (message != null) { - message.markUnread(); - } - } else if (packet.hasChild("received", "urn:xmpp:carbons:2") - || (packet.hasChild("sent", "urn:xmpp:carbons:2"))) { - message = this.parseCarbonMessage(packet, account); - if (message != null) { - if (message.getStatus() == Message.STATUS_SEND) { - account.activateGracePeriod(); - notify = false; - mXmppConnectionService.markRead( - message.getConversation(), false); - } else { - message.markUnread(); - } - } - } else { - parseNonMessage(packet, account); - } - } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { - message = this.parseGroupchat(packet, account); - if (message != null) { - if (message.getStatus() == Message.STATUS_RECEIVED) { - message.markUnread(); - notify = alwaysNotifyInConference - || NotificationService - .wasHighlightedOrPrivate(message); - } else { - mXmppConnectionService.markRead(message.getConversation(), - false); - account.activateGracePeriod(); - notify = false; - } - } - } else if (packet.getType() == MessagePacket.TYPE_ERROR) { - this.parseError(packet, account); - return; - } else if (packet.getType() == MessagePacket.TYPE_HEADLINE) { - this.parseHeadline(packet, account); - return; - } - if ((message == null) || (message.getBody() == null)) { - return; - } - if ((mXmppConnectionService.confirmMessages()) - && ((packet.getId() != null))) { - if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, - "urn:xmpp:chat-markers:0"); - mXmppConnectionService.sendMessagePacket(account, receipt); - } - if (packet.hasChild("request", "urn:xmpp:receipts")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, - "urn:xmpp:receipts"); - mXmppConnectionService.sendMessagePacket(account, receipt); - } - } - Conversation conversation = message.getConversation(); - conversation.add(message); - if (packet.getType() != MessagePacket.TYPE_ERROR) { - if (message.getEncryption() == Message.ENCRYPTION_NONE - || mXmppConnectionService.saveEncryptedMessages()) { - mXmppConnectionService.databaseBackend.createMessage(message); - } - } - if (message.bodyContainsDownloadable()) { - this.mXmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); - } - notify = notify && !conversation.isMuted(); - if (notify) { - mXmppConnectionService.getNotificationService().push(message); - } - mXmppConnectionService.updateConversationUi(); - } - - private void parseHeadline(MessagePacket packet, Account account) { - if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { - Element event = packet.findChild("event", - "http://jabber.org/protocol/pubsub#event"); - parseEvent(event, packet.getFrom(), account); - } - } - - private void parseNick(MessagePacket packet, Account account) { - Element nick = packet.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - if (packet.getFrom() != null) { - Contact contact = account.getRoster().getContact( - packet.getFrom()); - contact.setPresenceName(nick.getContent()); - } - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/conversations/src/main/java/eu/siacs/conversations/parser/PresenceParser.java deleted file mode 100644 index 4e90cda8..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ /dev/null @@ -1,133 +0,0 @@ -package eu.siacs.conversations.parser; - -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Presences; -import eu.siacs.conversations.generator.PresenceGenerator; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnPresencePacketReceived; -import eu.siacs.conversations.xmpp.stanzas.PresencePacket; - -public class PresenceParser extends AbstractParser implements - OnPresencePacketReceived { - - public PresenceParser(XmppConnectionService service) { - super(service); - } - - public void parseConferencePresence(PresencePacket packet, Account account) { - PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine(); - if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) { - Conversation muc = mXmppConnectionService.find(account, packet - .getAttribute("from").split("/", 2)[0]); - if (muc != null) { - boolean before = muc.getMucOptions().online(); - muc.getMucOptions().processPacket(packet, mPgpEngine); - if (before != muc.getMucOptions().online()) { - mXmppConnectionService.updateConversationUi(); - } - mXmppConnectionService.getAvatarService().clear(muc); - } - } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) { - Conversation muc = mXmppConnectionService.find(account, packet - .getAttribute("from").split("/", 2)[0]); - if (muc != null) { - boolean before = muc.getMucOptions().online(); - muc.getMucOptions().processPacket(packet, mPgpEngine); - if (before != muc.getMucOptions().online()) { - mXmppConnectionService.updateConversationUi(); - } - mXmppConnectionService.getAvatarService().clear(muc); - } - } - } - - public void parseContactPresence(PresencePacket packet, Account account) { - PresenceGenerator mPresenceGenerator = mXmppConnectionService - .getPresenceGenerator(); - if (packet.getFrom() == null) { - return; - } - String[] fromParts = packet.getFrom().split("/", 2); - String type = packet.getAttribute("type"); - if (fromParts[0].equals(account.getJid())) { - if (fromParts.length == 2) { - if (type == null) { - account.updatePresence(fromParts[1], - Presences.parseShow(packet.findChild("show"))); - } else if (type.equals("unavailable")) { - account.removePresence(fromParts[1]); - account.deactivateGracePeriod(); - } - } - } else { - Contact contact = account.getRoster().getContact(packet.getFrom()); - if (type == null) { - String presence; - if (fromParts.length >= 2) { - presence = fromParts[1]; - } else { - presence = ""; - } - int sizeBefore = contact.getPresences().size(); - contact.updatePresence(presence, - Presences.parseShow(packet.findChild("show"))); - PgpEngine pgp = mXmppConnectionService.getPgpEngine(); - if (pgp != null) { - Element x = packet.findChild("x", "jabber:x:signed"); - if (x != null) { - Element status = packet.findChild("status"); - String msg; - if (status != null) { - msg = status.getContent(); - } else { - msg = ""; - } - contact.setPgpKeyId(pgp.fetchKeyId(account, msg, - x.getContent())); - } - } - boolean online = sizeBefore < contact.getPresences().size(); - updateLastseen(packet, account, true); - mXmppConnectionService.onContactStatusChanged - .onContactStatusChanged(contact, online); - } else if (type.equals("unavailable")) { - if (fromParts.length != 2) { - contact.clearPresences(); - } else { - contact.removePresence(fromParts[1]); - } - mXmppConnectionService.onContactStatusChanged - .onContactStatusChanged(contact, false); - } else if (type.equals("subscribe")) { - if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { - mXmppConnectionService.sendPresencePacket(account, - mPresenceGenerator.sendPresenceUpdatesTo(contact)); - } else { - contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); - } - } - Element nick = packet.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - contact.setPresenceName(nick.getContent()); - } - } - mXmppConnectionService.updateRosterUi(); - } - - @Override - public void onPresencePacketReceived(Account account, PresencePacket packet) { - if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) { - this.parseConferencePresence(packet, account); - } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) { - this.parseConferencePresence(packet, account); - } else { - this.parseContactPresence(packet, account); - } - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/conversations/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java deleted file mode 100644 index b49cf4e6..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ /dev/null @@ -1,335 +0,0 @@ -package eu.siacs.conversations.persistance; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.Roster; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteCantOpenDatabaseException; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; - -public class DatabaseBackend extends SQLiteOpenHelper { - - private static DatabaseBackend instance = null; - - private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 8; - - private static String CREATE_CONTATCS_STATEMENT = "create table " - + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " - + Contact.SERVERNAME + " TEXT, " + Contact.SYSTEMNAME + " TEXT," - + Contact.JID + " TEXT," + Contact.KEYS + " TEXT," - + Contact.PHOTOURI + " TEXT," + Contact.OPTIONS + " NUMBER," - + Contact.SYSTEMACCOUNT + " NUMBER, " + Contact.AVATAR + " TEXT, " - + "FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES " - + Account.TABLENAME + "(" + Account.UUID - + ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", " - + Contact.JID + ") ON CONFLICT REPLACE);"; - - private DatabaseBackend(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("PRAGMA foreign_keys=ON;"); - db.execSQL("create table " + Account.TABLENAME + "(" + Account.UUID - + " TEXT PRIMARY KEY," + Account.USERNAME + " TEXT," - + Account.SERVER + " TEXT," + Account.PASSWORD + " TEXT," - + Account.ROSTERVERSION + " TEXT," + Account.OPTIONS - + " NUMBER, " + Account.AVATAR + " TEXT, " + Account.KEYS - + " TEXT)"); - db.execSQL("create table " + Conversation.TABLENAME + " (" - + Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME - + " TEXT, " + Conversation.CONTACT + " TEXT, " - + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACTJID - + " TEXT, " + Conversation.CREATED + " NUMBER, " - + Conversation.STATUS + " NUMBER, " + Conversation.MODE - + " NUMBER, " + Conversation.ATTRIBUTES + " TEXT, FOREIGN KEY(" - + Conversation.ACCOUNT + ") REFERENCES " + Account.TABLENAME - + "(" + Account.UUID + ") ON DELETE CASCADE);"); - db.execSQL("create table " + Message.TABLENAME + "( " + Message.UUID - + " TEXT PRIMARY KEY, " + Message.CONVERSATION + " TEXT, " - + Message.TIME_SENT + " NUMBER, " + Message.COUNTERPART - + " TEXT, " + Message.TRUE_COUNTERPART + " TEXT," - + Message.BODY + " TEXT, " + Message.ENCRYPTION + " NUMBER, " - + Message.STATUS + " NUMBER," + Message.TYPE + " NUMBER, " - + Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY(" - + Message.CONVERSATION + ") REFERENCES " - + Conversation.TABLENAME + "(" + Conversation.UUID - + ") ON DELETE CASCADE);"); - - db.execSQL(CREATE_CONTATCS_STATEMENT); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - if (oldVersion < 2 && newVersion >= 2) { - db.execSQL("update " + Account.TABLENAME + " set " - + Account.OPTIONS + " = " + Account.OPTIONS + " | 8"); - } - if (oldVersion < 3 && newVersion >= 3) { - db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " - + Message.TYPE + " NUMBER"); - } - if (oldVersion < 5 && newVersion >= 5) { - db.execSQL("DROP TABLE " + Contact.TABLENAME); - db.execSQL(CREATE_CONTATCS_STATEMENT); - db.execSQL("UPDATE " + Account.TABLENAME + " SET " - + Account.ROSTERVERSION + " = NULL"); - } - if (oldVersion < 6 && newVersion >= 6) { - db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " - + Message.TRUE_COUNTERPART + " TEXT"); - } - if (oldVersion < 7 && newVersion >= 7) { - db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " - + Message.REMOTE_MSG_ID + " TEXT"); - db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " - + Contact.AVATAR + " TEXT"); - db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " - + Account.AVATAR + " TEXT"); - } - if (oldVersion < 8 && newVersion >= 8) { - db.execSQL("ALTER TABLE " + Conversation.TABLENAME + " ADD COLUMN " - + Conversation.ATTRIBUTES + " TEXT"); - } - } - - public static synchronized DatabaseBackend getInstance(Context context) { - if (instance == null) { - instance = new DatabaseBackend(context); - } - return instance; - } - - public void createConversation(Conversation conversation) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Conversation.TABLENAME, null, conversation.getContentValues()); - } - - public void createMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Message.TABLENAME, null, message.getContentValues()); - } - - public void createAccount(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Account.TABLENAME, null, account.getContentValues()); - } - - public void createContact(Contact contact) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Contact.TABLENAME, null, contact.getContentValues()); - } - - public int getConversationCount() { - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.rawQuery("select count(uuid) as count from " - + Conversation.TABLENAME + " where " + Conversation.STATUS - + "=" + Conversation.STATUS_AVAILABLE, null); - cursor.moveToFirst(); - return cursor.getInt(0); - } - - public CopyOnWriteArrayList getConversations(int status) { - CopyOnWriteArrayList list = new CopyOnWriteArrayList(); - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { Integer.toString(status) }; - Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME - + " where " + Conversation.STATUS + " = ? order by " - + Conversation.CREATED + " desc", selectionArgs); - while (cursor.moveToNext()) { - list.add(Conversation.fromCursor(cursor)); - } - return list; - } - - public ArrayList getMessages(Conversation conversations, int limit) { - return getMessages(conversations, limit, -1); - } - - public ArrayList getMessages(Conversation conversation, int limit, - long timestamp) { - ArrayList list = new ArrayList(); - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor; - if (timestamp == -1) { - String[] selectionArgs = { conversation.getUuid() }; - cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION - + "=?", selectionArgs, null, null, Message.TIME_SENT - + " DESC", String.valueOf(limit)); - } else { - String[] selectionArgs = { conversation.getUuid(), - Long.toString(timestamp) }; - cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION - + "=? and " + Message.TIME_SENT + " 0) { - cursor.moveToLast(); - do { - Message message = Message.fromCursor(cursor); - message.setConversation(conversation); - list.add(message); - } while (cursor.moveToPrevious()); - } - return list; - } - - public Conversation findConversation(Account account, String contactJid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { account.getUuid(), contactJid + "%" }; - Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID - + " like ?", selectionArgs, null, null, null); - if (cursor.getCount() == 0) - return null; - cursor.moveToFirst(); - return Conversation.fromCursor(cursor); - } - - public void updateConversation(Conversation conversation) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { conversation.getUuid() }; - db.update(Conversation.TABLENAME, conversation.getContentValues(), - Conversation.UUID + "=?", args); - } - - public List getAccounts() { - List list = new ArrayList(); - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.query(Account.TABLENAME, null, null, null, null, - null, null); - while (cursor.moveToNext()) { - list.add(Account.fromCursor(cursor)); - } - cursor.close(); - return list; - } - - public void updateAccount(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; - db.update(Account.TABLENAME, account.getContentValues(), Account.UUID - + "=?", args); - } - - public void deleteAccount(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; - db.delete(Account.TABLENAME, Account.UUID + "=?", args); - } - - public boolean hasEnabledAccounts() { - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.rawQuery("select count(" + Account.UUID + ") from " - + Account.TABLENAME + " where not options & (1 <<1)", null); - try { - cursor.moveToFirst(); - int count = cursor.getInt(0); - cursor.close(); - return (count > 0); - } catch (SQLiteCantOpenDatabaseException e) { - return true; // better safe than sorry - } - } - - @Override - public SQLiteDatabase getWritableDatabase() { - SQLiteDatabase db = super.getWritableDatabase(); - db.execSQL("PRAGMA foreign_keys=ON;"); - return db; - } - - public void updateMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { message.getUuid() }; - db.update(Message.TABLENAME, message.getContentValues(), Message.UUID - + "=?", args); - } - - public void readRoster(Roster roster) { - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor; - String args[] = { roster.getAccount().getUuid() }; - cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", - args, null, null, null); - while (cursor.moveToNext()) { - roster.initContact(Contact.fromCursor(cursor)); - } - cursor.close(); - } - - public void writeRoster(Roster roster) { - Account account = roster.getAccount(); - SQLiteDatabase db = this.getWritableDatabase(); - for (Contact contact : roster.getContacts()) { - if (contact.getOption(Contact.Options.IN_ROSTER)) { - db.insert(Contact.TABLENAME, null, contact.getContentValues()); - } else { - String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?"; - String[] whereArgs = { account.getUuid(), contact.getJid() }; - db.delete(Contact.TABLENAME, where, whereArgs); - } - } - account.setRosterVersion(roster.getVersion()); - updateAccount(account); - } - - public void deleteMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { message.getUuid() }; - db.delete(Message.TABLENAME, Message.UUID + "=?", args); - } - - public void deleteMessagesInConversation(Conversation conversation) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { conversation.getUuid() }; - db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args); - } - - public Conversation findConversationByUuid(String conversationUuid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { conversationUuid }; - Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.UUID + "=?", selectionArgs, null, null, null); - if (cursor.getCount() == 0) { - return null; - } - cursor.moveToFirst(); - return Conversation.fromCursor(cursor); - } - - public Message findMessageByUuid(String messageUuid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { messageUuid }; - Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?", - selectionArgs, null, null, null); - if (cursor.getCount() == 0) { - return null; - } - cursor.moveToFirst(); - return Message.fromCursor(cursor); - } - - public Account findAccountByUuid(String accountUuid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { accountUuid }; - Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?", - selectionArgs, null, null, null); - if (cursor.getCount() == 0) { - return null; - } - cursor.moveToFirst(); - return Account.fromCursor(cursor); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/conversations/src/main/java/eu/siacs/conversations/persistance/FileBackend.java deleted file mode 100644 index b891e9ef..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ /dev/null @@ -1,480 +0,0 @@ -package eu.siacs.conversations.persistance; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.DigestOutputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.RectF; -import android.media.ExifInterface; -import android.net.Uri; -import android.os.Environment; -import android.provider.MediaStore; -import android.util.Base64; -import android.util.Base64OutputStream; -import android.util.Log; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; -import eu.siacs.conversations.xmpp.pep.Avatar; - -public class FileBackend { - - private static int IMAGE_SIZE = 1920; - - private SimpleDateFormat imageDateFormat = new SimpleDateFormat( - "yyyyMMdd_HHmmssSSS", Locale.US); - - private XmppConnectionService mXmppConnectionService; - - public FileBackend(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - public DownloadableFile getFile(Message message) { - return getFile(message, true); - } - - public DownloadableFile getFile(Message message, boolean decrypted) { - StringBuilder filename = new StringBuilder(); - filename.append(getConversationsDirectory()); - filename.append(message.getUuid()); - if ((decrypted) || (message.getEncryption() == Message.ENCRYPTION_NONE)) { - filename.append(".webp"); - } else { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - filename.append(".webp"); - } else { - filename.append(".webp.pgp"); - } - } - return new DownloadableFile(filename.toString()); - } - - public static String getConversationsDirectory() { - return Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_PICTURES).getAbsolutePath() - + "/Conversations/"; - } - - public Bitmap resize(Bitmap originalBitmap, int size) { - int w = originalBitmap.getWidth(); - int h = originalBitmap.getHeight(); - if (Math.max(w, h) > size) { - int scalledW; - int scalledH; - if (w <= h) { - scalledW = (int) (w / ((double) h / size)); - scalledH = size; - } else { - scalledW = size; - scalledH = (int) (h / ((double) w / size)); - } - Bitmap scalledBitmap = Bitmap.createScaledBitmap(originalBitmap, - scalledW, scalledH, true); - return scalledBitmap; - } else { - return originalBitmap; - } - } - - public Bitmap rotate(Bitmap bitmap, int degree) { - int w = bitmap.getWidth(); - int h = bitmap.getHeight(); - Matrix mtx = new Matrix(); - mtx.postRotate(degree); - return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true); - } - - public DownloadableFile copyImageToPrivateStorage(Message message, Uri image) - throws ImageCopyException { - return this.copyImageToPrivateStorage(message, image, 0); - } - - private DownloadableFile copyImageToPrivateStorage(Message message, - Uri image, int sampleSize) throws ImageCopyException { - try { - InputStream is = mXmppConnectionService.getContentResolver() - .openInputStream(image); - DownloadableFile file = getFile(message); - file.getParentFile().mkdirs(); - file.createNewFile(); - Bitmap originalBitmap; - BitmapFactory.Options options = new BitmapFactory.Options(); - int inSampleSize = (int) Math.pow(2, sampleSize); - Log.d(Config.LOGTAG, "reading bitmap with sample size " - + inSampleSize); - options.inSampleSize = inSampleSize; - originalBitmap = BitmapFactory.decodeStream(is, null, options); - is.close(); - if (originalBitmap == null) { - throw new ImageCopyException(R.string.error_not_an_image_file); - } - Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE); - originalBitmap = null; - int rotation = getRotation(image); - if (rotation > 0) { - scalledBitmap = rotate(scalledBitmap, rotation); - } - OutputStream os = new FileOutputStream(file); - boolean success = scalledBitmap.compress( - Bitmap.CompressFormat.WEBP, 75, os); - if (!success) { - throw new ImageCopyException(R.string.error_compressing_image); - } - os.flush(); - os.close(); - long size = file.getSize(); - int width = scalledBitmap.getWidth(); - int height = scalledBitmap.getHeight(); - message.setBody(Long.toString(size) + ',' + width + ',' + height); - return file; - } catch (FileNotFoundException e) { - throw new ImageCopyException(R.string.error_file_not_found); - } catch (IOException e) { - throw new ImageCopyException(R.string.error_io_exception); - } catch (SecurityException e) { - throw new ImageCopyException( - R.string.error_security_exception_during_image_copy); - } catch (OutOfMemoryError e) { - ++sampleSize; - if (sampleSize <= 3) { - return copyImageToPrivateStorage(message, image, sampleSize); - } else { - throw new ImageCopyException(R.string.error_out_of_memory); - } - } - } - - private int getRotation(Uri image) { - if ("content".equals(image.getScheme())) { - try { - Cursor cursor = mXmppConnectionService - .getContentResolver() - .query(image, - new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, - null, null, null); - if (cursor.getCount() != 1) { - return -1; - } - cursor.moveToFirst(); - return cursor.getInt(0); - } catch (IllegalArgumentException e) { - return -1; - } - } else { - ExifInterface exif; - try { - exif = new ExifInterface(image.toString()); - if (exif.getAttribute(ExifInterface.TAG_ORIENTATION) - .equalsIgnoreCase("6")) { - return 90; - } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION) - .equalsIgnoreCase("8")) { - return 270; - } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION) - .equalsIgnoreCase("3")) { - return 180; - } else { - return 0; - } - } catch (IOException e) { - return -1; - } - } - } - - public Bitmap getImageFromMessage(Message message) { - return BitmapFactory.decodeFile(getFile(message).getAbsolutePath()); - } - - public Bitmap getThumbnail(Message message, int size, boolean cacheOnly) - throws FileNotFoundException { - Bitmap thumbnail = mXmppConnectionService.getBitmapCache().get( - message.getUuid()); - if ((thumbnail == null) && (!cacheOnly)) { - File file = getFile(message); - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = calcSampleSize(file, size); - Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath(), - options); - if (fullsize == null) { - throw new FileNotFoundException(); - } - thumbnail = resize(fullsize, size); - this.mXmppConnectionService.getBitmapCache().put(message.getUuid(), - thumbnail); - } - return thumbnail; - } - - public void removeFiles(Conversation conversation) { - String prefix = mXmppConnectionService.getFilesDir().getAbsolutePath(); - String path = prefix + "/" + conversation.getAccount().getJid() + "/" - + conversation.getContactJid(); - File file = new File(path); - try { - this.deleteFile(file); - } catch (IOException e) { - Log.d(Config.LOGTAG, - "error deleting file: " + file.getAbsolutePath()); - } - } - - private void deleteFile(File f) throws IOException { - if (f.isDirectory()) { - for (File c : f.listFiles()) - deleteFile(c); - } - f.delete(); - } - - public Uri getTakePhotoUri() { - StringBuilder pathBuilder = new StringBuilder(); - pathBuilder.append(Environment - .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)); - pathBuilder.append('/'); - pathBuilder.append("Camera"); - pathBuilder.append('/'); - pathBuilder.append("IMG_" + this.imageDateFormat.format(new Date()) - + ".jpg"); - Uri uri = Uri.parse("file://" + pathBuilder.toString()); - File file = new File(uri.toString()); - file.getParentFile().mkdirs(); - return uri; - } - - public Avatar getPepAvatar(Uri image, int size, Bitmap.CompressFormat format) { - try { - Avatar avatar = new Avatar(); - Bitmap bm = cropCenterSquare(image, size); - if (bm == null) { - return null; - } - ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream(); - Base64OutputStream mBase64OutputSttream = new Base64OutputStream( - mByteArrayOutputStream, Base64.DEFAULT); - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - DigestOutputStream mDigestOutputStream = new DigestOutputStream( - mBase64OutputSttream, digest); - if (!bm.compress(format, 75, mDigestOutputStream)) { - return null; - } - mDigestOutputStream.flush(); - mDigestOutputStream.close(); - avatar.sha1sum = CryptoHelper.bytesToHex(digest.digest()); - avatar.image = new String(mByteArrayOutputStream.toByteArray()); - return avatar; - } catch (NoSuchAlgorithmException e) { - return null; - } catch (IOException e) { - return null; - } - } - - public boolean isAvatarCached(Avatar avatar) { - File file = new File(getAvatarPath(avatar.getFilename())); - return file.exists(); - } - - public boolean save(Avatar avatar) { - if (isAvatarCached(avatar)) { - return true; - } - String filename = getAvatarPath(avatar.getFilename()); - File file = new File(filename + ".tmp"); - file.getParentFile().mkdirs(); - try { - file.createNewFile(); - FileOutputStream mFileOutputStream = new FileOutputStream(file); - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.reset(); - DigestOutputStream mDigestOutputStream = new DigestOutputStream( - mFileOutputStream, digest); - mDigestOutputStream.write(avatar.getImageAsBytes()); - mDigestOutputStream.flush(); - mDigestOutputStream.close(); - avatar.size = file.length(); - String sha1sum = CryptoHelper.bytesToHex(digest.digest()); - if (sha1sum.equals(avatar.sha1sum)) { - file.renameTo(new File(filename)); - return true; - } else { - Log.d(Config.LOGTAG, "sha1sum mismatch for " + avatar.owner); - file.delete(); - return false; - } - } catch (FileNotFoundException e) { - return false; - } catch (IOException e) { - return false; - } catch (NoSuchAlgorithmException e) { - return false; - } - } - - public String getAvatarPath(String avatar) { - return mXmppConnectionService.getFilesDir().getAbsolutePath() - + "/avatars/" + avatar; - } - - public Uri getAvatarUri(String avatar) { - return Uri.parse("file:" + getAvatarPath(avatar)); - } - - public Bitmap cropCenterSquare(Uri image, int size) { - try { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = calcSampleSize(image, size); - InputStream is = mXmppConnectionService.getContentResolver() - .openInputStream(image); - Bitmap input = BitmapFactory.decodeStream(is, null, options); - if (input == null) { - return null; - } else { - int rotation = getRotation(image); - if (rotation > 0) { - input = rotate(input, rotation); - } - return cropCenterSquare(input, size); - } - } catch (FileNotFoundException e) { - return null; - } - } - - public Bitmap cropCenter(Uri image, int newHeight, int newWidth) { - try { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = calcSampleSize(image, - Math.max(newHeight, newWidth)); - InputStream is = mXmppConnectionService.getContentResolver() - .openInputStream(image); - Bitmap source = BitmapFactory.decodeStream(is, null, options); - - int sourceWidth = source.getWidth(); - int sourceHeight = source.getHeight(); - float xScale = (float) newWidth / sourceWidth; - float yScale = (float) newHeight / sourceHeight; - float scale = Math.max(xScale, yScale); - float scaledWidth = scale * sourceWidth; - float scaledHeight = scale * sourceHeight; - float left = (newWidth - scaledWidth) / 2; - float top = (newHeight - scaledHeight) / 2; - - RectF targetRect = new RectF(left, top, left + scaledWidth, top - + scaledHeight); - Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, - source.getConfig()); - Canvas canvas = new Canvas(dest); - canvas.drawBitmap(source, null, targetRect, null); - - return dest; - } catch (FileNotFoundException e) { - return null; - } - - } - - public Bitmap cropCenterSquare(Bitmap input, int size) { - int w = input.getWidth(); - int h = input.getHeight(); - - float scale = Math.max((float) size / h, (float) size / w); - - float outWidth = scale * w; - float outHeight = scale * h; - float left = (size - outWidth) / 2; - float top = (size - outHeight) / 2; - RectF target = new RectF(left, top, left + outWidth, top + outHeight); - - Bitmap output = Bitmap.createBitmap(size, size, input.getConfig()); - Canvas canvas = new Canvas(output); - canvas.drawBitmap(input, null, target, null); - return output; - } - - private int calcSampleSize(Uri image, int size) - throws FileNotFoundException { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeStream(mXmppConnectionService.getContentResolver() - .openInputStream(image), null, options); - return calcSampleSize(options, size); - } - - private int calcSampleSize(File image, int size) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(image.getAbsolutePath(), options); - return calcSampleSize(options, size); - } - - private int calcSampleSize(BitmapFactory.Options options, int size) { - int height = options.outHeight; - int width = options.outWidth; - int inSampleSize = 1; - - if (height > size || width > size) { - int halfHeight = height / 2; - int halfWidth = width / 2; - - while ((halfHeight / inSampleSize) > size - && (halfWidth / inSampleSize) > size) { - inSampleSize *= 2; - } - } - return inSampleSize; - } - - public Uri getJingleFileUri(Message message) { - File file = getFile(message); - return Uri.parse("file://" + file.getAbsolutePath()); - } - - public class ImageCopyException extends Exception { - private static final long serialVersionUID = -1010013599132881427L; - private int resId; - - public ImageCopyException(int resId) { - this.resId = resId; - } - - public int getResId() { - return resId; - } - } - - public Bitmap getAvatar(String avatar, int size) { - if (avatar == null) { - return null; - } - Bitmap bm = cropCenter(getAvatarUri(avatar), size, size); - if (bm == null) { - return null; - } - return bm; - } - - public boolean isFileAvailable(Message message) { - return getFile(message).exists(); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/persistance/OnPhoneContactsMerged.java b/conversations/src/main/java/eu/siacs/conversations/persistance/OnPhoneContactsMerged.java deleted file mode 100644 index 6a457b17..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/persistance/OnPhoneContactsMerged.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.siacs.conversations.persistance; - -public interface OnPhoneContactsMerged { - public void phoneContactsMerged(); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/conversations/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java deleted file mode 100644 index 676a09c9..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package eu.siacs.conversations.services; - -public class AbstractConnectionManager { - protected XmppConnectionService mXmppConnectionService; - - public AbstractConnectionManager(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - public XmppConnectionService getXmppConnectionService() { - return this.mXmppConnectionService; - } - - public long getAutoAcceptFileSize() { - String config = this.mXmppConnectionService.getPreferences().getString( - "auto_accept_file_size", "524288"); - try { - return Long.parseLong(config); - } catch (NumberFormatException e) { - return 524288; - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/services/AvatarService.java b/conversations/src/main/java/eu/siacs/conversations/services/AvatarService.java deleted file mode 100644 index c0668a19..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ /dev/null @@ -1,298 +0,0 @@ -package eu.siacs.conversations.services; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Bookmark; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.ListItem; -import eu.siacs.conversations.entities.MucOptions; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.net.Uri; -import android.util.Log; - -public class AvatarService { - - private static final int FG_COLOR = 0xFFFAFAFA; - private static final int TRANSPARENT = 0x00000000; - - private static final String PREFIX_CONTACT = "contact"; - private static final String PREFIX_CONVERSATION = "conversation"; - private static final String PREFIX_ACCOUNT = "account"; - private static final String PREFIX_GENERIC = "generic"; - - private ArrayList sizes = new ArrayList(); - - protected XmppConnectionService mXmppConnectionService = null; - - public AvatarService(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - public Bitmap get(Contact contact, int size) { - final String KEY = key(contact, size); - Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY); - if (avatar != null) { - return avatar; - } - Log.d(Config.LOGTAG, "no cache hit for " + KEY); - avatar = mXmppConnectionService.getFileBackend().getAvatar( - contact.getAvatar(), size); - if (avatar == null) { - if (contact.getProfilePhoto() != null) { - avatar = mXmppConnectionService.getFileBackend() - .cropCenterSquare(Uri.parse(contact.getProfilePhoto()), - size); - if (avatar == null) { - avatar = get(contact.getDisplayName(), size); - } - } else { - avatar = get(contact.getDisplayName(), size); - } - } - this.mXmppConnectionService.getBitmapCache().put(KEY, avatar); - return avatar; - } - - public void clear(Contact contact) { - for (Integer size : sizes) { - this.mXmppConnectionService.getBitmapCache().remove( - key(contact, size)); - } - } - - private String key(Contact contact, int size) { - synchronized (this.sizes) { - if (!this.sizes.contains(size)) { - this.sizes.add(size); - } - } - return PREFIX_CONTACT + "_" + contact.getAccount().getJid() + "_" - + contact.getJid() + "_" + String.valueOf(size); - } - - public Bitmap get(ListItem item, int size) { - if (item instanceof Contact) { - return get((Contact) item, size); - } else if (item instanceof Bookmark) { - Bookmark bookmark = (Bookmark) item; - if (bookmark.getConversation() != null) { - return get(bookmark.getConversation(), size); - } else { - return get(bookmark.getDisplayName(), size); - } - } else { - return get(item.getDisplayName(), size); - } - } - - public Bitmap get(Conversation conversation, int size) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { - return get(conversation.getContact(), size); - } else { - return get(conversation.getMucOptions(), size); - } - } - - public void clear(Conversation conversation) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { - clear(conversation.getContact()); - } else { - clear(conversation.getMucOptions()); - } - } - - public Bitmap get(MucOptions mucOptions, int size) { - final String KEY = key(mucOptions, size); - Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY); - if (bitmap != null) { - return bitmap; - } - Log.d(Config.LOGTAG, "no cache hit for " + KEY); - List users = mucOptions.getUsers(); - int count = users.size(); - bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - bitmap.eraseColor(TRANSPARENT); - - if (count == 0) { - String name = mucOptions.getConversation().getName(); - String letter = name.substring(0, 1); - int color = this.getColorForName(name); - drawTile(canvas, letter, color, 0, 0, size, size); - } else if (count == 1) { - drawTile(canvas, users.get(0), 0, 0, size, size); - } else if (count == 2) { - drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size); - drawTile(canvas, users.get(1), size / 2 + 1, 0, size, size); - } else if (count == 3) { - drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size); - drawTile(canvas, users.get(1), size / 2 + 1, 0, size, size / 2 - 1); - drawTile(canvas, users.get(2), size / 2 + 1, size / 2 + 1, size, - size); - } else if (count == 4) { - drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size / 2 - 1); - drawTile(canvas, users.get(1), 0, size / 2 + 1, size / 2 - 1, size); - drawTile(canvas, users.get(2), size / 2 + 1, 0, size, size / 2 - 1); - drawTile(canvas, users.get(3), size / 2 + 1, size / 2 + 1, size, - size); - } else { - drawTile(canvas, users.get(0), 0, 0, size / 2 - 1, size / 2 - 1); - drawTile(canvas, users.get(1), 0, size / 2 + 1, size / 2 - 1, size); - drawTile(canvas, users.get(2), size / 2 + 1, 0, size, size / 2 - 1); - drawTile(canvas, "\u2026", 0xFF202020, size / 2 + 1, size / 2 + 1, - size, size); - } - this.mXmppConnectionService.getBitmapCache().put(KEY, bitmap); - return bitmap; - } - - public void clear(MucOptions options) { - for (Integer size : sizes) { - this.mXmppConnectionService.getBitmapCache().remove( - key(options, size)); - } - } - - private String key(MucOptions options, int size) { - synchronized (this.sizes) { - if (!this.sizes.contains(size)) { - this.sizes.add(size); - } - } - return PREFIX_CONVERSATION + "_" + options.getConversation().getUuid() - + "_" + String.valueOf(size); - } - - public Bitmap get(Account account, int size) { - final String KEY = key(account, size); - Bitmap avatar = mXmppConnectionService.getBitmapCache().get(KEY); - if (avatar != null) { - return avatar; - } - Log.d(Config.LOGTAG, "no cache hit for " + KEY); - avatar = mXmppConnectionService.getFileBackend().getAvatar( - account.getAvatar(), size); - if (avatar == null) { - avatar = get(account.getJid(), size); - } - mXmppConnectionService.getBitmapCache().put(KEY, avatar); - return avatar; - } - - public void clear(Account account) { - for (Integer size : sizes) { - this.mXmppConnectionService.getBitmapCache().remove( - key(account, size)); - } - } - - private String key(Account account, int size) { - synchronized (this.sizes) { - if (!this.sizes.contains(size)) { - this.sizes.add(size); - } - } - return PREFIX_ACCOUNT + "_" + account.getUuid() + "_" - + String.valueOf(size); - } - - public Bitmap get(String name, int size) { - final String KEY = key(name, size); - Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY); - if (bitmap != null) { - return bitmap; - } - Log.d(Config.LOGTAG, "no cache hit for " + KEY); - bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - String letter = name.substring(0, 1); - int color = this.getColorForName(name); - drawTile(canvas, letter, color, 0, 0, size, size); - mXmppConnectionService.getBitmapCache().put(KEY, bitmap); - return bitmap; - } - - private String key(String name, int size) { - synchronized (this.sizes) { - if (!this.sizes.contains(size)) { - this.sizes.add(size); - } - } - return PREFIX_GENERIC + "_" + name + "_" + String.valueOf(size); - } - - private void drawTile(Canvas canvas, String letter, int tileColor, - int left, int top, int right, int bottom) { - letter = letter.toUpperCase(Locale.getDefault()); - Paint tilePaint = new Paint(), textPaint = new Paint(); - tilePaint.setColor(tileColor); - textPaint.setFlags(Paint.ANTI_ALIAS_FLAG); - textPaint.setColor(FG_COLOR); - textPaint.setTypeface(Typeface.create("sans-serif-light", - Typeface.NORMAL)); - textPaint.setTextSize((float) ((right - left) * 0.8)); - Rect rect = new Rect(); - - canvas.drawRect(new Rect(left, top, right, bottom), tilePaint); - textPaint.getTextBounds(letter, 0, 1, rect); - float width = textPaint.measureText(letter); - canvas.drawText(letter, (right + left) / 2 - width / 2, (top + bottom) - / 2 + rect.height() / 2, textPaint); - } - - private void drawTile(Canvas canvas, MucOptions.User user, int left, - int top, int right, int bottom) { - Contact contact = user.getContact(); - if (contact != null) { - Uri uri = null; - if (contact.getAvatar() != null) { - uri = mXmppConnectionService.getFileBackend().getAvatarUri( - contact.getAvatar()); - } else if (contact.getProfilePhoto() != null) { - uri = Uri.parse(contact.getProfilePhoto()); - } - if (uri != null) { - Bitmap bitmap = mXmppConnectionService.getFileBackend() - .cropCenter(uri, bottom - top, right - left); - if (bitmap != null) { - drawTile(canvas, bitmap, left, top, right, bottom); - } else { - String letter = user.getName().substring(0, 1); - int color = this.getColorForName(user.getName()); - drawTile(canvas, letter, color, left, top, right, bottom); - } - } else { - String letter = user.getName().substring(0, 1); - int color = this.getColorForName(user.getName()); - drawTile(canvas, letter, color, left, top, right, bottom); - } - } else { - String letter = user.getName().substring(0, 1); - int color = this.getColorForName(user.getName()); - drawTile(canvas, letter, color, left, top, right, bottom); - } - } - - private void drawTile(Canvas canvas, Bitmap bm, int dstleft, int dsttop, - int dstright, int dstbottom) { - Rect dst = new Rect(dstleft, dsttop, dstright, dstbottom); - canvas.drawBitmap(bm, null, dst, null); - } - - private int getColorForName(String name) { - int holoColors[] = { 0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5, - 0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4, 0xFF009688, 0xFFff5722, - 0xFF795548, 0xFF607d8b }; - return holoColors[(int) ((name.hashCode() & 0xffffffffl) % holoColors.length)]; - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/services/EventReceiver.java b/conversations/src/main/java/eu/siacs/conversations/services/EventReceiver.java deleted file mode 100644 index dfbe9db7..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/services/EventReceiver.java +++ /dev/null @@ -1,24 +0,0 @@ -package eu.siacs.conversations.services; - -import eu.siacs.conversations.persistance.DatabaseBackend; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class EventReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Intent mIntentForService = new Intent(context, - XmppConnectionService.class); - if (intent.getAction() != null) { - mIntentForService.setAction(intent.getAction()); - } else { - mIntentForService.setAction("other"); - } - if (intent.getAction().equals("ui") - || DatabaseBackend.getInstance(context).hasEnabledAccounts()) { - context.startService(mIntentForService); - } - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/services/NotificationService.java b/conversations/src/main/java/eu/siacs/conversations/services/NotificationService.java deleted file mode 100644 index 00765deb..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ /dev/null @@ -1,237 +0,0 @@ -package eu.siacs.conversations.services; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.PowerManager; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.TaskStackBuilder; -import android.text.Html; -import android.util.DisplayMetrics; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.ui.ConversationActivity; - -public class NotificationService { - - private XmppConnectionService mXmppConnectionService; - - private LinkedHashMap> notifications = new LinkedHashMap>(); - - public int NOTIFICATION_ID = 0x2342; - private Conversation mOpenConversation; - private boolean mIsInForeground; - - public NotificationService(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - public void push(Message message) { - PowerManager pm = (PowerManager) mXmppConnectionService - .getSystemService(Context.POWER_SERVICE); - boolean isScreenOn = pm.isScreenOn(); - - if (this.mIsInForeground && isScreenOn - && this.mOpenConversation == message.getConversation()) { - return; - } - synchronized (notifications) { - String conversationUuid = message.getConversationUuid(); - if (notifications.containsKey(conversationUuid)) { - notifications.get(conversationUuid).add(message); - } else { - ArrayList mList = new ArrayList(); - mList.add(message); - notifications.put(conversationUuid, mList); - } - Account account = message.getConversation().getAccount(); - updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) - && !account.inGracePeriod()); - } - - } - - public void clear() { - synchronized (notifications) { - notifications.clear(); - updateNotification(false); - } - } - - public void clear(Conversation conversation) { - synchronized (notifications) { - notifications.remove(conversation.getUuid()); - updateNotification(false); - } - } - - private void updateNotification(boolean notify) { - NotificationManager notificationManager = (NotificationManager) mXmppConnectionService - .getSystemService(Context.NOTIFICATION_SERVICE); - SharedPreferences preferences = mXmppConnectionService.getPreferences(); - - String ringtone = preferences.getString("notification_ringtone", null); - boolean vibrate = preferences.getBoolean("vibrate_on_notification", - true); - - if (notifications.size() == 0) { - notificationManager.cancel(NOTIFICATION_ID); - } else { - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( - mXmppConnectionService); - mBuilder.setSmallIcon(R.drawable.ic_notification); - if (notifications.size() == 1) { - ArrayList messages = notifications.values().iterator() - .next(); - if (messages.size() >= 1) { - Conversation conversation = messages.get(0) - .getConversation(); - mBuilder.setLargeIcon(mXmppConnectionService - .getAvatarService().get(conversation, getPixel(64))); - mBuilder.setContentTitle(conversation.getName()); - StringBuilder text = new StringBuilder(); - for (int i = 0; i < messages.size(); ++i) { - text.append(messages.get(i).getReadableBody( - mXmppConnectionService)); - if (i != messages.size() - 1) { - text.append("\n"); - } - } - mBuilder.setStyle(new NotificationCompat.BigTextStyle() - .bigText(text.toString())); - mBuilder.setContentText(messages.get(0).getReadableBody( - mXmppConnectionService)); - if (notify) { - mBuilder.setTicker(messages.get(messages.size() - 1) - .getReadableBody(mXmppConnectionService)); - } - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); - } else { - notificationManager.cancel(NOTIFICATION_ID); - return; - } - } else { - NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(notifications.size() - + " " - + mXmppConnectionService - .getString(R.string.unread_conversations)); - StringBuilder names = new StringBuilder(); - Conversation conversation = null; - for (ArrayList messages : notifications.values()) { - if (messages.size() > 0) { - conversation = messages.get(0).getConversation(); - String name = conversation.getName(); - style.addLine(Html.fromHtml("" - + name - + " " - + messages.get(0).getReadableBody( - mXmppConnectionService))); - names.append(name); - names.append(", "); - } - } - if (names.length() >= 2) { - names.delete(names.length() - 2, names.length()); - } - mBuilder.setContentTitle(notifications.size() - + " " - + mXmppConnectionService - .getString(R.string.unread_conversations)); - mBuilder.setContentText(names.toString()); - mBuilder.setStyle(style); - if (conversation != null) { - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); - } - } - if (notify) { - if (vibrate) { - int dat = 70; - long[] pattern = { 0, 3 * dat, dat, dat }; - mBuilder.setVibrate(pattern); - } - if (ringtone != null) { - mBuilder.setSound(Uri.parse(ringtone)); - } - } - mBuilder.setDeleteIntent(createDeleteIntent()); - mBuilder.setLights(0xffffffff, 2000, 4000); - Notification notification = mBuilder.build(); - notificationManager.notify(NOTIFICATION_ID, notification); - } - } - - private PendingIntent createContentIntent(String conversationUuid) { - TaskStackBuilder stackBuilder = TaskStackBuilder - .create(mXmppConnectionService); - stackBuilder.addParentStack(ConversationActivity.class); - - Intent viewConversationIntent = new Intent(mXmppConnectionService, - ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - conversationUuid); - viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); - - stackBuilder.addNextIntent(viewConversationIntent); - - PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, - PendingIntent.FLAG_UPDATE_CURRENT); - return resultPendingIntent; - } - - private PendingIntent createDeleteIntent() { - Intent intent = new Intent(mXmppConnectionService, - XmppConnectionService.class); - intent.setAction("clear_notification"); - return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); - } - - public static boolean wasHighlightedOrPrivate(Message message) { - String nick = message.getConversation().getMucOptions().getActualNick(); - Pattern highlight = generateNickHighlightPattern(nick); - if (message.getBody() == null || nick == null) { - return false; - } - Matcher m = highlight.matcher(message.getBody()); - return (m.find() || message.getType() == Message.TYPE_PRIVATE); - } - - private static Pattern generateNickHighlightPattern(String nick) { - // We expect a word boundary, i.e. space or start of string, followed by - // the - // nick (matched in case-insensitive manner), followed by optional - // punctuation (for example "bob: i disagree" or "how are you alice?"), - // followed by another word boundary. - return Pattern.compile("\\b" + nick + "\\p{Punct}?\\b", - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); - } - - public void setOpenConversation(Conversation conversation) { - this.mOpenConversation = conversation; - } - - public void setIsInForeground(boolean foreground) { - this.mIsInForeground = foreground; - } - - private int getPixel(int dp) { - DisplayMetrics metrics = mXmppConnectionService.getResources() - .getDisplayMetrics(); - return ((int) (dp * metrics.density)); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/conversations/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java deleted file mode 100644 index 37e334eb..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ /dev/null @@ -1,1927 +0,0 @@ -package eu.siacs.conversations.services; - -import java.security.SecureRandom; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Hashtable; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.openintents.openpgp.util.OpenPgpApi; -import org.openintents.openpgp.util.OpenPgpServiceConnection; - -import de.duenndns.ssl.MemorizingTrustManager; - -import net.java.otr4j.OtrException; -import net.java.otr4j.session.Session; -import net.java.otr4j.session.SessionStatus; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Bookmark; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.entities.MucOptions.OnRenameListener; -import eu.siacs.conversations.entities.Presences; -import eu.siacs.conversations.generator.IqGenerator; -import eu.siacs.conversations.generator.MessageGenerator; -import eu.siacs.conversations.generator.PresenceGenerator; -import eu.siacs.conversations.http.HttpConnectionManager; -import eu.siacs.conversations.parser.IqParser; -import eu.siacs.conversations.parser.MessageParser; -import eu.siacs.conversations.parser.PresenceParser; -import eu.siacs.conversations.persistance.DatabaseBackend; -import eu.siacs.conversations.persistance.FileBackend; -import eu.siacs.conversations.ui.UiCallback; -import eu.siacs.conversations.utils.CryptoHelper; -import eu.siacs.conversations.utils.ExceptionHelper; -import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener; -import eu.siacs.conversations.utils.PRNGFixes; -import eu.siacs.conversations.utils.PhoneHelper; -import eu.siacs.conversations.utils.UIHelper; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnBindListener; -import eu.siacs.conversations.xmpp.OnContactStatusChanged; -import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.OnMessageAcknowledged; -import eu.siacs.conversations.xmpp.OnStatusChanged; -import eu.siacs.conversations.xmpp.XmppConnection; -import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager; -import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived; -import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; -import eu.siacs.conversations.xmpp.pep.Avatar; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; -import eu.siacs.conversations.xmpp.stanzas.PresencePacket; -import android.annotation.SuppressLint; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.ContentObserver; -import android.graphics.Bitmap; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.Uri; -import android.os.Binder; -import android.os.Bundle; -import android.os.FileObserver; -import android.os.IBinder; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.SystemClock; -import android.preference.PreferenceManager; -import android.provider.ContactsContract; -import android.util.Log; -import android.util.LruCache; - -public class XmppConnectionService extends Service { - - public DatabaseBackend databaseBackend; - private FileBackend fileBackend = new FileBackend(this); - - public long startDate; - - private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; - public static String ACTION_CLEAR_NOTIFICATION = "clear_notification"; - - private MemorizingTrustManager mMemorizingTrustManager; - - private NotificationService mNotificationService = new NotificationService( - this); - - private MessageParser mMessageParser = new MessageParser(this); - private PresenceParser mPresenceParser = new PresenceParser(this); - private IqParser mIqParser = new IqParser(this); - private MessageGenerator mMessageGenerator = new MessageGenerator(this); - private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this); - - private List accounts; - private CopyOnWriteArrayList conversations = null; - private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager( - this); - private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( - this); - private AvatarService mAvatarService = new AvatarService(this); - - private OnConversationUpdate mOnConversationUpdate = null; - private Integer convChangedListenerCount = 0; - private OnAccountUpdate mOnAccountUpdate = null; - private Integer accountChangedListenerCount = 0; - private OnRosterUpdate mOnRosterUpdate = null; - private Integer rosterChangedListenerCount = 0; - public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() { - - @Override - public void onContactStatusChanged(Contact contact, boolean online) { - Conversation conversation = find(getConversations(), contact); - if (conversation != null) { - conversation.endOtrIfNeeded(); - if (online && (contact.getPresences().size() == 1)) { - sendUnsendMessages(conversation); - } - } - } - }; - - private SecureRandom mRandom; - - private ContentObserver contactObserver = new ContentObserver(null) { - @Override - public void onChange(boolean selfChange) { - super.onChange(selfChange); - Intent intent = new Intent(getApplicationContext(), - XmppConnectionService.class); - intent.setAction(ACTION_MERGE_PHONE_CONTACTS); - startService(intent); - } - }; - - private FileObserver fileObserver = new FileObserver( - FileBackend.getConversationsDirectory()) { - - @Override - public void onEvent(int event, String path) { - if (event == FileObserver.DELETE) { - markFileDeleted(path.split("\\.")[0]); - } - } - }; - - private final IBinder mBinder = new XmppConnectionBinder(); - private OnStatusChanged statusListener = new OnStatusChanged() { - - @Override - public void onStatusChanged(Account account) { - XmppConnection connection = account.getXmppConnection(); - if (mOnAccountUpdate != null) { - mOnAccountUpdate.onAccountUpdate(); - ; - } - if (account.getStatus() == Account.STATUS_ONLINE) { - for (Conversation conversation : account.pendingConferenceLeaves) { - leaveMuc(conversation); - } - for (Conversation conversation : account.pendingConferenceJoins) { - joinMuc(conversation); - } - mJingleConnectionManager.cancelInTransmission(); - List conversations = getConversations(); - for (int i = 0; i < conversations.size(); ++i) { - if (conversations.get(i).getAccount() == account) { - conversations.get(i).startOtrIfNeeded(); - sendUnsendMessages(conversations.get(i)); - } - } - if (connection != null && connection.getFeatures().csi()) { - if (checkListeners()) { - Log.d(Config.LOGTAG, account.getJid() - + " sending csi//inactive"); - connection.sendInactive(); - } else { - Log.d(Config.LOGTAG, account.getJid() - + " sending csi//active"); - connection.sendActive(); - } - } - syncDirtyContacts(account); - scheduleWakeupCall(Config.PING_MAX_INTERVAL, true); - } else if (account.getStatus() == Account.STATUS_OFFLINE) { - resetSendingToWaiting(account); - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - int timeToReconnect = mRandom.nextInt(50) + 10; - scheduleWakeupCall(timeToReconnect, false); - } - } else if (account.getStatus() == Account.STATUS_REGISTRATION_SUCCESSFULL) { - databaseBackend.updateAccount(account); - reconnectAccount(account, true); - } else if ((account.getStatus() != Account.STATUS_CONNECTING) - && (account.getStatus() != Account.STATUS_NO_INTERNET)) { - if (connection != null) { - int next = connection.getTimeToNextAttempt(); - Log.d(Config.LOGTAG, account.getJid() - + ": error connecting account. try again in " - + next + "s for the " - + (connection.getAttempt() + 1) + " time"); - scheduleWakeupCall((int) (next * 1.2), false); - } - } - UIHelper.showErrorNotification(getApplicationContext(), - getAccounts()); - } - }; - - private OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() { - - @Override - public void onJinglePacketReceived(Account account, JinglePacket packet) { - mJingleConnectionManager.deliverPacket(account, packet); - } - }; - - private OpenPgpServiceConnection pgpServiceConnection; - private PgpEngine mPgpEngine = null; - private Intent pingIntent; - private PendingIntent pendingPingIntent = null; - private WakeLock wakeLock; - private PowerManager pm; - private OnBindListener mOnBindListener = new OnBindListener() { - - @Override - public void onBind(final Account account) { - account.getRoster().clearPresences(); - account.clearPresences(); // self presences - account.pendingConferenceJoins.clear(); - account.pendingConferenceLeaves.clear(); - fetchRosterFromServer(account); - fetchBookmarks(account); - sendPresencePacket(account, - mPresenceGenerator.sendPresence(account)); - connectMultiModeConversations(account); - updateConversationUi(); - } - }; - - private OnMessageAcknowledged mOnMessageAcknowledgedListener = new OnMessageAcknowledged() { - - @Override - public void onMessageAcknowledged(Account account, String uuid) { - for (Conversation conversation : getConversations()) { - if (conversation.getAccount() == account) { - for (Message message : conversation.getMessages()) { - if ((message.getStatus() == Message.STATUS_UNSEND || message - .getStatus() == Message.STATUS_WAITING) - && message.getUuid().equals(uuid)) { - markMessage(message, Message.STATUS_SEND); - return; - } - } - } - } - } - }; - private LruCache mBitmapCache; - - public PgpEngine getPgpEngine() { - if (pgpServiceConnection.isBound()) { - if (this.mPgpEngine == null) { - this.mPgpEngine = new PgpEngine(new OpenPgpApi( - getApplicationContext(), - pgpServiceConnection.getService()), this); - } - return mPgpEngine; - } else { - return null; - } - - } - - public FileBackend getFileBackend() { - return this.fileBackend; - } - - public AvatarService getAvatarService() { - return this.mAvatarService; - } - - public Message attachImageToConversation(final Conversation conversation, - final Uri uri, final UiCallback callback) { - final Message message; - if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { - message = new Message(conversation, "", - Message.ENCRYPTION_DECRYPTED); - } else { - message = new Message(conversation, "", - conversation.getNextEncryption(forceEncryption())); - } - message.setPresence(conversation.getNextPresence()); - message.setType(Message.TYPE_IMAGE); - message.setStatus(Message.STATUS_OFFERED); - new Thread(new Runnable() { - - @Override - public void run() { - try { - getFileBackend().copyImageToPrivateStorage(message, uri); - if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { - getPgpEngine().encrypt(message, callback); - } else { - callback.success(message); - } - } catch (FileBackend.ImageCopyException e) { - callback.error(e.getResId(), message); - } - } - }).start(); - return message; - } - - public Conversation find(Bookmark bookmark) { - return find(bookmark.getAccount(), bookmark.getJid()); - } - - public Conversation find(Account account, String jid) { - return find(getConversations(), account, jid); - } - - public class XmppConnectionBinder extends Binder { - public XmppConnectionService getService() { - return XmppConnectionService.this; - } - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent != null && intent.getAction() != null) { - if (intent.getAction().equals(ACTION_MERGE_PHONE_CONTACTS)) { - mergePhoneContactsWithRoster(); - return START_STICKY; - } else if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { - logoutAndSave(); - return START_NOT_STICKY; - } else if (intent.getAction().equals(ACTION_CLEAR_NOTIFICATION)) { - mNotificationService.clear(); - } - } - this.wakeLock.acquire(); - - for (Account account : accounts) { - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - if (!hasInternetConnection()) { - account.setStatus(Account.STATUS_NO_INTERNET); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - } else { - if (account.getStatus() == Account.STATUS_NO_INTERNET) { - account.setStatus(Account.STATUS_OFFLINE); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - } - if (account.getStatus() == Account.STATUS_ONLINE) { - long lastReceived = account.getXmppConnection() - .getLastPacketReceived(); - long lastSent = account.getXmppConnection() - .getLastPingSent(); - if (lastSent - lastReceived >= Config.PING_TIMEOUT * 1000) { - Log.d(Config.LOGTAG, account.getJid() - + ": ping timeout"); - this.reconnectAccount(account, true); - } else if (SystemClock.elapsedRealtime() - lastReceived >= Config.PING_MIN_INTERVAL * 1000) { - account.getXmppConnection().sendPing(); - this.scheduleWakeupCall(2, false); - } - } else if (account.getStatus() == Account.STATUS_OFFLINE) { - if (account.getXmppConnection() == null) { - account.setXmppConnection(this - .createConnection(account)); - } - new Thread(account.getXmppConnection()).start(); - } else if ((account.getStatus() == Account.STATUS_CONNECTING) - && ((SystemClock.elapsedRealtime() - account - .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { - Log.d(Config.LOGTAG, account.getJid() - + ": time out during connect reconnecting"); - reconnectAccount(account, true); - } else { - if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { - reconnectAccount(account, true); - } - } - // in any case. reschedule wakup call - this.scheduleWakeupCall(Config.PING_MAX_INTERVAL, true); - } - if (mOnAccountUpdate != null) { - mOnAccountUpdate.onAccountUpdate(); - } - } - } - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - return START_STICKY; - } - - public boolean hasInternetConnection() { - ConnectivityManager cm = (ConnectivityManager) getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); - return activeNetwork != null && activeNetwork.isConnected(); - } - - @SuppressLint("TrulyRandom") - @Override - public void onCreate() { - ExceptionHelper.init(getApplicationContext()); - PRNGFixes.apply(); - this.mRandom = new SecureRandom(); - this.mMemorizingTrustManager = new MemorizingTrustManager( - getApplicationContext()); - - int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); - int cacheSize = maxMemory / 8; - this.mBitmapCache = new LruCache(cacheSize) { - @Override - protected int sizeOf(String key, Bitmap bitmap) { - return bitmap.getByteCount() / 1024; - } - }; - - this.databaseBackend = DatabaseBackend - .getInstance(getApplicationContext()); - this.accounts = databaseBackend.getAccounts(); - - for (Account account : this.accounts) { - this.databaseBackend.readRoster(account.getRoster()); - } - this.mergePhoneContactsWithRoster(); - this.getConversations(); - - getContentResolver().registerContentObserver( - ContactsContract.Contacts.CONTENT_URI, true, contactObserver); - this.fileObserver.startWatching(); - this.pgpServiceConnection = new OpenPgpServiceConnection( - getApplicationContext(), "org.sufficientlysecure.keychain"); - this.pgpServiceConnection.bindToService(); - - this.pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "XmppConnectionService"); - } - - @Override - public void onDestroy() { - super.onDestroy(); - this.logoutAndSave(); - } - - @Override - public void onTaskRemoved(Intent rootIntent) { - super.onTaskRemoved(rootIntent); - this.logoutAndSave(); - } - - private void logoutAndSave() { - for (Account account : accounts) { - databaseBackend.writeRoster(account.getRoster()); - if (account.getXmppConnection() != null) { - disconnect(account, false); - } - } - Context context = getApplicationContext(); - AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(context, EventReceiver.class); - alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); - Log.d(Config.LOGTAG, "good bye"); - stopSelf(); - } - - protected void scheduleWakeupCall(int seconds, boolean ping) { - long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000; - Context context = getApplicationContext(); - AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - - if (ping) { - if (this.pingIntent == null) { - this.pingIntent = new Intent(context, EventReceiver.class); - this.pingIntent.setAction("ping"); - this.pingIntent.putExtra("time", timeToWake); - this.pendingPingIntent = PendingIntent.getBroadcast(context, 0, - this.pingIntent, 0); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - timeToWake, pendingPingIntent); - } else { - long scheduledTime = this.pingIntent.getLongExtra("time", 0); - if (scheduledTime < SystemClock.elapsedRealtime() - || (scheduledTime > timeToWake)) { - this.pingIntent.putExtra("time", timeToWake); - alarmManager.cancel(this.pendingPingIntent); - this.pendingPingIntent = PendingIntent.getBroadcast( - context, 0, this.pingIntent, 0); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - timeToWake, pendingPingIntent); - } - } - } else { - Intent intent = new Intent(context, EventReceiver.class); - intent.setAction("ping_check"); - PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, - intent, 0); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, - alarmIntent); - } - - } - - public XmppConnection createConnection(Account account) { - SharedPreferences sharedPref = getPreferences(); - account.setResource(sharedPref.getString("resource", "mobile") - .toLowerCase(Locale.getDefault())); - XmppConnection connection = new XmppConnection(account, this); - connection.setOnMessagePacketReceivedListener(this.mMessageParser); - connection.setOnStatusChangedListener(this.statusListener); - connection.setOnPresencePacketReceivedListener(this.mPresenceParser); - connection.setOnUnregisteredIqPacketReceivedListener(this.mIqParser); - connection.setOnJinglePacketReceivedListener(this.jingleListener); - connection.setOnBindListener(this.mOnBindListener); - connection - .setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener); - return connection; - } - - public void sendMessage(Message message) { - Account account = message.getConversation().getAccount(); - account.deactivateGracePeriod(); - Conversation conv = message.getConversation(); - MessagePacket packet = null; - boolean saveInDb = true; - boolean send = false; - if (account.getStatus() == Account.STATUS_ONLINE - && account.getXmppConnection() != null) { - if (message.getType() == Message.TYPE_IMAGE) { - if (message.getPresence() != null) { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession() - && (message.getPresence() != null)) { - conv.startOtrSession(this, message.getPresence(), - true); - message.setStatus(Message.STATUS_WAITING); - } else if (conv.hasValidOtrSession() - && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - mJingleConnectionManager - .createNewConnection(message); - } else if (message.getPresence() == null) { - message.setStatus(Message.STATUS_WAITING); - } - } else { - mJingleConnectionManager.createNewConnection(message); - } - } else { - message.setStatus(Message.STATUS_WAITING); - } - } else { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession() - && (message.getPresence() != null)) { - conv.startOtrSession(this, message.getPresence(), true); - message.setStatus(Message.STATUS_WAITING); - } else if (conv.hasValidOtrSession() - && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - message.setPresence(conv.getOtrSession().getSessionID() - .getUserID()); - packet = mMessageGenerator.generateOtrChat(message); - send = true; - - } else if (message.getPresence() == null) { - message.setStatus(Message.STATUS_WAITING); - } - } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - message.getConversation().endOtrIfNeeded(); - failWaitingOtrMessages(message.getConversation()); - packet = mMessageGenerator.generatePgpChat(message); - send = true; - } else { - message.getConversation().endOtrIfNeeded(); - failWaitingOtrMessages(message.getConversation()); - packet = mMessageGenerator.generateChat(message); - send = true; - } - } - if (!account.getXmppConnection().getFeatures().sm() - && conv.getMode() != Conversation.MODE_MULTI) { - message.setStatus(Message.STATUS_SEND); - } - } else { - message.setStatus(Message.STATUS_WAITING); - if (message.getType() == Message.TYPE_TEXT) { - if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - String pgpBody = message.getEncryptedBody(); - String decryptedBody = message.getBody(); - message.setBody(pgpBody); - message.setEncryption(Message.ENCRYPTION_PGP); - databaseBackend.createMessage(message); - saveInDb = false; - message.setBody(decryptedBody); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - } else if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (conv.hasValidOtrSession()) { - message.setPresence(conv.getOtrSession().getSessionID() - .getUserID()); - } else if (!conv.hasValidOtrSession() - && message.getPresence() != null) { - conv.startOtrSession(this, message.getPresence(), false); - } - } - } - - } - conv.add(message); - if (saveInDb) { - if (message.getEncryption() == Message.ENCRYPTION_NONE - || saveEncryptedMessages()) { - databaseBackend.createMessage(message); - } - } - if ((send) && (packet != null)) { - sendMessagePacket(account, packet); - } - updateConversationUi(); - } - - private void sendUnsendMessages(Conversation conversation) { - for (int i = 0; i < conversation.getMessages().size(); ++i) { - int status = conversation.getMessages().get(i).getStatus(); - if (status == Message.STATUS_WAITING) { - resendMessage(conversation.getMessages().get(i)); - } - } - } - - private void resendMessage(Message message) { - Account account = message.getConversation().getAccount(); - MessagePacket packet = null; - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - Presences presences = message.getConversation().getContact() - .getPresences(); - if (!message.getConversation().hasValidOtrSession()) { - if ((message.getPresence() != null) - && (presences.has(message.getPresence()))) { - message.getConversation().startOtrSession(this, - message.getPresence(), true); - } else { - if (presences.size() == 1) { - String presence = presences.asStringArray()[0]; - message.getConversation().startOtrSession(this, - presence, true); - } - } - } else { - if (message.getConversation().getOtrSession() - .getSessionStatus() == SessionStatus.ENCRYPTED) { - if (message.getType() == Message.TYPE_TEXT) { - packet = mMessageGenerator.generateOtrChat(message, - true); - } else if (message.getType() == Message.TYPE_IMAGE) { - mJingleConnectionManager.createNewConnection(message); - } - } - } - } else if (message.getType() == Message.TYPE_TEXT) { - if (message.getEncryption() == Message.ENCRYPTION_NONE) { - packet = mMessageGenerator.generateChat(message, true); - } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED) - || (message.getEncryption() == Message.ENCRYPTION_PGP)) { - packet = mMessageGenerator.generatePgpChat(message, true); - } - } else if (message.getType() == Message.TYPE_IMAGE) { - Presences presences = message.getConversation().getContact() - .getPresences(); - if ((message.getPresence() != null) - && (presences.has(message.getPresence()))) { - markMessage(message, Message.STATUS_OFFERED); - mJingleConnectionManager.createNewConnection(message); - } else { - if (presences.size() == 1) { - String presence = presences.asStringArray()[0]; - message.setPresence(presence); - markMessage(message, Message.STATUS_OFFERED); - mJingleConnectionManager.createNewConnection(message); - } - } - } - if (packet != null) { - if (!account.getXmppConnection().getFeatures().sm() - && message.getConversation().getMode() != Conversation.MODE_MULTI) { - markMessage(message, Message.STATUS_SEND); - } else { - markMessage(message, Message.STATUS_UNSEND); - } - sendMessagePacket(account, packet); - } - } - - public void fetchRosterFromServer(Account account) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); - if (!"".equals(account.getRosterVersion())) { - Log.d(Config.LOGTAG, account.getJid() - + ": fetching roster version " + account.getRosterVersion()); - } else { - Log.d(Config.LOGTAG, account.getJid() + ": fetching roster"); - } - iqPacket.query("jabber:iq:roster").setAttribute("ver", - account.getRosterVersion()); - account.getXmppConnection().sendIqPacket(iqPacket, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(final Account account, - IqPacket packet) { - Element query = packet.findChild("query"); - if (query != null) { - account.getRoster().markAllAsNotInRoster(); - mIqParser.rosterItems(account, query); - } - } - }); - } - - public void fetchBookmarks(Account account) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); - Element query = iqPacket.query("jabber:iq:private"); - query.addChild("storage", "storage:bookmarks"); - OnIqPacketReceived callback = new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - Element query = packet.query(); - List bookmarks = new CopyOnWriteArrayList(); - Element storage = query.findChild("storage", - "storage:bookmarks"); - if (storage != null) { - for (Element item : storage.getChildren()) { - if (item.getName().equals("conference")) { - Bookmark bookmark = Bookmark.parse(item, account); - bookmarks.add(bookmark); - Conversation conversation = find(bookmark); - if (conversation != null) { - conversation.setBookmark(bookmark); - } else { - if (bookmark.autojoin()) { - conversation = findOrCreateConversation( - account, bookmark.getJid(), true); - conversation.setBookmark(bookmark); - joinMuc(conversation); - } - } - } - } - } - account.setBookmarks(bookmarks); - } - }; - sendIqPacket(account, iqPacket, callback); - - } - - public void pushBookmarks(Account account) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_SET); - Element query = iqPacket.query("jabber:iq:private"); - Element storage = query.addChild("storage", "storage:bookmarks"); - for (Bookmark bookmark : account.getBookmarks()) { - storage.addChild(bookmark); - } - sendIqPacket(account, iqPacket, null); - } - - private void mergePhoneContactsWithRoster() { - PhoneHelper.loadPhoneContacts(getApplicationContext(), - new OnPhoneContactsLoadedListener() { - @Override - public void onPhoneContactsLoaded(List phoneContacts) { - for (Account account : accounts) { - account.getRoster().clearSystemAccounts(); - } - for (Bundle phoneContact : phoneContacts) { - for (Account account : accounts) { - String jid = phoneContact.getString("jid"); - Contact contact = account.getRoster() - .getContact(jid); - String systemAccount = phoneContact - .getInt("phoneid") - + "#" - + phoneContact.getString("lookup"); - contact.setSystemAccount(systemAccount); - contact.setPhotoUri(phoneContact - .getString("photouri")); - contact.setSystemName(phoneContact - .getString("displayname")); - getAvatarService().clear(contact); - } - } - } - }); - } - - public List getConversations() { - if (this.conversations == null) { - Hashtable accountLookupTable = new Hashtable(); - for (Account account : this.accounts) { - accountLookupTable.put(account.getUuid(), account); - } - this.conversations = databaseBackend - .getConversations(Conversation.STATUS_AVAILABLE); - for (Conversation conv : this.conversations) { - Account account = accountLookupTable.get(conv.getAccountUuid()); - conv.setAccount(account); - conv.setMessages(databaseBackend.getMessages(conv, 50)); - checkDeletedFiles(conv); - } - } - return this.conversations; - } - - private void checkDeletedFiles(Conversation conversation) { - for (Message message : conversation.getMessages()) { - if (message.getType() == Message.TYPE_IMAGE - && message.getEncryption() != Message.ENCRYPTION_PGP) { - if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DeletedDownloadable()); - } - } - } - } - - private void markFileDeleted(String uuid) { - for (Conversation conversation : getConversations()) { - for (Message message : conversation.getMessages()) { - if (message.getType() == Message.TYPE_IMAGE - && message.getEncryption() != Message.ENCRYPTION_PGP - && message.getUuid().equals(uuid)) { - if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DeletedDownloadable()); - updateConversationUi(); - } - return; - } - } - } - } - - public void populateWithOrderedConversations(List list) { - populateWithOrderedConversations(list, true); - } - - public void populateWithOrderedConversations(List list, - boolean includeConferences) { - list.clear(); - if (includeConferences) { - list.addAll(getConversations()); - } else { - for (Conversation conversation : getConversations()) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { - list.add(conversation); - } - } - } - Collections.sort(list, new Comparator() { - @Override - public int compare(Conversation lhs, Conversation rhs) { - Message left = lhs.getLatestMessage(); - Message right = rhs.getLatestMessage(); - if (left.getTimeSent() > right.getTimeSent()) { - return -1; - } else if (left.getTimeSent() < right.getTimeSent()) { - return 1; - } else { - return 0; - } - } - }); - } - - public int loadMoreMessages(Conversation conversation, long timestamp) { - List messages = databaseBackend.getMessages(conversation, 50, - timestamp); - for (Message message : messages) { - message.setConversation(conversation); - } - conversation.addAll(0, messages); - return messages.size(); - } - - public List getAccounts() { - return this.accounts; - } - - public Conversation find(List haystack, Contact contact) { - for (Conversation conversation : haystack) { - if (conversation.getContact() == contact) { - return conversation; - } - } - return null; - } - - public Conversation find(List haystack, Account account, - String jid) { - for (Conversation conversation : haystack) { - if ((account == null || conversation.getAccount().equals(account)) - && (conversation.getContactJid().split("/", 2)[0] - .equals(jid))) { - return conversation; - } - } - return null; - } - - public Conversation findOrCreateConversation(Account account, String jid, - boolean muc) { - Conversation conversation = find(account, jid); - if (conversation != null) { - return conversation; - } - conversation = databaseBackend.findConversation(account, jid); - if (conversation != null) { - conversation.setStatus(Conversation.STATUS_AVAILABLE); - conversation.setAccount(account); - if (muc) { - conversation.setMode(Conversation.MODE_MULTI); - } else { - conversation.setMode(Conversation.MODE_SINGLE); - } - conversation.setMessages(databaseBackend.getMessages(conversation, - 50)); - this.databaseBackend.updateConversation(conversation); - } else { - String conversationName; - Contact contact = account.getRoster().getContact(jid); - if (contact != null) { - conversationName = contact.getDisplayName(); - } else { - conversationName = jid.split("@")[0]; - } - if (muc) { - conversation = new Conversation(conversationName, account, jid, - Conversation.MODE_MULTI); - } else { - conversation = new Conversation(conversationName, account, jid, - Conversation.MODE_SINGLE); - } - this.databaseBackend.createConversation(conversation); - } - this.conversations.add(conversation); - updateConversationUi(); - return conversation; - } - - public void archiveConversation(Conversation conversation) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { - Bookmark bookmark = conversation.getBookmark(); - if (bookmark != null && bookmark.autojoin()) { - bookmark.setAutojoin(false); - pushBookmarks(bookmark.getAccount()); - } - } - leaveMuc(conversation); - } else { - conversation.endOtrIfNeeded(); - } - this.databaseBackend.updateConversation(conversation); - this.conversations.remove(conversation); - updateConversationUi(); - } - - public void clearConversationHistory(Conversation conversation) { - this.databaseBackend.deleteMessagesInConversation(conversation); - this.fileBackend.removeFiles(conversation); - conversation.getMessages().clear(); - updateConversationUi(); - } - - public int getConversationCount() { - return this.databaseBackend.getConversationCount(); - } - - public void createAccount(Account account) { - databaseBackend.createAccount(account); - this.accounts.add(account); - this.reconnectAccount(account, false); - updateAccountUi(); - } - - public void updateAccount(Account account) { - this.statusListener.onStatusChanged(account); - databaseBackend.updateAccount(account); - reconnectAccount(account, false); - updateAccountUi(); - UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); - } - - public void deleteAccount(Account account) { - for (Conversation conversation : conversations) { - if (conversation.getAccount() == account) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - leaveMuc(conversation); - } else if (conversation.getMode() == Conversation.MODE_SINGLE) { - conversation.endOtrIfNeeded(); - } - conversations.remove(conversation); - } - } - if (account.getXmppConnection() != null) { - this.disconnect(account, true); - } - databaseBackend.deleteAccount(account); - this.accounts.remove(account); - updateAccountUi(); - UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); - } - - public void setOnConversationListChangedListener( - OnConversationUpdate listener) { - if (!isScreenOn()) { - Log.d(Config.LOGTAG, - "ignoring setOnConversationListChangedListener"); - return; - } - synchronized (this.convChangedListenerCount) { - if (checkListeners()) { - switchToForeground(); - } - this.mOnConversationUpdate = listener; - this.mNotificationService.setIsInForeground(true); - this.convChangedListenerCount++; - } - } - - public void removeOnConversationListChangedListener() { - synchronized (this.convChangedListenerCount) { - this.convChangedListenerCount--; - if (this.convChangedListenerCount <= 0) { - this.convChangedListenerCount = 0; - this.mOnConversationUpdate = null; - this.mNotificationService.setIsInForeground(false); - if (checkListeners()) { - switchToBackground(); - } - } - } - } - - public void setOnAccountListChangedListener(OnAccountUpdate listener) { - if (!isScreenOn()) { - Log.d(Config.LOGTAG, "ignoring setOnAccountListChangedListener"); - return; - } - synchronized (this.accountChangedListenerCount) { - if (checkListeners()) { - switchToForeground(); - } - this.mOnAccountUpdate = listener; - this.accountChangedListenerCount++; - } - } - - public void removeOnAccountListChangedListener() { - synchronized (this.accountChangedListenerCount) { - this.accountChangedListenerCount--; - if (this.accountChangedListenerCount <= 0) { - this.mOnAccountUpdate = null; - this.accountChangedListenerCount = 0; - if (checkListeners()) { - switchToBackground(); - } - } - } - } - - public void setOnRosterUpdateListener(OnRosterUpdate listener) { - if (!isScreenOn()) { - Log.d(Config.LOGTAG, "ignoring setOnRosterUpdateListener"); - return; - } - synchronized (this.rosterChangedListenerCount) { - if (checkListeners()) { - switchToForeground(); - } - this.mOnRosterUpdate = listener; - this.rosterChangedListenerCount++; - } - } - - public void removeOnRosterUpdateListener() { - synchronized (this.rosterChangedListenerCount) { - this.rosterChangedListenerCount--; - if (this.rosterChangedListenerCount <= 0) { - this.rosterChangedListenerCount = 0; - this.mOnRosterUpdate = null; - if (checkListeners()) { - switchToBackground(); - } - } - } - } - - private boolean checkListeners() { - return (this.mOnAccountUpdate == null - && this.mOnConversationUpdate == null && this.mOnRosterUpdate == null); - } - - private void switchToForeground() { - for (Account account : getAccounts()) { - if (account.getStatus() == Account.STATUS_ONLINE) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null && connection.getFeatures().csi()) { - connection.sendActive(); - } - } - } - Log.d(Config.LOGTAG, "app switched into foreground"); - } - - private void switchToBackground() { - for (Account account : getAccounts()) { - if (account.getStatus() == Account.STATUS_ONLINE) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null && connection.getFeatures().csi()) { - connection.sendInactive(); - } - } - } - this.mNotificationService.setIsInForeground(false); - Log.d(Config.LOGTAG, "app switched into background"); - } - - private boolean isScreenOn() { - PowerManager pm = (PowerManager) this - .getSystemService(Context.POWER_SERVICE); - return pm.isScreenOn(); - } - - public void connectMultiModeConversations(Account account) { - List conversations = getConversations(); - for (int i = 0; i < conversations.size(); i++) { - Conversation conversation = conversations.get(i); - if ((conversation.getMode() == Conversation.MODE_MULTI) - && (conversation.getAccount() == account)) { - joinMuc(conversation); - } - } - } - - public void joinMuc(Conversation conversation) { - Account account = conversation.getAccount(); - account.pendingConferenceJoins.remove(conversation); - account.pendingConferenceLeaves.remove(conversation); - if (account.getStatus() == Account.STATUS_ONLINE) { - Log.d(Config.LOGTAG, - "joining conversation " + conversation.getContactJid()); - String nick = conversation.getMucOptions().getProposedNick(); - conversation.getMucOptions().setJoinNick(nick); - PresencePacket packet = new PresencePacket(); - String joinJid = conversation.getMucOptions().getJoinJid(); - packet.setAttribute("to", conversation.getMucOptions().getJoinJid()); - Element x = new Element("x"); - x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); - if (conversation.getMucOptions().getPassword() != null) { - Element password = x.addChild("password"); - password.setContent(conversation.getMucOptions().getPassword()); - } - String sig = account.getPgpSignature(); - if (sig != null) { - packet.addChild("status").setContent("online"); - packet.addChild("x", "jabber:x:signed").setContent(sig); - } - if (conversation.getMessages().size() != 0) { - final SimpleDateFormat mDateFormat = new SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); - mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - Date date = new Date(conversation.getLatestMessage() - .getTimeSent() + 1000); - x.addChild("history").setAttribute("since", - mDateFormat.format(date)); - } - packet.addChild(x); - sendPresencePacket(account, packet); - if (!joinJid.equals(conversation.getContactJid())) { - conversation.setContactJid(joinJid); - databaseBackend.updateConversation(conversation); - } - } else { - account.pendingConferenceJoins.add(conversation); - } - } - - private OnRenameListener renameListener = null; - private IqGenerator mIqGenerator = new IqGenerator(this); - - public void setOnRenameListener(OnRenameListener listener) { - this.renameListener = listener; - } - - public void providePasswordForMuc(Conversation conversation, String password) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - conversation.getMucOptions().setPassword(password); - if (conversation.getBookmark() != null) { - conversation.getBookmark().setAutojoin(true); - pushBookmarks(conversation.getAccount()); - } - databaseBackend.updateConversation(conversation); - joinMuc(conversation); - } - } - - public void renameInMuc(final Conversation conversation, final String nick) { - final MucOptions options = conversation.getMucOptions(); - options.setJoinNick(nick); - if (options.online()) { - Account account = conversation.getAccount(); - options.setOnRenameListener(new OnRenameListener() { - - @Override - public void onRename(boolean success) { - if (renameListener != null) { - renameListener.onRename(success); - } - if (success) { - conversation.setContactJid(conversation.getMucOptions() - .getJoinJid()); - databaseBackend.updateConversation(conversation); - Bookmark bookmark = conversation.getBookmark(); - if (bookmark != null) { - bookmark.setNick(nick); - pushBookmarks(bookmark.getAccount()); - } - } - } - }); - options.flagAboutToRename(); - PresencePacket packet = new PresencePacket(); - packet.setAttribute("to", options.getJoinJid()); - packet.setAttribute("from", conversation.getAccount().getFullJid()); - - String sig = account.getPgpSignature(); - if (sig != null) { - packet.addChild("status").setContent("online"); - packet.addChild("x", "jabber:x:signed").setContent(sig); - } - sendPresencePacket(account, packet); - } else { - conversation.setContactJid(options.getJoinJid()); - databaseBackend.updateConversation(conversation); - if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { - Bookmark bookmark = conversation.getBookmark(); - if (bookmark != null) { - bookmark.setNick(nick); - pushBookmarks(bookmark.getAccount()); - } - joinMuc(conversation); - } - } - } - - public void leaveMuc(Conversation conversation) { - Account account = conversation.getAccount(); - account.pendingConferenceJoins.remove(conversation); - account.pendingConferenceLeaves.remove(conversation); - if (account.getStatus() == Account.STATUS_ONLINE) { - PresencePacket packet = new PresencePacket(); - packet.setAttribute("to", conversation.getMucOptions().getJoinJid()); - packet.setAttribute("from", conversation.getAccount().getFullJid()); - packet.setAttribute("type", "unavailable"); - sendPresencePacket(conversation.getAccount(), packet); - conversation.getMucOptions().setOffline(); - conversation.deregisterWithBookmark(); - Log.d(Config.LOGTAG, conversation.getAccount().getJid() - + ": leaving muc " + conversation.getContactJid()); - } else { - account.pendingConferenceLeaves.add(conversation); - } - } - - public void disconnect(Account account, boolean force) { - if ((account.getStatus() == Account.STATUS_ONLINE) - || (account.getStatus() == Account.STATUS_DISABLED)) { - if (!force) { - List conversations = getConversations(); - for (int i = 0; i < conversations.size(); i++) { - Conversation conversation = conversations.get(i); - if (conversation.getAccount() == account) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - leaveMuc(conversation); - } else { - if (conversation.endOtrIfNeeded()) { - Log.d(Config.LOGTAG, account.getJid() - + ": ended otr session with " - + conversation.getContactJid()); - } - } - } - } - } - account.getXmppConnection().disconnect(force); - } - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - public void updateMessage(Message message) { - databaseBackend.updateMessage(message); - updateConversationUi(); - } - - protected void syncDirtyContacts(Account account) { - for (Contact contact : account.getRoster().getContacts()) { - if (contact.getOption(Contact.Options.DIRTY_PUSH)) { - pushContactToServer(contact); - } - if (contact.getOption(Contact.Options.DIRTY_DELETE)) { - deleteContactOnServer(contact); - } - } - } - - public void createContact(Contact contact) { - SharedPreferences sharedPref = getPreferences(); - boolean autoGrant = sharedPref.getBoolean("grant_new_contacts", true); - if (autoGrant) { - contact.setOption(Contact.Options.PREEMPTIVE_GRANT); - contact.setOption(Contact.Options.ASKING); - } - pushContactToServer(contact); - } - - public void onOtrSessionEstablished(Conversation conversation) { - Account account = conversation.getAccount(); - List messages = conversation.getMessages(); - Session otrSession = conversation.getOtrSession(); - Log.d(Config.LOGTAG, - account.getJid() + " otr session established with " - + conversation.getContactJid() + "/" - + otrSession.getSessionID().getUserID()); - for (int i = 0; i < messages.size(); ++i) { - Message msg = messages.get(i); - if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING) - && (msg.getEncryption() == Message.ENCRYPTION_OTR)) { - msg.setPresence(otrSession.getSessionID().getUserID()); - if (msg.getType() == Message.TYPE_TEXT) { - MessagePacket outPacket = mMessageGenerator - .generateOtrChat(msg, true); - if (outPacket != null) { - msg.setStatus(Message.STATUS_SEND); - databaseBackend.updateMessage(msg); - sendMessagePacket(account, outPacket); - } - } else if (msg.getType() == Message.TYPE_IMAGE) { - mJingleConnectionManager.createNewConnection(msg); - } - } - } - updateConversationUi(); - } - - public boolean renewSymmetricKey(Conversation conversation) { - Account account = conversation.getAccount(); - byte[] symmetricKey = new byte[32]; - this.mRandom.nextBytes(symmetricKey); - Session otrSession = conversation.getOtrSession(); - if (otrSession != null) { - MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_CHAT); - packet.setFrom(account.getFullJid()); - packet.addChild("private", "urn:xmpp:carbons:2"); - packet.addChild("no-copy", "urn:xmpp:hints"); - packet.setTo(otrSession.getSessionID().getAccountID() + "/" - + otrSession.getSessionID().getUserID()); - try { - packet.setBody(otrSession - .transformSending(CryptoHelper.FILETRANSFER - + CryptoHelper.bytesToHex(symmetricKey))); - sendMessagePacket(account, packet); - conversation.setSymmetricKey(symmetricKey); - return true; - } catch (OtrException e) { - return false; - } - } - return false; - } - - public void pushContactToServer(Contact contact) { - contact.resetOption(Contact.Options.DIRTY_DELETE); - contact.setOption(Contact.Options.DIRTY_PUSH); - Account account = contact.getAccount(); - if (account.getStatus() == Account.STATUS_ONLINE) { - boolean ask = contact.getOption(Contact.Options.ASKING); - boolean sendUpdates = contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST) - && contact.getOption(Contact.Options.PREEMPTIVE_GRANT); - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - iq.query("jabber:iq:roster").addChild(contact.asElement()); - account.getXmppConnection().sendIqPacket(iq, null); - if (sendUpdates) { - sendPresencePacket(account, - mPresenceGenerator.sendPresenceUpdatesTo(contact)); - } - if (ask) { - sendPresencePacket(account, - mPresenceGenerator.requestPresenceUpdatesFrom(contact)); - } - } - } - - public void publishAvatar(Account account, Uri image, - final UiCallback callback) { - final Bitmap.CompressFormat format = Config.AVATAR_FORMAT; - final int size = Config.AVATAR_SIZE; - final Avatar avatar = getFileBackend() - .getPepAvatar(image, size, format); - if (avatar != null) { - avatar.height = size; - avatar.width = size; - if (format.equals(Bitmap.CompressFormat.WEBP)) { - avatar.type = "image/webp"; - } else if (format.equals(Bitmap.CompressFormat.JPEG)) { - avatar.type = "image/jpeg"; - } else if (format.equals(Bitmap.CompressFormat.PNG)) { - avatar.type = "image/png"; - } - if (!getFileBackend().save(avatar)) { - callback.error(R.string.error_saving_avatar, avatar); - return; - } - IqPacket packet = this.mIqGenerator.publishAvatar(avatar); - this.sendIqPacket(account, packet, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket result) { - if (result.getType() == IqPacket.TYPE_RESULT) { - IqPacket packet = XmppConnectionService.this.mIqGenerator - .publishAvatarMetadata(avatar); - sendIqPacket(account, packet, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket result) { - if (result.getType() == IqPacket.TYPE_RESULT) { - if (account.setAvatar(avatar.getFilename())) { - databaseBackend.updateAccount(account); - } - callback.success(avatar); - } else { - callback.error( - R.string.error_publish_avatar_server_reject, - avatar); - } - } - }); - } else { - callback.error( - R.string.error_publish_avatar_server_reject, - avatar); - } - } - }); - } else { - callback.error(R.string.error_publish_avatar_converting, null); - } - } - - public void fetchAvatar(Account account, Avatar avatar) { - fetchAvatar(account, avatar, null); - } - - public void fetchAvatar(Account account, final Avatar avatar, - final UiCallback callback) { - IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar); - sendIqPacket(account, packet, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket result) { - final String ERROR = account.getJid() - + ": fetching avatar for " + avatar.owner + " failed "; - if (result.getType() == IqPacket.TYPE_RESULT) { - avatar.image = mIqParser.avatarData(result); - if (avatar.image != null) { - if (getFileBackend().save(avatar)) { - if (account.getJid().equals(avatar.owner)) { - if (account.setAvatar(avatar.getFilename())) { - databaseBackend.updateAccount(account); - } - getAvatarService().clear(account); - updateConversationUi(); - updateAccountUi(); - } else { - Contact contact = account.getRoster() - .getContact(avatar.owner); - contact.setAvatar(avatar.getFilename()); - getAvatarService().clear(contact); - updateConversationUi(); - updateRosterUi(); - } - if (callback != null) { - callback.success(avatar); - } - Log.d(Config.LOGTAG, account.getJid() - + ": succesfully fetched avatar for " - + avatar.owner); - return; - } - } else { - - Log.d(Config.LOGTAG, ERROR + "(parsing error)"); - } - } else { - Element error = result.findChild("error"); - if (error == null) { - Log.d(Config.LOGTAG, ERROR + "(server error)"); - } else { - Log.d(Config.LOGTAG, ERROR + error.toString()); - } - } - if (callback != null) { - callback.error(0, null); - } - - } - }); - } - - public void checkForAvatar(Account account, - final UiCallback callback) { - IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); - this.sendIqPacket(account, packet, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { - Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); - if (pubsub != null) { - Element items = pubsub.findChild("items"); - if (items != null) { - Avatar avatar = Avatar.parseMetadata(items); - if (avatar != null) { - avatar.owner = account.getJid(); - if (fileBackend.isAvatarCached(avatar)) { - if (account.setAvatar(avatar.getFilename())) { - databaseBackend.updateAccount(account); - } - getAvatarService().clear(account); - callback.success(avatar); - } else { - fetchAvatar(account, avatar, callback); - } - return; - } - } - } - } - callback.error(0, null); - } - }); - } - - public void deleteContactOnServer(Contact contact) { - contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); - contact.resetOption(Contact.Options.DIRTY_PUSH); - contact.setOption(Contact.Options.DIRTY_DELETE); - Account account = contact.getAccount(); - if (account.getStatus() == Account.STATUS_ONLINE) { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - Element item = iq.query("jabber:iq:roster").addChild("item"); - item.setAttribute("jid", contact.getJid()); - item.setAttribute("subscription", "remove"); - account.getXmppConnection().sendIqPacket(iq, null); - } - } - - public void updateConversation(Conversation conversation) { - this.databaseBackend.updateConversation(conversation); - } - - public void reconnectAccount(final Account account, final boolean force) { - new Thread(new Runnable() { - - @Override - public void run() { - if (account.getXmppConnection() != null) { - disconnect(account, force); - } - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - if (account.getXmppConnection() == null) { - account.setXmppConnection(createConnection(account)); - } - Thread thread = new Thread(account.getXmppConnection()); - thread.start(); - scheduleWakeupCall((int) (Config.CONNECT_TIMEOUT * 1.2), - false); - } else { - account.getRoster().clearPresences(); - account.setXmppConnection(null); - } - } - }).start(); - } - - public void invite(Conversation conversation, String contact) { - MessagePacket packet = mMessageGenerator.invite(conversation, contact); - sendMessagePacket(conversation.getAccount(), packet); - } - - public void resetSendingToWaiting(Account account) { - for (Conversation conversation : getConversations()) { - if (conversation.getAccount() == account) { - for (Message message : conversation.getMessages()) { - if (message.getType() != Message.TYPE_IMAGE - && message.getStatus() == Message.STATUS_UNSEND) { - markMessage(message, Message.STATUS_WAITING); - } - } - } - } - } - - public boolean markMessage(Account account, String recipient, String uuid, - int status) { - if (uuid == null) { - return false; - } else { - for (Conversation conversation : getConversations()) { - if (conversation.getContactJid().equals(recipient) - && conversation.getAccount().equals(account)) { - return markMessage(conversation, uuid, status); - } - } - return false; - } - } - - public boolean markMessage(Conversation conversation, String uuid, - int status) { - if (uuid == null) { - return false; - } else { - for (Message message : conversation.getMessages()) { - if (uuid.equals(message.getUuid()) - || (message.getStatus() >= Message.STATUS_SEND && uuid - .equals(message.getRemoteMsgId()))) { - markMessage(message, status); - return true; - } - } - return false; - } - } - - public void markMessage(Message message, int status) { - if (status == Message.STATUS_SEND_FAILED - && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message - .getStatus() == Message.STATUS_SEND_DISPLAYED)) { - return; - } - message.setStatus(status); - databaseBackend.updateMessage(message); - updateConversationUi(); - } - - public SharedPreferences getPreferences() { - return PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - } - - public boolean forceEncryption() { - return getPreferences().getBoolean("force_encryption", false); - } - - public boolean confirmMessages() { - return getPreferences().getBoolean("confirm_messages", true); - } - - public boolean saveEncryptedMessages() { - return !getPreferences().getBoolean("dont_save_encrypted", false); - } - - public boolean indicateReceived() { - return getPreferences().getBoolean("indicate_received", false); - } - - public void updateConversationUi() { - if (mOnConversationUpdate != null) { - mOnConversationUpdate.onConversationUpdate(); - } - } - - public void updateAccountUi() { - if (mOnAccountUpdate != null) { - mOnAccountUpdate.onAccountUpdate(); - } - } - - public void updateRosterUi() { - if (mOnRosterUpdate != null) { - mOnRosterUpdate.onRosterUpdate(); - } - } - - public Account findAccountByJid(String accountJid) { - for (Account account : this.accounts) { - if (account.getJid().equals(accountJid)) { - return account; - } - } - return null; - } - - public Conversation findConversationByUuid(String uuid) { - for (Conversation conversation : getConversations()) { - if (conversation.getUuid().equals(uuid)) { - return conversation; - } - } - return null; - } - - public void markRead(Conversation conversation, boolean calledByUi) { - mNotificationService.clear(conversation); - String id = conversation.getLatestMarkableMessageId(); - conversation.markRead(); - if (confirmMessages() && id != null && calledByUi) { - Log.d(Config.LOGTAG, conversation.getAccount().getJid() - + ": sending read marker for " + conversation.getName()); - Account account = conversation.getAccount(); - String to = conversation.getContactJid(); - this.sendMessagePacket(conversation.getAccount(), - mMessageGenerator.confirm(account, to, id)); - } - if (!calledByUi) { - updateConversationUi(); - } - } - - public void failWaitingOtrMessages(Conversation conversation) { - for (Message message : conversation.getMessages()) { - if (message.getEncryption() == Message.ENCRYPTION_OTR - && message.getStatus() == Message.STATUS_WAITING) { - markMessage(message, Message.STATUS_SEND_FAILED); - } - } - } - - public SecureRandom getRNG() { - return this.mRandom; - } - - public MemorizingTrustManager getMemorizingTrustManager() { - return this.mMemorizingTrustManager; - } - - public PowerManager getPowerManager() { - return this.pm; - } - - public LruCache getBitmapCache() { - return this.mBitmapCache; - } - - public void replyWithNotAcceptable(Account account, MessagePacket packet) { - if (account.getStatus() == Account.STATUS_ONLINE) { - MessagePacket error = this.mMessageGenerator - .generateNotAcceptable(packet); - sendMessagePacket(account, error); - } - } - - public void syncRosterToDisk(final Account account) { - new Thread(new Runnable() { - - @Override - public void run() { - databaseBackend.writeRoster(account.getRoster()); - } - }).start(); - - } - - public List getKnownHosts() { - List hosts = new ArrayList(); - for (Account account : getAccounts()) { - if (!hosts.contains(account.getServer())) { - hosts.add(account.getServer()); - } - for (Contact contact : account.getRoster().getContacts()) { - if (contact.showInRoster()) { - String server = contact.getServer(); - if (server != null && !hosts.contains(server)) { - hosts.add(server); - } - } - } - } - return hosts; - } - - public List getKnownConferenceHosts() { - ArrayList mucServers = new ArrayList(); - for (Account account : accounts) { - if (account.getXmppConnection() != null) { - String server = account.getXmppConnection().getMucServer(); - if (server != null && !mucServers.contains(server)) { - mucServers.add(server); - } - } - } - return mucServers; - } - - public void sendMessagePacket(Account account, MessagePacket packet) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.sendMessagePacket(packet); - } - } - - public void sendPresencePacket(Account account, PresencePacket packet) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.sendPresencePacket(packet); - } - } - - public void sendIqPacket(Account account, IqPacket packet, - OnIqPacketReceived callback) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.sendIqPacket(packet, callback); - } - } - - public MessageGenerator getMessageGenerator() { - return this.mMessageGenerator; - } - - public PresenceGenerator getPresenceGenerator() { - return this.mPresenceGenerator; - } - - public IqGenerator getIqGenerator() { - return this.mIqGenerator; - } - - public JingleConnectionManager getJingleConnectionManager() { - return this.mJingleConnectionManager; - } - - public interface OnConversationUpdate { - public void onConversationUpdate(); - } - - public interface OnAccountUpdate { - public void onAccountUpdate(); - } - - public interface OnRosterUpdate { - public void onRosterUpdate(); - } - - public List findContacts(String jid) { - ArrayList contacts = new ArrayList(); - for (Account account : getAccounts()) { - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - Contact contact = account.getRoster().getContactFromRoster(jid); - if (contact != null) { - contacts.add(contact); - } - } - } - return contacts; - } - - public NotificationService getNotificationService() { - return this.mNotificationService; - } - - public HttpConnectionManager getHttpConnectionManager() { - return this.mHttpConnectionManager; - } - - private class DeletedDownloadable implements Downloadable { - - @Override - public boolean start() { - return false; - } - - @Override - public int getStatus() { - return Downloadable.STATUS_DELETED; - } - - @Override - public long getFileSize() { - return 0; - } - - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java deleted file mode 100644 index 62a2cbe1..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java +++ /dev/null @@ -1,145 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.Collections; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ListView; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.ListItem; -import eu.siacs.conversations.ui.adapter.ListItemAdapter; - -public class ChooseContactActivity extends XmppActivity { - - private ListView mListView; - private ArrayList contacts = new ArrayList(); - private ArrayAdapter mContactsAdapter; - - private EditText mSearchEditText; - - private TextWatcher mSearchTextWatcher = new TextWatcher() { - - @Override - public void afterTextChanged(Editable editable) { - filterContacts(editable.toString()); - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - } - }; - - private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() { - - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - mSearchEditText.post(new Runnable() { - - @Override - public void run() { - mSearchEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mSearchEditText, - InputMethodManager.SHOW_IMPLICIT); - } - }); - - return true; - } - - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), - InputMethodManager.HIDE_IMPLICIT_ONLY); - mSearchEditText.setText(""); - filterContacts(null); - return true; - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_choose_contact); - mListView = (ListView) findViewById(R.id.choose_contact_list); - mListView.setFastScrollEnabled(true); - mContactsAdapter = new ListItemAdapter(this, contacts); - mListView.setAdapter(mContactsAdapter); - mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View arg1, - int position, long arg3) { - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), - InputMethodManager.HIDE_IMPLICIT_ONLY); - Intent request = getIntent(); - Intent data = new Intent(); - ListItem mListItem = contacts.get(position); - data.putExtra("contact", mListItem.getJid()); - String account = request.getStringExtra("account"); - if (account == null && mListItem instanceof Contact) { - account = ((Contact) mListItem).getAccount().getJid(); - } - data.putExtra("account", account); - data.putExtra("conversation", - request.getStringExtra("conversation")); - setResult(RESULT_OK, data); - finish(); - } - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.choose_contact, menu); - MenuItem menuSearchView = (MenuItem) menu.findItem(R.id.action_search); - View mSearchView = menuSearchView.getActionView(); - mSearchEditText = (EditText) mSearchView - .findViewById(R.id.search_field); - mSearchEditText.addTextChangedListener(mSearchTextWatcher); - menuSearchView.setOnActionExpandListener(mOnActionExpandListener); - return true; - } - - @Override - void onBackendConnected() { - filterContacts(null); - } - - protected void filterContacts(String needle) { - this.contacts.clear(); - for (Account account : xmppConnectionService.getAccounts()) { - if (account.getStatus() != Account.STATUS_DISABLED) { - for (Contact contact : account.getRoster().getContacts()) { - if (contact.showInRoster() && contact.match(needle)) { - this.contacts.add(contact); - } - } - } - } - Collections.sort(this.contacts); - mContactsAdapter.notifyDataSetChanged(); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java deleted file mode 100644 index 6b4642cb..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ /dev/null @@ -1,280 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.List; - -import org.openintents.openpgp.util.OpenPgpUtils; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.entities.MucOptions.OnRenameListener; -import eu.siacs.conversations.entities.MucOptions.User; -import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; -import android.app.PendingIntent; -import android.content.Context; -import android.content.IntentSender.SendIntentException; -import android.graphics.Bitmap; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -public class ConferenceDetailsActivity extends XmppActivity { - public static final String ACTION_VIEW_MUC = "view_muc"; - private Conversation conversation; - private TextView mYourNick; - private ImageView mYourPhoto; - private ImageButton mEditNickButton; - private TextView mRoleAffiliaton; - private TextView mFullJid; - private TextView mAccountJid; - private LinearLayout membersView; - private LinearLayout mMoreDetails; - private Button mInviteButton; - private String uuid = null; - - private OnClickListener inviteListener = new OnClickListener() { - - @Override - public void onClick(View v) { - inviteToConversation(conversation); - } - }; - - private List users = new ArrayList(); - private OnConversationUpdate onConvChanged = new OnConversationUpdate() { - - @Override - public void onConversationUpdate() { - runOnUiThread(new Runnable() { - - @Override - public void run() { - populateView(); - } - }); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_muc_details); - mYourNick = (TextView) findViewById(R.id.muc_your_nick); - mYourPhoto = (ImageView) findViewById(R.id.your_photo); - mEditNickButton = (ImageButton) findViewById(R.id.edit_nick_button); - mFullJid = (TextView) findViewById(R.id.muc_jabberid); - membersView = (LinearLayout) findViewById(R.id.muc_members); - mAccountJid = (TextView) findViewById(R.id.details_account); - mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details); - mMoreDetails.setVisibility(View.GONE); - mInviteButton = (Button) findViewById(R.id.invite); - mInviteButton.setOnClickListener(inviteListener); - getActionBar().setHomeButtonEnabled(true); - getActionBar().setDisplayHomeAsUpEnabled(true); - mEditNickButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - quickEdit(conversation.getMucOptions().getActualNick(), - new OnValueEdited() { - - @Override - public void onValueEdited(String value) { - xmppConnectionService.renameInMuc(conversation, - value); - } - }); - } - }); - } - - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - switch (menuItem.getItemId()) { - case android.R.id.home: - finish(); - break; - case R.id.action_edit_subject: - if (conversation != null) { - quickEdit(conversation.getName(), new OnValueEdited() { - - @Override - public void onValueEdited(String value) { - MessagePacket packet = xmppConnectionService - .getMessageGenerator().conferenceSubject( - conversation, value); - xmppConnectionService.sendMessagePacket( - conversation.getAccount(), packet); - } - }); - } - break; - } - return super.onOptionsItemSelected(menuItem); - } - - public String getReadableRole(int role) { - switch (role) { - case User.ROLE_MODERATOR: - return getString(R.string.moderator); - case User.ROLE_PARTICIPANT: - return getString(R.string.participant); - case User.ROLE_VISITOR: - return getString(R.string.visitor); - default: - return ""; - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.muc_details, menu); - return true; - } - - @Override - void onBackendConnected() { - registerListener(); - if (getIntent().getAction().equals(ACTION_VIEW_MUC)) { - this.uuid = getIntent().getExtras().getString("uuid"); - } - if (uuid != null) { - this.conversation = xmppConnectionService - .findConversationByUuid(uuid); - if (this.conversation != null) { - populateView(); - } - } - } - - @Override - protected void onStop() { - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnConversationListChangedListener(); - } - super.onStop(); - } - - protected void registerListener() { - xmppConnectionService - .setOnConversationListChangedListener(this.onConvChanged); - xmppConnectionService.setOnRenameListener(new OnRenameListener() { - - @Override - public void onRename(final boolean success) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - populateView(); - if (success) { - Toast.makeText( - ConferenceDetailsActivity.this, - getString(R.string.your_nick_has_been_changed), - Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(ConferenceDetailsActivity.this, - getString(R.string.nick_in_use), - Toast.LENGTH_SHORT).show(); - } - } - }); - } - }); - } - - private void populateView() { - mAccountJid.setText(getString(R.string.using_account, conversation - .getAccount().getJid())); - mYourPhoto.setImageBitmap(avatarService().get( - conversation.getAccount(), getPixel(48))); - setTitle(conversation.getName()); - mFullJid.setText(conversation.getContactJid().split("/", 2)[0]); - mYourNick.setText(conversation.getMucOptions().getActualNick()); - mRoleAffiliaton = (TextView) findViewById(R.id.muc_role); - if (conversation.getMucOptions().online()) { - mMoreDetails.setVisibility(View.VISIBLE); - User self = conversation.getMucOptions().getSelf(); - switch (self.getAffiliation()) { - case User.AFFILIATION_ADMIN: - mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " (" - + getString(R.string.admin) + ")"); - break; - case User.AFFILIATION_OWNER: - mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " (" - + getString(R.string.owner) + ")"); - break; - default: - mRoleAffiliaton.setText(getReadableRole(self.getRole())); - break; - } - } - this.users.clear(); - this.users.addAll(conversation.getMucOptions().getUsers()); - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - membersView.removeAllViews(); - for (final User user : conversation.getMucOptions().getUsers()) { - View view = (View) inflater.inflate(R.layout.contact, membersView, - false); - TextView name = (TextView) view - .findViewById(R.id.contact_display_name); - TextView key = (TextView) view.findViewById(R.id.key); - TextView role = (TextView) view.findViewById(R.id.contact_jid); - if (user.getPgpKeyId() != 0) { - key.setVisibility(View.VISIBLE); - key.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - viewPgpKey(user); - } - }); - key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId())); - } - Bitmap bm; - Contact contact = user.getContact(); - if (contact != null) { - bm = avatarService().get(contact, getPixel(48)); - name.setText(contact.getDisplayName()); - role.setText(user.getName() + " \u2022 " - + getReadableRole(user.getRole())); - } else { - bm = avatarService().get(user.getName(), getPixel(48)); - name.setText(user.getName()); - role.setText(getReadableRole(user.getRole())); - } - ImageView iv = (ImageView) view.findViewById(R.id.contact_photo); - iv.setImageBitmap(bm); - membersView.addView(view); - } - } - - private void viewPgpKey(User user) { - PgpEngine pgp = xmppConnectionService.getPgpEngine(); - if (pgp != null) { - PendingIntent intent = pgp.getIntentForKey( - conversation.getAccount(), user.getPgpKeyId()); - if (intent != null) { - try { - startIntentSenderForResult(intent.getIntentSender(), 0, - null, 0, 0, 0); - } catch (SendIntentException e) { - - } - } - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java deleted file mode 100644 index ae26466e..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ /dev/null @@ -1,436 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.Iterator; - -import org.openintents.openpgp.util.OpenPgpUtils; - -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentSender.SendIntentException; -import android.net.Uri; -import android.os.Bundle; -import android.provider.ContactsContract.CommonDataKinds; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Intents; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.CheckBox; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.CompoundButton; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.QuickContactBadge; -import android.widget.TextView; -import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Presences; -import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; -import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; -import eu.siacs.conversations.utils.UIHelper; - -public class ContactDetailsActivity extends XmppActivity { - public static final String ACTION_VIEW_CONTACT = "view_contact"; - - private Contact contact; - - private String accountJid; - private String contactJid; - - private TextView contactJidTv; - private TextView accountJidTv; - private TextView status; - private TextView lastseen; - private CheckBox send; - private CheckBox receive; - private QuickContactBadge badge; - - private DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - ContactDetailsActivity.this.xmppConnectionService - .deleteContactOnServer(contact); - ContactDetailsActivity.this.finish(); - } - }; - - private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); - intent.setType(Contacts.CONTENT_ITEM_TYPE); - intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid()); - intent.putExtra(Intents.Insert.IM_PROTOCOL, - CommonDataKinds.Im.PROTOCOL_JABBER); - intent.putExtra("finishActivityOnSaveCompleted", true); - ContactDetailsActivity.this.startActivityForResult(intent, 0); - } - }; - private OnClickListener onBadgeClick = new OnClickListener() { - - @Override - public void onClick(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder( - ContactDetailsActivity.this); - builder.setTitle(getString(R.string.action_add_phone_book)); - builder.setMessage(getString(R.string.add_phone_book_text, - contact.getJid())); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.add), addToPhonebook); - builder.create().show(); - } - }; - - private LinearLayout keys; - - private OnRosterUpdate rosterUpdate = new OnRosterUpdate() { - - @Override - public void onRosterUpdate() { - runOnUiThread(new Runnable() { - - @Override - public void run() { - populateView(); - } - }); - } - }; - - private OnCheckedChangeListener mOnSendCheckedChange = new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - if (isChecked) { - if (contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - xmppConnectionService.sendPresencePacket(contact - .getAccount(), - xmppConnectionService.getPresenceGenerator() - .sendPresenceUpdatesTo(contact)); - } else { - contact.setOption(Contact.Options.PREEMPTIVE_GRANT); - } - } else { - contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); - xmppConnectionService.sendPresencePacket(contact.getAccount(), - xmppConnectionService.getPresenceGenerator() - .stopPresenceUpdatesTo(contact)); - } - } - }; - - private OnCheckedChangeListener mOnReceiveCheckedChange = new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - if (isChecked) { - xmppConnectionService.sendPresencePacket(contact.getAccount(), - xmppConnectionService.getPresenceGenerator() - .requestPresenceUpdatesFrom(contact)); - } else { - xmppConnectionService.sendPresencePacket(contact.getAccount(), - xmppConnectionService.getPresenceGenerator() - .stopPresenceUpdatesFrom(contact)); - } - } - }; - - private OnAccountUpdate accountUpdate = new OnAccountUpdate() { - - @Override - public void onAccountUpdate() { - runOnUiThread(new Runnable() { - - @Override - public void run() { - populateView(); - } - }); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) { - this.accountJid = getIntent().getExtras().getString("account"); - this.contactJid = getIntent().getExtras().getString("contact"); - } - setContentView(R.layout.activity_contact_details); - - contactJidTv = (TextView) findViewById(R.id.details_contactjid); - accountJidTv = (TextView) findViewById(R.id.details_account); - status = (TextView) findViewById(R.id.details_contactstatus); - lastseen = (TextView) findViewById(R.id.details_lastseen); - send = (CheckBox) findViewById(R.id.details_send_presence); - receive = (CheckBox) findViewById(R.id.details_receive_presence); - badge = (QuickContactBadge) findViewById(R.id.details_contact_badge); - keys = (LinearLayout) findViewById(R.id.details_contact_keys); - getActionBar().setHomeButtonEnabled(true); - getActionBar().setDisplayHomeAsUpEnabled(true); - - } - - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setNegativeButton(getString(R.string.cancel), null); - switch (menuItem.getItemId()) { - case android.R.id.home: - finish(); - break; - case R.id.action_delete_contact: - builder.setTitle(getString(R.string.action_delete_contact)) - .setMessage( - getString(R.string.remove_contact_text, - contact.getJid())) - .setPositiveButton(getString(R.string.delete), - removeFromRoster).create().show(); - break; - case R.id.action_edit_contact: - if (contact.getSystemAccount() == null) { - quickEdit(contact.getDisplayName(), new OnValueEdited() { - - @Override - public void onValueEdited(String value) { - contact.setServerName(value); - ContactDetailsActivity.this.xmppConnectionService - .pushContactToServer(contact); - populateView(); - } - }); - } else { - Intent intent = new Intent(Intent.ACTION_EDIT); - String[] systemAccount = contact.getSystemAccount().split("#"); - long id = Long.parseLong(systemAccount[0]); - Uri uri = Contacts.getLookupUri(id, systemAccount[1]); - intent.setDataAndType(uri, Contacts.CONTENT_ITEM_TYPE); - intent.putExtra("finishActivityOnSaveCompleted", true); - startActivity(intent); - } - break; - } - return super.onOptionsItemSelected(menuItem); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.contact_details, menu); - return true; - } - - private void populateView() { - send.setOnCheckedChangeListener(null); - receive.setOnCheckedChangeListener(null); - setTitle(contact.getDisplayName()); - if (contact.getOption(Contact.Options.FROM)) { - send.setText(R.string.send_presence_updates); - send.setChecked(true); - } else if (contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - send.setChecked(false); - send.setText(R.string.send_presence_updates); - } else { - send.setText(R.string.preemptively_grant); - if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { - send.setChecked(true); - } else { - send.setChecked(false); - } - } - if (contact.getOption(Contact.Options.TO)) { - receive.setText(R.string.receive_presence_updates); - receive.setChecked(true); - } else { - receive.setText(R.string.ask_for_presence_updates); - if (contact.getOption(Contact.Options.ASKING)) { - receive.setChecked(true); - } else { - receive.setChecked(false); - } - } - if (contact.getAccount().getStatus() == Account.STATUS_ONLINE) { - receive.setEnabled(true); - send.setEnabled(true); - } else { - receive.setEnabled(false); - send.setEnabled(false); - } - - send.setOnCheckedChangeListener(this.mOnSendCheckedChange); - receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange); - - lastseen.setText(UIHelper.lastseen(getApplicationContext(), - contact.lastseen.time)); - - switch (contact.getMostAvailableStatus()) { - case Presences.CHAT: - status.setText(R.string.contact_status_free_to_chat); - status.setTextColor(mColorGreen); - break; - case Presences.ONLINE: - status.setText(R.string.contact_status_online); - status.setTextColor(mColorGreen); - break; - case Presences.AWAY: - status.setText(R.string.contact_status_away); - status.setTextColor(mColorOrange); - break; - case Presences.XA: - status.setText(R.string.contact_status_extended_away); - status.setTextColor(mColorOrange); - break; - case Presences.DND: - status.setText(R.string.contact_status_do_not_disturb); - status.setTextColor(mColorRed); - break; - case Presences.OFFLINE: - status.setText(R.string.contact_status_offline); - status.setTextColor(mSecondaryTextColor); - break; - default: - status.setText(R.string.contact_status_offline); - status.setTextColor(mSecondaryTextColor); - break; - } - if (contact.getPresences().size() > 1) { - contactJidTv.setText(contact.getJid() + " (" - + contact.getPresences().size() + ")"); - } else { - contactJidTv.setText(contact.getJid()); - } - accountJidTv.setText(getString(R.string.using_account, contact - .getAccount().getJid())); - prepareContactBadge(badge, contact); - if (contact.getSystemAccount() == null) { - badge.setOnClickListener(onBadgeClick); - } - - keys.removeAllViews(); - boolean hasKeys = false; - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - for (Iterator iterator = contact.getOtrFingerprints() - .iterator(); iterator.hasNext();) { - hasKeys = true; - final String otrFingerprint = iterator.next(); - View view = (View) inflater.inflate(R.layout.contact_key, keys, - false); - TextView key = (TextView) view.findViewById(R.id.key); - TextView keyType = (TextView) view.findViewById(R.id.key_type); - ImageButton remove = (ImageButton) view - .findViewById(R.id.button_remove); - remove.setVisibility(View.VISIBLE); - keyType.setText("OTR Fingerprint"); - key.setText(otrFingerprint); - keys.addView(view); - remove.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - confirmToDeleteFingerprint(otrFingerprint); - } - }); - } - if (contact.getPgpKeyId() != 0) { - hasKeys = true; - View view = (View) inflater.inflate(R.layout.contact_key, keys, - false); - TextView key = (TextView) view.findViewById(R.id.key); - TextView keyType = (TextView) view.findViewById(R.id.key_type); - keyType.setText("PGP Key ID"); - key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId())); - view.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - PgpEngine pgp = ContactDetailsActivity.this.xmppConnectionService - .getPgpEngine(); - if (pgp != null) { - PendingIntent intent = pgp.getIntentForKey(contact); - if (intent != null) { - try { - startIntentSenderForResult( - intent.getIntentSender(), 0, null, 0, - 0, 0); - } catch (SendIntentException e) { - - } - } - } - } - }); - keys.addView(view); - } - if (hasKeys) { - keys.setVisibility(View.VISIBLE); - } else { - keys.setVisibility(View.GONE); - } - } - - private void prepareContactBadge(QuickContactBadge badge, Contact contact) { - if (contact.getSystemAccount() != null) { - String[] systemAccount = contact.getSystemAccount().split("#"); - long id = Long.parseLong(systemAccount[0]); - badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1])); - } - badge.setImageBitmap(avatarService().get(contact, getPixel(72))); - } - - protected void confirmToDeleteFingerprint(final String fingerprint) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.delete_fingerprint); - builder.setMessage(R.string.sure_delete_fingerprint); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.delete, - new android.content.DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - if (contact.deleteOtrFingerprint(fingerprint)) { - populateView(); - xmppConnectionService.syncRosterToDisk(contact - .getAccount()); - } - } - - }); - builder.create().show(); - } - - @Override - public void onBackendConnected() { - xmppConnectionService.setOnRosterUpdateListener(this.rosterUpdate); - xmppConnectionService - .setOnAccountListChangedListener(this.accountUpdate); - if ((accountJid != null) && (contactJid != null)) { - Account account = xmppConnectionService - .findAccountByJid(accountJid); - if (account == null) { - return; - } - this.contact = account.getRoster().getContact(contactJid); - populateView(); - } - } - - @Override - protected void onStop() { - super.onStop(); - xmppConnectionService.removeOnRosterUpdateListener(); - xmppConnectionService.removeOnAccountListChangedListener(); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java deleted file mode 100644 index 91e1c81f..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ /dev/null @@ -1,947 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.List; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; -import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; -import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; -import eu.siacs.conversations.ui.adapter.ConversationAdapter; -import eu.siacs.conversations.utils.ExceptionHelper; -import android.net.Uri; -import android.os.Bundle; -import android.os.SystemClock; -import android.provider.MediaStore; -import android.annotation.SuppressLint; -import android.app.ActionBar; -import android.app.AlertDialog; -import android.app.FragmentTransaction; -import android.app.PendingIntent; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.IntentSender.SendIntentException; -import android.content.Intent; -import android.support.v4.widget.SlidingPaneLayout; -import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.ListView; -import android.widget.PopupMenu; -import android.widget.PopupMenu.OnMenuItemClickListener; -import android.widget.Toast; - -public class ConversationActivity extends XmppActivity implements - OnAccountUpdate, OnConversationUpdate, OnRosterUpdate { - - public static final String VIEW_CONVERSATION = "viewConversation"; - public static final String CONVERSATION = "conversationUuid"; - public static final String TEXT = "text"; - public static final String PRESENCE = "eu.siacs.conversations.presence"; - - public static final int REQUEST_SEND_MESSAGE = 0x0201; - public static final int REQUEST_DECRYPT_PGP = 0x0202; - private static final int REQUEST_ATTACH_FILE_DIALOG = 0x0203; - private static final int REQUEST_IMAGE_CAPTURE = 0x0204; - private static final int REQUEST_RECORD_AUDIO = 0x0205; - private static final int REQUEST_SEND_PGP_IMAGE = 0x0206; - public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207; - - private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; - private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; - private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0303; - private static final String STATE_OPEN_CONVERSATION = "state_open_conversation"; - private static final String STATE_PANEL_OPEN = "state_panel_open"; - - private String mOpenConverstaion = null; - private boolean mPanelOpen = true; - - private View mContentView; - - private List conversationList = new ArrayList(); - private Conversation selectedConversation = null; - private ListView listView; - - private boolean paneShouldBeOpen = true; - private ArrayAdapter listAdapter; - - private Toast prepareImageToast; - - private Uri pendingImageUri = null; - - public List getConversationList() { - return this.conversationList; - } - - public Conversation getSelectedConversation() { - return this.selectedConversation; - } - - public void setSelectedConversation(Conversation conversation) { - this.selectedConversation = conversation; - } - - public ListView getConversationListView() { - return this.listView; - } - - public boolean shouldPaneBeOpen() { - return paneShouldBeOpen; - } - - public void showConversationsOverview() { - if (mContentView instanceof SlidingPaneLayout) { - SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; - mSlidingPaneLayout.openPane(); - } - } - - public void hideConversationsOverview() { - if (mContentView instanceof SlidingPaneLayout) { - SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; - mSlidingPaneLayout.closePane(); - } - } - - public boolean isConversationsOverviewHideable() { - if (mContentView instanceof SlidingPaneLayout) { - SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; - return mSlidingPaneLayout.isSlideable(); - } else { - return false; - } - } - - public boolean isConversationsOverviewVisable() { - if (mContentView instanceof SlidingPaneLayout) { - SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; - return mSlidingPaneLayout.isOpen(); - } else { - return true; - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (savedInstanceState != null) { - mOpenConverstaion = savedInstanceState.getString( - STATE_OPEN_CONVERSATION, null); - mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true); - } - - setContentView(R.layout.fragment_conversations_overview); - - listView = (ListView) findViewById(R.id.list); - - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - - this.listAdapter = new ConversationAdapter(this, conversationList); - listView.setAdapter(this.listAdapter); - - listView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View clickedView, - int position, long arg3) { - paneShouldBeOpen = false; - if (getSelectedConversation() != conversationList.get(position)) { - setSelectedConversation(conversationList.get(position)); - swapConversationFragment(); - } else { - hideConversationsOverview(); - } - } - }); - mContentView = findViewById(R.id.content_view_spl); - if (mContentView == null) { - mContentView = findViewById(R.id.content_view_ll); - } - if (mContentView instanceof SlidingPaneLayout) { - SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; - mSlidingPaneLayout.setParallaxDistance(150); - mSlidingPaneLayout - .setShadowResource(R.drawable.es_slidingpane_shadow); - mSlidingPaneLayout.setSliderFadeColor(0); - mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() { - - @Override - public void onPanelOpened(View arg0) { - paneShouldBeOpen = true; - ActionBar ab = getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(false); - ab.setHomeButtonEnabled(false); - ab.setTitle(R.string.app_name); - } - invalidateOptionsMenu(); - hideKeyboard(); - if (xmppConnectionServiceBound) { - xmppConnectionService.getNotificationService() - .setOpenConversation(null); - } - } - - @Override - public void onPanelClosed(View arg0) { - paneShouldBeOpen = false; - if ((conversationList.size() > 0) - && (getSelectedConversation() != null)) { - openConversation(getSelectedConversation()); - if (!getSelectedConversation().isRead()) { - xmppConnectionService.markRead( - getSelectedConversation(), true); - listView.invalidateViews(); - } - } - } - - @Override - public void onPanelSlide(View arg0, float arg1) { - // TODO Auto-generated method stub - - } - }); - } - } - - public void openConversation(Conversation conversation) { - ActionBar ab = getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(true); - ab.setHomeButtonEnabled(true); - if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE - || ConversationActivity.this - .useSubjectToIdentifyConference()) { - ab.setTitle(getSelectedConversation().getName()); - } else { - ab.setTitle(getSelectedConversation().getContactJid() - .split("/")[0]); - } - } - invalidateOptionsMenu(); - if (xmppConnectionServiceBound) { - xmppConnectionService.getNotificationService().setOpenConversation( - conversation); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.conversations, menu); - MenuItem menuSecure = (MenuItem) menu.findItem(R.id.action_security); - MenuItem menuArchive = (MenuItem) menu.findItem(R.id.action_archive); - MenuItem menuMucDetails = (MenuItem) menu - .findItem(R.id.action_muc_details); - MenuItem menuContactDetails = (MenuItem) menu - .findItem(R.id.action_contact_details); - MenuItem menuAttach = (MenuItem) menu.findItem(R.id.action_attach_file); - MenuItem menuClearHistory = (MenuItem) menu - .findItem(R.id.action_clear_history); - MenuItem menuAdd = (MenuItem) menu.findItem(R.id.action_add); - MenuItem menuInviteContact = (MenuItem) menu - .findItem(R.id.action_invite); - MenuItem menuMute = (MenuItem) menu.findItem(R.id.action_mute); - - if (isConversationsOverviewVisable() - && isConversationsOverviewHideable()) { - menuArchive.setVisible(false); - menuMucDetails.setVisible(false); - menuContactDetails.setVisible(false); - menuSecure.setVisible(false); - menuInviteContact.setVisible(false); - menuAttach.setVisible(false); - menuClearHistory.setVisible(false); - menuMute.setVisible(false); - } else { - menuAdd.setVisible(!isConversationsOverviewHideable()); - if (this.getSelectedConversation() != null) { - if (this.getSelectedConversation().getLatestMessage() - .getEncryption() != Message.ENCRYPTION_NONE) { - menuSecure.setIcon(R.drawable.ic_action_secure); - } - if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) { - menuContactDetails.setVisible(false); - menuAttach.setVisible(false); - } else { - menuMucDetails.setVisible(false); - menuInviteContact.setVisible(false); - } - } - } - return true; - } - - private void selectPresenceToAttachFile(final int attachmentChoice) { - selectPresence(getSelectedConversation(), new OnPresenceSelected() { - - @Override - public void onPresenceSelected() { - if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) { - pendingImageUri = xmppConnectionService.getFileBackend() - .getTakePhotoUri(); - Intent takePictureIntent = new Intent( - MediaStore.ACTION_IMAGE_CAPTURE); - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, - pendingImageUri); - if (takePictureIntent.resolveActivity(getPackageManager()) != null) { - startActivityForResult(takePictureIntent, - REQUEST_IMAGE_CAPTURE); - } - } else if (attachmentChoice == ATTACHMENT_CHOICE_CHOOSE_IMAGE) { - Intent attachFileIntent = new Intent(); - attachFileIntent.setType("image/*"); - attachFileIntent.setAction(Intent.ACTION_GET_CONTENT); - Intent chooser = Intent.createChooser(attachFileIntent, - getString(R.string.attach_file)); - startActivityForResult(chooser, REQUEST_ATTACH_FILE_DIALOG); - } else if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) { - Intent intent = new Intent( - MediaStore.Audio.Media.RECORD_SOUND_ACTION); - startActivityForResult(intent, REQUEST_RECORD_AUDIO); - } - } - }); - } - - private void attachFile(final int attachmentChoice) { - final Conversation conversation = getSelectedConversation(); - if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { - if (hasPgp()) { - if (conversation.getContact().getPgpKeyId() != 0) { - xmppConnectionService.getPgpEngine().hasKey( - conversation.getContact(), - new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, - Contact contact) { - ConversationActivity.this.runIntent(pi, - attachmentChoice); - } - - @Override - public void success(Contact contact) { - selectPresenceToAttachFile(attachmentChoice); - } - - @Override - public void error(int error, Contact contact) { - displayErrorDialog(error); - } - }); - } else { - final ConversationFragment fragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (fragment != null) { - fragment.showNoPGPKeyDialog(false, - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation - .setNextEncryption(Message.ENCRYPTION_NONE); - xmppConnectionService.databaseBackend - .updateConversation(conversation); - selectPresenceToAttachFile(attachmentChoice); - } - }); - } - } - } else { - showInstallPgpDialog(); - } - } else if (getSelectedConversation().getNextEncryption( - forceEncryption()) == Message.ENCRYPTION_NONE) { - selectPresenceToAttachFile(attachmentChoice); - } else { - selectPresenceToAttachFile(attachmentChoice); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - showConversationsOverview(); - return true; - } else if (item.getItemId() == R.id.action_add) { - startActivity(new Intent(this, StartConversationActivity.class)); - return true; - } else if (getSelectedConversation() != null) { - switch (item.getItemId()) { - case R.id.action_attach_file: - attachFileDialog(); - break; - case R.id.action_archive: - this.endConversation(getSelectedConversation()); - break; - case R.id.action_contact_details: - Contact contact = this.getSelectedConversation().getContact(); - if (contact.showInRoster()) { - switchToContactDetails(contact); - } else { - showAddToRosterDialog(getSelectedConversation()); - } - break; - case R.id.action_muc_details: - Intent intent = new Intent(this, - ConferenceDetailsActivity.class); - intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); - intent.putExtra("uuid", getSelectedConversation().getUuid()); - startActivity(intent); - break; - case R.id.action_invite: - inviteToConversation(getSelectedConversation()); - break; - case R.id.action_security: - selectEncryptionDialog(getSelectedConversation()); - break; - case R.id.action_clear_history: - clearHistoryDialog(getSelectedConversation()); - break; - case R.id.action_mute: - muteConversationDialog(getSelectedConversation()); - break; - default: - break; - } - return super.onOptionsItemSelected(item); - } else { - return super.onOptionsItemSelected(item); - } - } - - public void endConversation(Conversation conversation) { - conversation.setStatus(Conversation.STATUS_ARCHIVED); - paneShouldBeOpen = true; - showConversationsOverview(); - xmppConnectionService.archiveConversation(conversation); - if (conversationList.size() > 0) { - setSelectedConversation(conversationList.get(0)); - } else { - setSelectedConversation(null); - } - } - - @SuppressLint("InflateParams") - protected void clearHistoryDialog(final Conversation conversation) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.clear_conversation_history)); - View dialogView = getLayoutInflater().inflate( - R.layout.dialog_clear_history, null); - final CheckBox endConversationCheckBox = (CheckBox) dialogView - .findViewById(R.id.end_conversation_checkbox); - builder.setView(dialogView); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.delete_messages), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - ConversationActivity.this.xmppConnectionService - .clearConversationHistory(conversation); - if (endConversationCheckBox.isChecked()) { - endConversation(conversation); - } - } - }); - builder.create().show(); - } - - protected void attachFileDialog() { - View menuAttachFile = findViewById(R.id.action_attach_file); - if (menuAttachFile == null) { - return; - } - PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile); - attachFilePopup.inflate(R.menu.attachment_choices); - attachFilePopup - .setOnMenuItemClickListener(new OnMenuItemClickListener() { - - @Override - public boolean onMenuItemClick(MenuItem item) { - switch (item.getItemId()) { - case R.id.attach_choose_picture: - attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE); - break; - case R.id.attach_take_picture: - attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO); - break; - case R.id.attach_record_voice: - attachFile(ATTACHMENT_CHOICE_RECORD_VOICE); - break; - } - return false; - } - }); - attachFilePopup.show(); - } - - protected void selectEncryptionDialog(final Conversation conversation) { - View menuItemView = findViewById(R.id.action_security); - if (menuItemView == null) { - return; - } - PopupMenu popup = new PopupMenu(this, menuItemView); - final ConversationFragment fragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (fragment != null) { - popup.setOnMenuItemClickListener(new OnMenuItemClickListener() { - - @Override - public boolean onMenuItemClick(MenuItem item) { - switch (item.getItemId()) { - case R.id.encryption_choice_none: - conversation.setNextEncryption(Message.ENCRYPTION_NONE); - item.setChecked(true); - break; - case R.id.encryption_choice_otr: - conversation.setNextEncryption(Message.ENCRYPTION_OTR); - item.setChecked(true); - break; - case R.id.encryption_choice_pgp: - if (hasPgp()) { - if (conversation.getAccount().getKeys() - .has("pgp_signature")) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); - item.setChecked(true); - } else { - announcePgp(conversation.getAccount(), - conversation); - } - } else { - showInstallPgpDialog(); - } - break; - default: - conversation.setNextEncryption(Message.ENCRYPTION_NONE); - break; - } - xmppConnectionService.databaseBackend - .updateConversation(conversation); - fragment.updateChatMsgHint(); - return true; - } - }); - popup.inflate(R.menu.encryption_choices); - MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr); - MenuItem none = popup.getMenu().findItem( - R.id.encryption_choice_none); - if (conversation.getMode() == Conversation.MODE_MULTI) { - otr.setEnabled(false); - } else { - if (forceEncryption()) { - none.setVisible(false); - } - } - switch (conversation.getNextEncryption(forceEncryption())) { - case Message.ENCRYPTION_NONE: - none.setChecked(true); - break; - case Message.ENCRYPTION_OTR: - otr.setChecked(true); - break; - case Message.ENCRYPTION_PGP: - popup.getMenu().findItem(R.id.encryption_choice_pgp) - .setChecked(true); - break; - default: - popup.getMenu().findItem(R.id.encryption_choice_none) - .setChecked(true); - break; - } - popup.show(); - } - } - - protected void muteConversationDialog(final Conversation conversation) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.disable_notifications_for_this_conversation); - final int[] durations = getResources().getIntArray( - R.array.mute_options_durations); - builder.setItems(R.array.mute_options_descriptions, - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - long till; - if (durations[which] == -1) { - till = Long.MAX_VALUE; - } else { - till = SystemClock.elapsedRealtime() - + (durations[which] * 1000); - } - conversation.setMutedTill(till); - ConversationActivity.this.xmppConnectionService.databaseBackend - .updateConversation(conversation); - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (selectedFragment != null) { - selectedFragment.updateMessages(); - } - } - }); - builder.create().show(); - } - - protected ConversationFragment swapConversationFragment() { - ConversationFragment selectedFragment = new ConversationFragment(); - if (!isFinishing()) { - - FragmentTransaction transaction = getFragmentManager() - .beginTransaction(); - transaction.replace(R.id.selected_conversation, selectedFragment, - "conversation"); - try { - transaction.commitAllowingStateLoss(); - } catch (IllegalStateException e) { - return selectedFragment; - } - } - return selectedFragment; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - if (!isConversationsOverviewVisable()) { - showConversationsOverview(); - return false; - } - } - return super.onKeyDown(keyCode, event); - } - - @Override - protected void onNewIntent(Intent intent) { - if (xmppConnectionServiceBound) { - if ((Intent.ACTION_VIEW.equals(intent.getAction()) && (VIEW_CONVERSATION - .equals(intent.getType())))) { - String convToView = (String) intent.getExtras().get( - CONVERSATION); - updateConversationList(); - for (int i = 0; i < conversationList.size(); ++i) { - if (conversationList.get(i).getUuid().equals(convToView)) { - setSelectedConversation(conversationList.get(i)); - break; - } - } - paneShouldBeOpen = false; - String text = intent.getExtras().getString(TEXT, null); - swapConversationFragment().setText(text); - } - } else { - handledViewIntent = false; - setIntent(intent); - } - } - - @Override - public void onStart() { - super.onStart(); - if (this.xmppConnectionServiceBound) { - this.onBackendConnected(); - } - if (conversationList.size() >= 1) { - this.onConversationUpdate(); - } - } - - @Override - protected void onStop() { - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnConversationListChangedListener(); - xmppConnectionService.removeOnAccountListChangedListener(); - xmppConnectionService.removeOnRosterUpdateListener(); - xmppConnectionService.getNotificationService().setOpenConversation( - null); - } - super.onStop(); - } - - @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - Conversation conversation = getSelectedConversation(); - if (conversation != null) { - savedInstanceState.putString(STATE_OPEN_CONVERSATION, - conversation.getUuid()); - } - savedInstanceState.putBoolean(STATE_PANEL_OPEN, - isConversationsOverviewVisable()); - super.onSaveInstanceState(savedInstanceState); - } - - @Override - void onBackendConnected() { - this.registerListener(); - updateConversationList(); - - if (xmppConnectionService.getAccounts().size() == 0) { - startActivity(new Intent(this, EditAccountActivity.class)); - } else if (conversationList.size() <= 0) { - startActivity(new Intent(this, StartConversationActivity.class)); - finish(); - } else if (mOpenConverstaion != null) { - selectConversationByUuid(mOpenConverstaion); - paneShouldBeOpen = mPanelOpen; - if (paneShouldBeOpen) { - showConversationsOverview(); - } - swapConversationFragment(); - mOpenConverstaion = null; - } else if (getIntent() != null - && VIEW_CONVERSATION.equals(getIntent().getType())) { - String uuid = (String) getIntent().getExtras().get(CONVERSATION); - String text = getIntent().getExtras().getString(TEXT, null); - selectConversationByUuid(uuid); - paneShouldBeOpen = false; - swapConversationFragment().setText(text); - setIntent(null); - } else { - showConversationsOverview(); - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (selectedFragment != null) { - selectedFragment.onBackendConnected(); - } else { - pendingImageUri = null; - setSelectedConversation(conversationList.get(0)); - swapConversationFragment(); - } - } - - if (pendingImageUri != null) { - attachImageToConversation(getSelectedConversation(), - pendingImageUri); - pendingImageUri = null; - } - ExceptionHelper.checkForCrash(this, this.xmppConnectionService); - } - - private void selectConversationByUuid(String uuid) { - for (int i = 0; i < conversationList.size(); ++i) { - if (conversationList.get(i).getUuid().equals(uuid)) { - setSelectedConversation(conversationList.get(i)); - } - } - } - - public void registerListener() { - xmppConnectionService.setOnConversationListChangedListener(this); - xmppConnectionService.setOnAccountListChangedListener(this); - xmppConnectionService.setOnRosterUpdateListener(this); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, - final Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - if (requestCode == REQUEST_DECRYPT_PGP) { - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (selectedFragment != null) { - selectedFragment.hideSnackbar(); - selectedFragment.updateMessages(); - } - } else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) { - pendingImageUri = data.getData(); - if (xmppConnectionServiceBound) { - attachImageToConversation(getSelectedConversation(), - pendingImageUri); - pendingImageUri = null; - } - } else if (requestCode == REQUEST_SEND_PGP_IMAGE) { - - } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) { - attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE); - } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) { - attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO); - } else if (requestCode == REQUEST_ANNOUNCE_PGP) { - announcePgp(getSelectedConversation().getAccount(), - getSelectedConversation()); - } else if (requestCode == REQUEST_ENCRYPT_MESSAGE) { - // encryptTextMessage(); - } else if (requestCode == REQUEST_IMAGE_CAPTURE) { - if (xmppConnectionServiceBound) { - attachImageToConversation(getSelectedConversation(), - pendingImageUri); - pendingImageUri = null; - } - Intent intent = new Intent( - Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(pendingImageUri); - sendBroadcast(intent); - } else if (requestCode == REQUEST_RECORD_AUDIO) { - attachAudioToConversation(getSelectedConversation(), - data.getData()); - } - } else { - if (requestCode == REQUEST_IMAGE_CAPTURE) { - pendingImageUri = null; - } - } - } - - private void attachAudioToConversation(Conversation conversation, Uri uri) { - - } - - private void attachImageToConversation(Conversation conversation, Uri uri) { - prepareImageToast = Toast.makeText(getApplicationContext(), - getText(R.string.preparing_image), Toast.LENGTH_LONG); - prepareImageToast.show(); - xmppConnectionService.attachImageToConversation(conversation, uri, - new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, - Message object) { - hidePrepareImageToast(); - ConversationActivity.this.runIntent(pi, - ConversationActivity.REQUEST_SEND_PGP_IMAGE); - } - - @Override - public void success(Message message) { - xmppConnectionService.sendMessage(message); - } - - @Override - public void error(int error, Message message) { - hidePrepareImageToast(); - displayErrorDialog(error); - } - }); - } - - private void hidePrepareImageToast() { - if (prepareImageToast != null) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - prepareImageToast.cancel(); - } - }); - } - } - - public void updateConversationList() { - xmppConnectionService - .populateWithOrderedConversations(conversationList); - listAdapter.notifyDataSetChanged(); - } - - public void runIntent(PendingIntent pi, int requestCode) { - try { - this.startIntentSenderForResult(pi.getIntentSender(), requestCode, - null, 0, 0, 0); - } catch (SendIntentException e1) { - } - } - - public void encryptTextMessage(Message message) { - xmppConnectionService.getPgpEngine().encrypt(message, - new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, - Message message) { - ConversationActivity.this.runIntent(pi, - ConversationActivity.REQUEST_SEND_MESSAGE); - } - - @Override - public void success(Message message) { - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - xmppConnectionService.sendMessage(message); - } - - @Override - public void error(int error, Message message) { - - } - }); - } - - public boolean forceEncryption() { - return getPreferences().getBoolean("force_encryption", false); - } - - public boolean useSendButtonToIndicateStatus() { - return getPreferences().getBoolean("send_button_status", false); - } - - public boolean indicateReceived() { - return getPreferences().getBoolean("indicate_received", false); - } - - @Override - public void onAccountUpdate() { - final ConversationFragment fragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (fragment != null) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - fragment.updateMessages(); - } - }); - } - } - - @Override - public void onConversationUpdate() { - runOnUiThread(new Runnable() { - - @Override - public void run() { - updateConversationList(); - if (paneShouldBeOpen) { - if (conversationList.size() >= 1) { - swapConversationFragment(); - } else { - startActivity(new Intent(getApplicationContext(), - StartConversationActivity.class)); - finish(); - } - } - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (selectedFragment != null) { - selectedFragment.updateMessages(); - } - } - }); - } - - @Override - public void onRosterUpdate() { - final ConversationFragment fragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (fragment != null) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - fragment.updateMessages(); - } - }); - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/conversations/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java deleted file mode 100644 index 0e71801b..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ /dev/null @@ -1,781 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; - -import net.java.otr4j.session.SessionStatus; -import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.entities.Presences; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.ui.EditMessage.OnEnterPressed; -import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected; -import eu.siacs.conversations.ui.XmppActivity.OnValueEdited; -import eu.siacs.conversations.ui.adapter.MessageAdapter; -import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; -import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; -import eu.siacs.conversations.utils.UIHelper; -import android.app.AlertDialog; -import android.app.Fragment; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentSender; -import android.content.IntentSender.SendIntentException; -import android.os.Bundle; -import android.text.Editable; -import android.text.Selection; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.AbsListView.OnScrollListener; -import android.widget.TextView.OnEditorActionListener; -import android.widget.AbsListView; - -import android.widget.ListView; -import android.widget.ImageButton; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -public class ConversationFragment extends Fragment { - - protected Conversation conversation; - protected ListView messagesView; - protected LayoutInflater inflater; - protected List messageList = new ArrayList(); - protected MessageAdapter messageListAdapter; - protected Contact contact; - - protected String queuedPqpMessage = null; - - private EditMessage mEditMessage; - private ImageButton mSendButton; - private String pastedText = null; - private RelativeLayout snackbar; - private TextView snackbarMessage; - private TextView snackbarAction; - - private boolean messagesLoaded = false; - - private IntentSender askForPassphraseIntent = null; - - private ConcurrentLinkedQueue mEncryptedMessages = new ConcurrentLinkedQueue(); - private boolean mDecryptJobRunning = false; - - private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() { - - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_SEND) { - InputMethodManager imm = (InputMethodManager) v.getContext() - .getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(v.getWindowToken(), 0); - sendMessage(); - return true; - } else { - return false; - } - } - }; - - private OnClickListener mSendButtonListener = new OnClickListener() { - - @Override - public void onClick(View v) { - sendMessage(); - } - }; - protected OnClickListener clickToDecryptListener = new OnClickListener() { - - @Override - public void onClick(View v) { - if (activity.hasPgp() && askForPassphraseIntent != null) { - try { - getActivity().startIntentSenderForResult( - askForPassphraseIntent, - ConversationActivity.REQUEST_DECRYPT_PGP, null, 0, - 0, 0); - } catch (SendIntentException e) { - // - } - } - } - }; - - private OnClickListener clickToMuc = new OnClickListener() { - - @Override - public void onClick(View v) { - Intent intent = new Intent(getActivity(), - ConferenceDetailsActivity.class); - intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); - intent.putExtra("uuid", conversation.getUuid()); - startActivity(intent); - } - }; - - private OnClickListener leaveMuc = new OnClickListener() { - - @Override - public void onClick(View v) { - activity.endConversation(conversation); - } - }; - - private OnClickListener joinMuc = new OnClickListener() { - - @Override - public void onClick(View v) { - activity.xmppConnectionService.joinMuc(conversation); - } - }; - - private OnClickListener enterPassword = new OnClickListener() { - - @Override - public void onClick(View v) { - MucOptions muc = conversation.getMucOptions(); - String password = muc.getPassword(); - if (password == null) { - password = ""; - } - activity.quickPasswordEdit(password, new OnValueEdited() { - - @Override - public void onValueEdited(String value) { - activity.xmppConnectionService.providePasswordForMuc( - conversation, value); - } - }); - } - }; - - private OnScrollListener mOnScrollListener = new OnScrollListener() { - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - // TODO Auto-generated method stub - - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { - if (firstVisibleItem == 0 && messagesLoaded) { - long timestamp = messageList.get(0).getTimeSent(); - messagesLoaded = false; - int size = activity.xmppConnectionService.loadMoreMessages( - conversation, timestamp); - messageList.clear(); - messageList.addAll(conversation.getMessages()); - updateStatusMessages(); - messageListAdapter.notifyDataSetChanged(); - if (size != 0) { - messagesLoaded = true; - } - messagesView.setSelectionFromTop(size + 1, 0); - } - } - }; - - private ConversationActivity activity; - - private void sendMessage() { - if (this.conversation == null) { - return; - } - if (mEditMessage.getText().length() < 1) { - if (this.conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setNextPresence(null); - updateChatMsgHint(); - } - return; - } - Message message = new Message(conversation, mEditMessage.getText() - .toString(), conversation.getNextEncryption(activity - .forceEncryption())); - if (conversation.getMode() == Conversation.MODE_MULTI) { - if (conversation.getNextPresence() != null) { - message.setPresence(conversation.getNextPresence()); - message.setType(Message.TYPE_PRIVATE); - conversation.setNextPresence(null); - } - } - if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_OTR) { - sendOtrMessage(message); - } else if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_PGP) { - sendPgpMessage(message); - } else { - sendPlainTextMessage(message); - } - } - - public void updateChatMsgHint() { - if (conversation.getMode() == Conversation.MODE_MULTI - && conversation.getNextPresence() != null) { - this.mEditMessage.setHint(getString( - R.string.send_private_message_to, - conversation.getNextPresence())); - } else { - switch (conversation.getNextEncryption(activity.forceEncryption())) { - case Message.ENCRYPTION_NONE: - mEditMessage - .setHint(getString(R.string.send_plain_text_message)); - break; - case Message.ENCRYPTION_OTR: - mEditMessage.setHint(getString(R.string.send_otr_message)); - break; - case Message.ENCRYPTION_PGP: - mEditMessage.setHint(getString(R.string.send_pgp_message)); - break; - default: - break; - } - } - } - - @Override - public View onCreateView(final LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - final View view = inflater.inflate(R.layout.fragment_conversation, - container, false); - mEditMessage = (EditMessage) view.findViewById(R.id.textinput); - mEditMessage.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - activity.hideConversationsOverview(); - } - }); - mEditMessage.setOnEditorActionListener(mEditorActionListener); - mEditMessage.setOnEnterPressedListener(new OnEnterPressed() { - - @Override - public void onEnterPressed() { - sendMessage(); - } - }); - - mSendButton = (ImageButton) view.findViewById(R.id.textSendButton); - mSendButton.setOnClickListener(this.mSendButtonListener); - - snackbar = (RelativeLayout) view.findViewById(R.id.snackbar); - snackbarMessage = (TextView) view.findViewById(R.id.snackbar_message); - snackbarAction = (TextView) view.findViewById(R.id.snackbar_action); - - messagesView = (ListView) view.findViewById(R.id.messages_view); - messagesView.setOnScrollListener(mOnScrollListener); - messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); - messageListAdapter = new MessageAdapter( - (ConversationActivity) getActivity(), this.messageList); - messageListAdapter - .setOnContactPictureClicked(new OnContactPictureClicked() { - - @Override - public void onContactPictureClicked(Message message) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - if (message.getPresence() != null) { - highlightInConference(message.getPresence()); - } else { - highlightInConference(message - .getCounterpart()); - } - } else { - Contact contact = message.getConversation() - .getContact(); - if (contact.showInRoster()) { - activity.switchToContactDetails(contact); - } else { - activity.showAddToRosterDialog(message - .getConversation()); - } - } - } - } - }); - messageListAdapter - .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { - - @Override - public void onContactPictureLongClicked(Message message) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - if (message.getPresence() != null) { - privateMessageWith(message.getPresence()); - } else { - privateMessageWith(message.getCounterpart()); - } - } - } - } - }); - messagesView.setAdapter(messageListAdapter); - - return view; - } - - protected void privateMessageWith(String counterpart) { - this.mEditMessage.setText(""); - this.conversation.setNextPresence(counterpart); - updateChatMsgHint(); - } - - protected void highlightInConference(String nick) { - String oldString = mEditMessage.getText().toString().trim(); - if (oldString.isEmpty() || mEditMessage.getSelectionStart() == 0) { - mEditMessage.getText().insert(0, nick + ": "); - } else { - if (mEditMessage.getText().charAt( - mEditMessage.getSelectionStart() - 1) != ' ') { - nick = " " + nick; - } - mEditMessage.getText().insert(mEditMessage.getSelectionStart(), - nick + " "); - } - } - - @Override - public void onStart() { - super.onStart(); - this.activity = (ConversationActivity) getActivity(); - if (activity.xmppConnectionServiceBound) { - this.onBackendConnected(); - } - } - - @Override - public void onStop() { - mDecryptJobRunning = false; - super.onStop(); - if (this.conversation != null) { - this.conversation.setNextMessage(mEditMessage.getText().toString()); - } - } - - public void onBackendConnected() { - this.activity = (ConversationActivity) getActivity(); - this.conversation = activity.getSelectedConversation(); - if (this.conversation == null) { - return; - } - String oldString = conversation.getNextMessage().trim(); - if (this.pastedText == null) { - this.mEditMessage.setText(oldString); - } else { - - if (oldString.isEmpty()) { - mEditMessage.setText(pastedText); - } else { - mEditMessage.setText(oldString + " " + pastedText); - } - pastedText = null; - } - int position = mEditMessage.length(); - Editable etext = mEditMessage.getText(); - Selection.setSelection(etext, position); - if (activity.isConversationsOverviewHideable()) { - if (!activity.shouldPaneBeOpen()) { - activity.hideConversationsOverview(); - activity.openConversation(conversation); - } - } - if (this.conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setNextPresence(null); - } - updateMessages(); - } - - public void updateMessages() { - if (getView() == null) { - return; - } - hideSnackbar(); - final ConversationActivity activity = (ConversationActivity) getActivity(); - if (this.conversation != null) { - final Contact contact = this.conversation.getContact(); - if (this.conversation.isMuted()) { - showSnackbar(R.string.notifications_disabled, R.string.enable, - new OnClickListener() { - - @Override - public void onClick(View v) { - conversation.setMutedTill(0); - activity.xmppConnectionService.databaseBackend - .updateConversation(conversation); - updateMessages(); - } - }); - } else if (!contact.showInRoster() - && contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - showSnackbar(R.string.contact_added_you, R.string.add_back, - new OnClickListener() { - - @Override - public void onClick(View v) { - activity.xmppConnectionService - .createContact(contact); - activity.switchToContactDetails(contact); - } - }); - } - for (Message message : this.conversation.getMessages()) { - if ((message.getEncryption() == Message.ENCRYPTION_PGP) - && ((message.getStatus() == Message.STATUS_RECEIVED) || (message - .getStatus() == Message.STATUS_SEND))) { - if (!mEncryptedMessages.contains(message)) { - mEncryptedMessages.add(message); - } - } - } - decryptNext(); - this.messageList.clear(); - if (this.conversation.getMessages().size() == 0) { - messagesLoaded = false; - } else { - this.messageList.addAll(this.conversation.getMessages()); - messagesLoaded = true; - updateStatusMessages(); - } - this.messageListAdapter.notifyDataSetChanged(); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - if (messageList.size() >= 1) { - makeFingerprintWarning(conversation.getLatestEncryption()); - } - } else { - if (!conversation.getMucOptions().online() - && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { - int error = conversation.getMucOptions().getError(); - switch (error) { - case MucOptions.ERROR_NICK_IN_USE: - showSnackbar(R.string.nick_in_use, R.string.edit, - clickToMuc); - break; - case MucOptions.ERROR_ROOM_NOT_FOUND: - showSnackbar(R.string.conference_not_found, - R.string.leave, leaveMuc); - break; - case MucOptions.ERROR_PASSWORD_REQUIRED: - showSnackbar(R.string.conference_requires_password, - R.string.enter_password, enterPassword); - break; - case MucOptions.ERROR_BANNED: - showSnackbar(R.string.conference_banned, - R.string.leave, leaveMuc); - break; - case MucOptions.ERROR_MEMBERS_ONLY: - showSnackbar(R.string.conference_members_only, - R.string.leave, leaveMuc); - break; - case MucOptions.KICKED_FROM_ROOM: - showSnackbar(R.string.conference_kicked, R.string.join, - joinMuc); - break; - default: - break; - } - } - } - getActivity().invalidateOptionsMenu(); - updateChatMsgHint(); - if (!activity.shouldPaneBeOpen()) { - activity.xmppConnectionService.markRead(conversation, true); - activity.updateConversationList(); - } - this.updateSendButton(); - } - } - - private void decryptNext() { - Message next = this.mEncryptedMessages.peek(); - PgpEngine engine = activity.xmppConnectionService.getPgpEngine(); - - if (next != null && engine != null && !mDecryptJobRunning) { - mDecryptJobRunning = true; - engine.decrypt(next, new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, Message message) { - mDecryptJobRunning = false; - askForPassphraseIntent = pi.getIntentSender(); - showSnackbar(R.string.openpgp_messages_found, - R.string.decrypt, clickToDecryptListener); - } - - @Override - public void success(Message message) { - mDecryptJobRunning = false; - mEncryptedMessages.remove(); - activity.xmppConnectionService.updateMessage(message); - } - - @Override - public void error(int error, Message message) { - message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED); - mDecryptJobRunning = false; - mEncryptedMessages.remove(); - activity.xmppConnectionService.updateConversationUi(); - } - }); - } - } - - private void messageSent() { - int size = this.messageList.size(); - messagesView.setSelection(size - 1); - mEditMessage.setText(""); - updateChatMsgHint(); - } - - public void updateSendButton() { - Conversation c = this.conversation; - if (activity.useSendButtonToIndicateStatus() && c != null - && c.getAccount().getStatus() == Account.STATUS_ONLINE) { - if (c.getMode() == Conversation.MODE_SINGLE) { - switch (c.getContact().getMostAvailableStatus()) { - case Presences.CHAT: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - break; - case Presences.ONLINE: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - break; - case Presences.AWAY: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_away); - break; - case Presences.XA: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_away); - break; - case Presences.DND: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_dnd); - break; - default: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); - break; - } - } else if (c.getMode() == Conversation.MODE_MULTI) { - if (c.getMucOptions().online()) { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); - } - } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); - } - } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); - } - } - - protected void updateStatusMessages() { - if (conversation.getMode() == Conversation.MODE_SINGLE) { - for (int i = this.messageList.size() - 1; i >= 0; --i) { - if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) { - return; - } else { - if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) { - this.messageList.add(i + 1, - Message.createStatusMessage(conversation)); - return; - } - } - } - } - } - - protected void makeFingerprintWarning(int latestEncryption) { - Set knownFingerprints = conversation.getContact() - .getOtrFingerprints(); - if ((latestEncryption == Message.ENCRYPTION_OTR) - && (conversation.hasValidOtrSession() - && (!conversation.isMuted()) - && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints - .contains(conversation.getOtrFingerprint())))) { - showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, - new OnClickListener() { - - @Override - public void onClick(View v) { - if (conversation.getOtrFingerprint() != null) { - AlertDialog dialog = UIHelper - .getVerifyFingerprintDialog( - (ConversationActivity) getActivity(), - conversation, snackbar); - dialog.show(); - } - } - }); - } - } - - protected void showSnackbar(int message, int action, - OnClickListener clickListener) { - snackbar.setVisibility(View.VISIBLE); - snackbar.setOnClickListener(null); - snackbarMessage.setText(message); - snackbarMessage.setOnClickListener(null); - snackbarAction.setText(action); - snackbarAction.setOnClickListener(clickListener); - } - - protected void hideSnackbar() { - snackbar.setVisibility(View.GONE); - } - - protected void sendPlainTextMessage(Message message) { - ConversationActivity activity = (ConversationActivity) getActivity(); - activity.xmppConnectionService.sendMessage(message); - messageSent(); - } - - protected void sendPgpMessage(final Message message) { - final ConversationActivity activity = (ConversationActivity) getActivity(); - final XmppConnectionService xmppService = activity.xmppConnectionService; - final Contact contact = message.getConversation().getContact(); - if (activity.hasPgp()) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { - if (contact.getPgpKeyId() != 0) { - xmppService.getPgpEngine().hasKey(contact, - new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, - Contact contact) { - activity.runIntent( - pi, - ConversationActivity.REQUEST_ENCRYPT_MESSAGE); - } - - @Override - public void success(Contact contact) { - messageSent(); - activity.encryptTextMessage(message); - } - - @Override - public void error(int error, Contact contact) { - - } - }); - - } else { - showNoPGPKeyDialog(false, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation - .setNextEncryption(Message.ENCRYPTION_NONE); - xmppService.databaseBackend - .updateConversation(conversation); - message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.sendMessage(message); - messageSent(); - } - }); - } - } else { - if (conversation.getMucOptions().pgpKeysInUse()) { - if (!conversation.getMucOptions().everybodyHasKeys()) { - Toast warning = Toast - .makeText(getActivity(), - R.string.missing_public_keys, - Toast.LENGTH_LONG); - warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0); - warning.show(); - } - activity.encryptTextMessage(message); - messageSent(); - } else { - showNoPGPKeyDialog(true, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation - .setNextEncryption(Message.ENCRYPTION_NONE); - message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.databaseBackend - .updateConversation(conversation); - xmppService.sendMessage(message); - messageSent(); - } - }); - } - } - } else { - activity.showInstallPgpDialog(); - } - } - - public void showNoPGPKeyDialog(boolean plural, - DialogInterface.OnClickListener listener) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - if (plural) { - builder.setTitle(getString(R.string.no_pgp_keys)); - builder.setMessage(getText(R.string.contacts_have_no_pgp_keys)); - } else { - builder.setTitle(getString(R.string.no_pgp_key)); - builder.setMessage(getText(R.string.contact_has_no_pgp_key)); - } - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.send_unencrypted), - listener); - builder.create().show(); - } - - protected void sendOtrMessage(final Message message) { - final ConversationActivity activity = (ConversationActivity) getActivity(); - final XmppConnectionService xmppService = activity.xmppConnectionService; - if (conversation.hasValidOtrSession()) { - activity.xmppConnectionService.sendMessage(message); - messageSent(); - } else { - activity.selectPresence(message.getConversation(), - new OnPresenceSelected() { - - @Override - public void onPresenceSelected() { - message.setPresence(conversation.getNextPresence()); - xmppService.sendMessage(message); - messageSent(); - } - }); - } - } - - public void setText(String text) { - this.pastedText = text; - } - - public void clearInputField() { - this.mEditMessage.setText(""); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java deleted file mode 100644 index 1543d740..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ /dev/null @@ -1,423 +0,0 @@ -package eu.siacs.conversations.ui; - -import android.app.PendingIntent; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Intent; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.AutoCompleteTextView; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; -import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; -import eu.siacs.conversations.utils.UIHelper; -import eu.siacs.conversations.utils.Validator; -import eu.siacs.conversations.xmpp.XmppConnection.Features; -import eu.siacs.conversations.xmpp.pep.Avatar; - -public class EditAccountActivity extends XmppActivity { - - private AutoCompleteTextView mAccountJid; - private EditText mPassword; - private EditText mPasswordConfirm; - private CheckBox mRegisterNew; - private Button mCancelButton; - private Button mSaveButton; - - private LinearLayout mStats; - private TextView mServerInfoSm; - private TextView mServerInfoCarbons; - private TextView mServerInfoPep; - private TextView mSessionEst; - private TextView mOtrFingerprint; - private RelativeLayout mOtrFingerprintBox; - private ImageButton mOtrFingerprintToClipboardButton; - - private String jidToEdit; - private Account mAccount; - - private boolean mFetchingAvatar = false; - - private OnClickListener mSaveButtonClickListener = new OnClickListener() { - - @Override - public void onClick(View v) { - if (mAccount != null - && mAccount.getStatus() == Account.STATUS_DISABLED) { - mAccount.setOption(Account.OPTION_DISABLED, false); - xmppConnectionService.updateAccount(mAccount); - return; - } - if (!Validator.isValidJid(mAccountJid.getText().toString())) { - mAccountJid.setError(getString(R.string.invalid_jid)); - mAccountJid.requestFocus(); - return; - } - boolean registerNewAccount = mRegisterNew.isChecked(); - String[] jidParts = mAccountJid.getText().toString().split("@"); - String username = jidParts[0]; - String server; - if (jidParts.length >= 2) { - server = jidParts[1]; - } else { - server = ""; - } - String password = mPassword.getText().toString(); - String passwordConfirm = mPasswordConfirm.getText().toString(); - if (registerNewAccount) { - if (!password.equals(passwordConfirm)) { - mPasswordConfirm - .setError(getString(R.string.passwords_do_not_match)); - mPasswordConfirm.requestFocus(); - return; - } - } - if (mAccount != null) { - mAccount.setPassword(password); - mAccount.setUsername(username); - mAccount.setServer(server); - mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); - xmppConnectionService.updateAccount(mAccount); - } else { - if (xmppConnectionService.findAccountByJid(mAccountJid - .getText().toString()) != null) { - mAccountJid - .setError(getString(R.string.account_already_exists)); - mAccountJid.requestFocus(); - return; - } - mAccount = new Account(username, server, password); - mAccount.setOption(Account.OPTION_USETLS, true); - mAccount.setOption(Account.OPTION_USECOMPRESSION, true); - mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); - xmppConnectionService.createAccount(mAccount); - } - if (jidToEdit != null) { - finish(); - } else { - updateSaveButton(); - updateAccountInformation(); - } - - } - }; - private OnClickListener mCancelButtonClickListener = new OnClickListener() { - - @Override - public void onClick(View v) { - finish(); - } - }; - private OnAccountUpdate mOnAccountUpdateListener = new OnAccountUpdate() { - - @Override - public void onAccountUpdate() { - runOnUiThread(new Runnable() { - - @Override - public void run() { - if (mAccount != null - && mAccount.getStatus() != Account.STATUS_ONLINE - && mFetchingAvatar) { - startActivity(new Intent(getApplicationContext(), - ManageAccountActivity.class)); - finish(); - } else if (jidToEdit == null && mAccount != null - && mAccount.getStatus() == Account.STATUS_ONLINE) { - if (!mFetchingAvatar) { - mFetchingAvatar = true; - xmppConnectionService.checkForAvatar(mAccount, - mAvatarFetchCallback); - } - } else { - updateSaveButton(); - } - if (mAccount != null) { - updateAccountInformation(); - } - } - }); - } - }; - private UiCallback mAvatarFetchCallback = new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, Avatar avatar) { - finishInitialSetup(avatar); - } - - @Override - public void success(Avatar avatar) { - finishInitialSetup(avatar); - } - - @Override - public void error(int errorCode, Avatar avatar) { - finishInitialSetup(avatar); - } - }; - private KnownHostsAdapter mKnownHostsAdapter; - private TextWatcher mTextWatcher = new TextWatcher() { - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - updateSaveButton(); - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - - } - - @Override - public void afterTextChanged(Editable s) { - - } - }; - - protected void finishInitialSetup(final Avatar avatar) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - Intent intent; - if (avatar != null) { - intent = new Intent(getApplicationContext(), - StartConversationActivity.class); - } else { - intent = new Intent(getApplicationContext(), - PublishProfilePictureActivity.class); - intent.putExtra("account", mAccount.getJid()); - intent.putExtra("setup", true); - } - startActivity(intent); - finish(); - } - }); - } - - protected boolean inputDataDiffersFromAccount() { - if (mAccount == null) { - return true; - } else { - return (!mAccount.getJid().equals(mAccountJid.getText().toString())) - || (!mAccount.getPassword().equals( - mPassword.getText().toString()) || mAccount - .isOptionSet(Account.OPTION_REGISTER) != mRegisterNew - .isChecked()); - } - } - - protected void updateSaveButton() { - if (mAccount != null - && mAccount.getStatus() == Account.STATUS_CONNECTING) { - this.mSaveButton.setEnabled(false); - this.mSaveButton.setTextColor(getSecondaryTextColor()); - this.mSaveButton.setText(R.string.account_status_connecting); - } else if (mAccount != null - && mAccount.getStatus() == Account.STATUS_DISABLED) { - this.mSaveButton.setEnabled(true); - this.mSaveButton.setTextColor(getPrimaryTextColor()); - this.mSaveButton.setText(R.string.enable); - } else { - this.mSaveButton.setEnabled(true); - this.mSaveButton.setTextColor(getPrimaryTextColor()); - if (jidToEdit != null) { - if (mAccount != null - && mAccount.getStatus() == Account.STATUS_ONLINE) { - this.mSaveButton.setText(R.string.save); - if (!accountInfoEdited()) { - this.mSaveButton.setEnabled(false); - this.mSaveButton.setTextColor(getSecondaryTextColor()); - } - } else { - this.mSaveButton.setText(R.string.connect); - } - } else { - this.mSaveButton.setText(R.string.next); - } - } - } - - protected boolean accountInfoEdited() { - return (!this.mAccount.getJid().equals( - this.mAccountJid.getText().toString())) - || (!this.mAccount.getPassword().equals( - this.mPassword.getText().toString())); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_edit_account); - this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid); - this.mAccountJid.addTextChangedListener(this.mTextWatcher); - this.mPassword = (EditText) findViewById(R.id.account_password); - this.mPassword.addTextChangedListener(this.mTextWatcher); - this.mPasswordConfirm = (EditText) findViewById(R.id.account_password_confirm); - this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new); - this.mStats = (LinearLayout) findViewById(R.id.stats); - this.mSessionEst = (TextView) findViewById(R.id.session_est); - this.mServerInfoCarbons = (TextView) findViewById(R.id.server_info_carbons); - this.mServerInfoSm = (TextView) findViewById(R.id.server_info_sm); - this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep); - this.mOtrFingerprint = (TextView) findViewById(R.id.otr_fingerprint); - this.mOtrFingerprintBox = (RelativeLayout) findViewById(R.id.otr_fingerprint_box); - this.mOtrFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_to_clipboard); - this.mSaveButton = (Button) findViewById(R.id.save_button); - this.mCancelButton = (Button) findViewById(R.id.cancel_button); - this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener); - this.mCancelButton.setOnClickListener(this.mCancelButtonClickListener); - this.mRegisterNew - .setOnCheckedChangeListener(new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - if (isChecked) { - mPasswordConfirm.setVisibility(View.VISIBLE); - } else { - mPasswordConfirm.setVisibility(View.GONE); - } - updateSaveButton(); - } - }); - } - - @Override - protected void onStart() { - super.onStart(); - if (getIntent() != null) { - this.jidToEdit = getIntent().getStringExtra("jid"); - if (this.jidToEdit != null) { - this.mRegisterNew.setVisibility(View.GONE); - getActionBar().setTitle(jidToEdit); - } else { - getActionBar().setTitle(R.string.action_add_account); - } - } - } - - @Override - protected void onStop() { - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnAccountListChangedListener(); - } - super.onStop(); - } - - @Override - protected void onBackendConnected() { - this.mKnownHostsAdapter = new KnownHostsAdapter(this, - android.R.layout.simple_list_item_1, - xmppConnectionService.getKnownHosts()); - this.xmppConnectionService - .setOnAccountListChangedListener(this.mOnAccountUpdateListener); - if (this.jidToEdit != null) { - this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit); - updateAccountInformation(); - } else if (this.xmppConnectionService.getAccounts().size() == 0) { - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setDisplayShowHomeEnabled(false); - this.mCancelButton.setEnabled(false); - this.mCancelButton.setTextColor(getSecondaryTextColor()); - } - this.mAccountJid.setAdapter(this.mKnownHostsAdapter); - updateSaveButton(); - } - - private void updateAccountInformation() { - this.mAccountJid.setText(this.mAccount.getJid()); - this.mPassword.setText(this.mAccount.getPassword()); - if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) { - this.mRegisterNew.setVisibility(View.VISIBLE); - this.mRegisterNew.setChecked(true); - this.mPasswordConfirm.setText(this.mAccount.getPassword()); - } else { - this.mRegisterNew.setVisibility(View.GONE); - this.mRegisterNew.setChecked(false); - } - if (this.mAccount.getStatus() == Account.STATUS_ONLINE - && !this.mFetchingAvatar) { - this.mStats.setVisibility(View.VISIBLE); - this.mSessionEst.setText(UIHelper.readableTimeDifference( - getApplicationContext(), this.mAccount.getXmppConnection() - .getLastSessionEstablished())); - Features features = this.mAccount.getXmppConnection().getFeatures(); - if (features.carbons()) { - this.mServerInfoCarbons.setText(R.string.server_info_available); - } else { - this.mServerInfoCarbons - .setText(R.string.server_info_unavailable); - } - if (features.sm()) { - this.mServerInfoSm.setText(R.string.server_info_available); - } else { - this.mServerInfoSm.setText(R.string.server_info_unavailable); - } - if (features.pubsub()) { - this.mServerInfoPep.setText(R.string.server_info_available); - } else { - this.mServerInfoPep.setText(R.string.server_info_unavailable); - } - final String fingerprint = this.mAccount - .getOtrFingerprint(xmppConnectionService); - if (fingerprint != null) { - this.mOtrFingerprintBox.setVisibility(View.VISIBLE); - this.mOtrFingerprint.setText(fingerprint); - this.mOtrFingerprintToClipboardButton - .setVisibility(View.VISIBLE); - this.mOtrFingerprintToClipboardButton - .setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - - if (OtrFingerprintToClipBoard(fingerprint)) { - Toast.makeText( - EditAccountActivity.this, - R.string.toast_message_otr_fingerprint, - Toast.LENGTH_SHORT).show(); - } - } - }); - } else { - this.mOtrFingerprintBox.setVisibility(View.GONE); - } - } else { - if (this.mAccount.errorStatus()) { - this.mAccountJid.setError(getString(this.mAccount - .getReadableStatusId())); - this.mAccountJid.requestFocus(); - } - this.mStats.setVisibility(View.GONE); - } - } - - private boolean OtrFingerprintToClipBoard(String fingerprint) { - ClipboardManager mClipBoardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - String label = getResources().getString(R.string.otr_fingerprint); - if (mClipBoardManager != null) { - ClipData mClipData = ClipData.newPlainText(label, fingerprint); - mClipBoardManager.setPrimaryClip(mClipData); - return true; - } - return false; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/EditMessage.java b/conversations/src/main/java/eu/siacs/conversations/ui/EditMessage.java deleted file mode 100644 index f8302050..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/EditMessage.java +++ /dev/null @@ -1,39 +0,0 @@ -package eu.siacs.conversations.ui; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.KeyEvent; -import android.widget.EditText; - -public class EditMessage extends EditText { - - public EditMessage(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public EditMessage(Context context) { - super(context); - } - - protected OnEnterPressed mOnEnterPressed; - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_ENTER) { - if (mOnEnterPressed != null) { - mOnEnterPressed.onEnterPressed(); - } - return true; - } - return super.onKeyDown(keyCode, event); - } - - public void setOnEnterPressedListener(OnEnterPressed listener) { - this.mOnEnterPressed = listener; - } - - public interface OnEnterPressed { - public void onEnterPressed(); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java deleted file mode 100644 index 5b5b0608..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java +++ /dev/null @@ -1,217 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.List; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; -import eu.siacs.conversations.ui.adapter.AccountAdapter; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.os.Bundle; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ContextMenu.ContextMenuInfo; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - -public class ManageAccountActivity extends XmppActivity { - - protected Account selectedAccount = null; - - protected List accountList = new ArrayList(); - protected ListView accountListView; - protected AccountAdapter mAccountAdapter; - protected OnAccountUpdate accountChanged = new OnAccountUpdate() { - - @Override - public void onAccountUpdate() { - accountList.clear(); - accountList.addAll(xmppConnectionService.getAccounts()); - runOnUiThread(new Runnable() { - - @Override - public void run() { - mAccountAdapter.notifyDataSetChanged(); - } - }); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - setContentView(R.layout.manage_accounts); - - accountListView = (ListView) findViewById(R.id.account_list); - this.mAccountAdapter = new AccountAdapter(this, accountList); - accountListView.setAdapter(this.mAccountAdapter); - accountListView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View view, - int position, long arg3) { - switchToAccount(accountList.get(position)); - } - }); - registerForContextMenu(accountListView); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - ManageAccountActivity.this.getMenuInflater().inflate( - R.menu.manageaccounts_context, menu); - AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; - this.selectedAccount = accountList.get(acmi.position); - if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) { - menu.findItem(R.id.mgmt_account_disable).setVisible(false); - menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(false); - menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false); - } else { - menu.findItem(R.id.mgmt_account_enable).setVisible(false); - } - menu.setHeaderTitle(this.selectedAccount.getJid()); - } - - @Override - protected void onStop() { - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnAccountListChangedListener(); - } - super.onStop(); - } - - @Override - void onBackendConnected() { - xmppConnectionService.setOnAccountListChangedListener(accountChanged); - this.accountList.clear(); - this.accountList.addAll(xmppConnectionService.getAccounts()); - mAccountAdapter.notifyDataSetChanged(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.manageaccounts, menu); - return true; - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.mgmt_account_publish_avatar: - publishAvatar(selectedAccount); - return true; - case R.id.mgmt_account_disable: - disableAccount(selectedAccount); - return true; - case R.id.mgmt_account_enable: - enableAccount(selectedAccount); - return true; - case R.id.mgmt_account_delete: - deleteAccount(selectedAccount); - return true; - case R.id.mgmt_account_announce_pgp: - publishOpenPGPPublicKey(selectedAccount); - default: - return super.onContextItemSelected(item); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_add_account: - startActivity(new Intent(getApplicationContext(), - EditAccountActivity.class)); - break; - default: - break; - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onNavigateUp() { - if (xmppConnectionService.getConversations().size() == 0) { - Intent contactsIntent = new Intent(this, - StartConversationActivity.class); - contactsIntent.setFlags( - // if activity exists in stack, pop the stack and go back to it - Intent.FLAG_ACTIVITY_CLEAR_TOP | - // otherwise, make a new task for it - Intent.FLAG_ACTIVITY_NEW_TASK | - // don't use the new activity animation; finish - // animation runs instead - Intent.FLAG_ACTIVITY_NO_ANIMATION); - startActivity(contactsIntent); - finish(); - return true; - } else { - return super.onNavigateUp(); - } - } - - private void publishAvatar(Account account) { - Intent intent = new Intent(getApplicationContext(), - PublishProfilePictureActivity.class); - intent.putExtra("account", account.getJid()); - startActivity(intent); - } - - private void disableAccount(Account account) { - account.setOption(Account.OPTION_DISABLED, true); - xmppConnectionService.updateAccount(account); - } - - private void enableAccount(Account account) { - account.setOption(Account.OPTION_DISABLED, false); - xmppConnectionService.updateAccount(account); - } - - private void publishOpenPGPPublicKey(Account account) { - if (ManageAccountActivity.this.hasPgp()) { - announcePgp(account, null); - } else { - this.showInstallPgpDialog(); - } - } - - private void deleteAccount(final Account account) { - AlertDialog.Builder builder = new AlertDialog.Builder( - ManageAccountActivity.this); - builder.setTitle(getString(R.string.mgmt_account_are_you_sure)); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text)); - builder.setPositiveButton(getString(R.string.delete), - new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - xmppConnectionService.deleteAccount(account); - selectedAccount = null; - } - }); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.create().show(); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - if (requestCode == REQUEST_ANNOUNCE_PGP) { - announcePgp(selectedAccount, null); - } - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java deleted file mode 100644 index 6aa40c41..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ /dev/null @@ -1,242 +0,0 @@ -package eu.siacs.conversations.ui; - -import android.app.PendingIntent; -import android.content.Intent; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.utils.PhoneHelper; -import eu.siacs.conversations.xmpp.pep.Avatar; - -public class PublishProfilePictureActivity extends XmppActivity { - - private static final int REQUEST_CHOOSE_FILE = 0xac23; - - private ImageView avatar; - private TextView accountTextView; - private TextView hintOrWarning; - private TextView secondaryHint; - private Button cancelButton; - private Button publishButton; - - private Uri avatarUri; - private Uri defaultUri; - - private Account account; - - private boolean support = false; - - private boolean mInitialAccountSetup; - - private UiCallback avatarPublication = new UiCallback() { - - @Override - public void success(Avatar object) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - if (mInitialAccountSetup) { - startActivity(new Intent(getApplicationContext(), - StartConversationActivity.class)); - } - finish(); - } - }); - } - - @Override - public void error(final int errorCode, Avatar object) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - hintOrWarning.setText(errorCode); - hintOrWarning.setTextColor(getWarningTextColor()); - publishButton.setText(R.string.publish); - enablePublishButton(); - } - }); - - } - - @Override - public void userInputRequried(PendingIntent pi, Avatar object) { - } - }; - - private OnLongClickListener backToDefaultListener = new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - avatarUri = defaultUri; - loadImageIntoPreview(defaultUri); - return true; - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_publish_profile_picture); - this.avatar = (ImageView) findViewById(R.id.account_image); - this.cancelButton = (Button) findViewById(R.id.cancel_button); - this.publishButton = (Button) findViewById(R.id.publish_button); - this.accountTextView = (TextView) findViewById(R.id.account); - this.hintOrWarning = (TextView) findViewById(R.id.hint_or_warning); - this.secondaryHint = (TextView) findViewById(R.id.secondary_hint); - this.publishButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (avatarUri != null) { - publishButton.setText(R.string.publishing); - disablePublishButton(); - xmppConnectionService.publishAvatar(account, avatarUri, - avatarPublication); - } - } - }); - this.cancelButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (mInitialAccountSetup) { - startActivity(new Intent(getApplicationContext(), - StartConversationActivity.class)); - } - finish(); - } - }); - this.avatar.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - Intent attachFileIntent = new Intent(); - attachFileIntent.setType("image/*"); - attachFileIntent.setAction(Intent.ACTION_GET_CONTENT); - Intent chooser = Intent.createChooser(attachFileIntent, - getString(R.string.attach_file)); - startActivityForResult(chooser, REQUEST_CHOOSE_FILE); - } - }); - this.defaultUri = PhoneHelper.getSefliUri(getApplicationContext()); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, - final Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - if (requestCode == REQUEST_CHOOSE_FILE) { - this.avatarUri = data.getData(); - if (xmppConnectionServiceBound) { - loadImageIntoPreview(this.avatarUri); - } - } - } - } - - @Override - protected void onBackendConnected() { - if (getIntent() != null) { - String jid = getIntent().getStringExtra("account"); - if (jid != null) { - this.account = xmppConnectionService.findAccountByJid(jid); - if (this.account.getXmppConnection() != null) { - this.support = this.account.getXmppConnection() - .getFeatures().pubsub(); - } - if (this.avatarUri == null) { - if (this.account.getAvatar() != null - || this.defaultUri == null) { - this.avatar.setImageBitmap(avatarService().get(account, - getPixel(194))); - if (this.defaultUri != null) { - this.avatar - .setOnLongClickListener(this.backToDefaultListener); - } else { - this.secondaryHint.setVisibility(View.INVISIBLE); - } - if (!support) { - this.hintOrWarning - .setTextColor(getWarningTextColor()); - this.hintOrWarning - .setText(R.string.error_publish_avatar_no_server_support); - } - } else { - this.avatarUri = this.defaultUri; - loadImageIntoPreview(this.defaultUri); - this.secondaryHint.setVisibility(View.INVISIBLE); - } - } else { - loadImageIntoPreview(avatarUri); - } - this.accountTextView.setText(this.account.getJid()); - } - } - - } - - @Override - protected void onStart() { - super.onStart(); - if (getIntent() != null) { - this.mInitialAccountSetup = getIntent().getBooleanExtra("setup", - false); - } - if (this.mInitialAccountSetup) { - this.cancelButton.setText(R.string.skip); - } - } - - protected void loadImageIntoPreview(Uri uri) { - Bitmap bm = xmppConnectionService.getFileBackend().cropCenterSquare( - uri, 384); - if (bm == null) { - disablePublishButton(); - this.hintOrWarning.setTextColor(getWarningTextColor()); - this.hintOrWarning - .setText(R.string.error_publish_avatar_converting); - return; - } - this.avatar.setImageBitmap(bm); - if (support) { - enablePublishButton(); - this.publishButton.setText(R.string.publish); - this.hintOrWarning.setText(R.string.publish_avatar_explanation); - this.hintOrWarning.setTextColor(getPrimaryTextColor()); - } else { - disablePublishButton(); - this.hintOrWarning.setTextColor(getWarningTextColor()); - this.hintOrWarning - .setText(R.string.error_publish_avatar_no_server_support); - } - if (this.defaultUri != null && uri.equals(this.defaultUri)) { - this.secondaryHint.setVisibility(View.INVISIBLE); - this.avatar.setOnLongClickListener(null); - } else if (this.defaultUri != null) { - this.secondaryHint.setVisibility(View.VISIBLE); - this.avatar.setOnLongClickListener(this.backToDefaultListener); - } - } - - protected void enablePublishButton() { - this.publishButton.setEnabled(true); - this.publishButton.setTextColor(getPrimaryTextColor()); - } - - protected void disablePublishButton() { - this.publishButton.setEnabled(false); - this.publishButton.setTextColor(getSecondaryTextColor()); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java deleted file mode 100644 index fc6308fc..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ /dev/null @@ -1,74 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; - -import eu.siacs.conversations.entities.Account; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Build; -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.PreferenceManager; - -public class SettingsActivity extends XmppActivity implements - OnSharedPreferenceChangeListener { - private SettingsFragment mSettingsFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mSettingsFragment = new SettingsFragment(); - getFragmentManager().beginTransaction() - .replace(android.R.id.content, mSettingsFragment).commit(); - } - - @Override - void onBackendConnected() { - - } - - @Override - public void onStart() { - super.onStart(); - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(this); - ListPreference resources = (ListPreference) mSettingsFragment - .findPreference("resource"); - if (resources != null) { - ArrayList entries = new ArrayList( - Arrays.asList(resources.getEntries())); - entries.add(0, Build.MODEL); - resources.setEntries(entries.toArray(new CharSequence[entries - .size()])); - resources.setEntryValues(entries.toArray(new CharSequence[entries - .size()])); - } - } - - @Override - public void onStop() { - super.onStop(); - PreferenceManager.getDefaultSharedPreferences(this) - .unregisterOnSharedPreferenceChangeListener(this); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences preferences, - String name) { - if (name.equals("resource")) { - String resource = preferences.getString("resource", "mobile") - .toLowerCase(Locale.US); - if (xmppConnectionServiceBound) { - for (Account account : xmppConnectionService.getAccounts()) { - account.setResource(resource); - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - xmppConnectionService.reconnectAccount(account, false); - } - } - } - } - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/SettingsFragment.java b/conversations/src/main/java/eu/siacs/conversations/ui/SettingsFragment.java deleted file mode 100644 index 7e1c3698..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/SettingsFragment.java +++ /dev/null @@ -1,15 +0,0 @@ -package eu.siacs.conversations.ui; - -import eu.siacs.conversations.R; -import android.os.Bundle; -import android.preference.PreferenceFragment; - -public class SettingsFragment extends PreferenceFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.preferences); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java deleted file mode 100644 index 9fbc3db1..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ /dev/null @@ -1,185 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.List; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.ui.adapter.ConversationAdapter; -import android.app.PendingIntent; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; -import android.widget.Toast; - -public class ShareWithActivity extends XmppActivity { - - private class Share { - public Uri uri; - public String account; - public String contact; - public String text; - } - - private Share share; - - private static final int REQUEST_START_NEW_CONVERSATION = 0x0501; - private ListView mListView; - private List mConversations = new ArrayList(); - - private UiCallback attachImageCallback = new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, Message object) { - // TODO Auto-generated method stub - - } - - @Override - public void success(Message message) { - xmppConnectionService.sendMessage(message); - } - - @Override - public void error(int errorCode, Message object) { - // TODO Auto-generated method stub - - } - }; - - protected void onActivityResult(int requestCode, int resultCode, - final Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_START_NEW_CONVERSATION - && resultCode == RESULT_OK) { - share.contact = data.getStringExtra("contact"); - share.account = data.getStringExtra("account"); - Log.d(Config.LOGTAG, "contact: " + share.contact + " account:" - + share.account); - } - if (xmppConnectionServiceBound && share != null - && share.contact != null && share.account != null) { - share(); - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - - setContentView(R.layout.share_with); - setTitle(getString(R.string.title_activity_sharewith)); - - mListView = (ListView) findViewById(R.id.choose_conversation_list); - ConversationAdapter mAdapter = new ConversationAdapter(this, - this.mConversations); - mListView.setAdapter(mAdapter); - mListView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View arg1, - int position, long arg3) { - Conversation conversation = mConversations.get(position); - if (conversation.getMode() == Conversation.MODE_SINGLE - || share.uri == null) { - share(mConversations.get(position)); - } - } - }); - - this.share = new Share(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.share_with, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_add: - Intent intent = new Intent(getApplicationContext(), - ChooseContactActivity.class); - startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onStart() { - if (getIntent().getType() != null - && getIntent().getType().startsWith("image/")) { - this.share.uri = (Uri) getIntent().getParcelableExtra( - Intent.EXTRA_STREAM); - } else { - this.share.text = getIntent().getStringExtra(Intent.EXTRA_TEXT); - } - if (xmppConnectionServiceBound) { - xmppConnectionService.populateWithOrderedConversations( - mConversations, this.share.uri == null); - } - super.onStart(); - } - - @Override - void onBackendConnected() { - if (xmppConnectionServiceBound && share != null - && share.contact != null && share.account != null) { - share(); - return; - } - xmppConnectionService.populateWithOrderedConversations(mConversations, - this.share != null && this.share.uri == null); - } - - private void share() { - Account account = xmppConnectionService.findAccountByJid(share.account); - if (account == null) { - return; - } - Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, share.contact, false); - share(conversation); - } - - private void share(final Conversation conversation) { - if (share.uri != null) { - selectPresence(conversation, new OnPresenceSelected() { - @Override - public void onPresenceSelected() { - Toast.makeText(getApplicationContext(), - getText(R.string.preparing_image), - Toast.LENGTH_LONG).show(); - ShareWithActivity.this.xmppConnectionService - .attachImageToConversation(conversation, share.uri, - attachImageCallback); - switchToConversation(conversation, null, true); - finish(); - } - }); - - } else { - switchToConversation(conversation, this.share.text, true); - finish(); - } - - } - -} \ No newline at end of file diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java deleted file mode 100644 index a1a2d4c2..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ /dev/null @@ -1,677 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import android.annotation.SuppressLint; -import android.app.ActionBar; -import android.app.ActionBar.Tab; -import android.app.ActionBar.TabListener; -import android.app.AlertDialog; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.app.ListFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.v13.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.Spinner; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Bookmark; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.ListItem; -import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; -import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; -import eu.siacs.conversations.ui.adapter.ListItemAdapter; -import eu.siacs.conversations.utils.Validator; - -public class StartConversationActivity extends XmppActivity { - - private Tab mContactsTab; - private Tab mConferencesTab; - private ViewPager mViewPager; - - private MyListFragment mContactsListFragment = new MyListFragment(); - private List contacts = new ArrayList(); - private ArrayAdapter mContactsAdapter; - - private MyListFragment mConferenceListFragment = new MyListFragment(); - private List conferences = new ArrayList(); - private ArrayAdapter mConferenceAdapter; - - private List mActivatedAccounts = new ArrayList(); - private List mKnownHosts; - private List mKnownConferenceHosts; - - private Menu mOptionsMenu; - private EditText mSearchEditText; - - public int conference_context_id; - public int contact_context_id; - - private TabListener mTabListener = new TabListener() { - - @Override - public void onTabUnselected(Tab tab, FragmentTransaction ft) { - return; - } - - @Override - public void onTabSelected(Tab tab, FragmentTransaction ft) { - mViewPager.setCurrentItem(tab.getPosition()); - onTabChanged(); - } - - @Override - public void onTabReselected(Tab tab, FragmentTransaction ft) { - return; - } - }; - - private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - getActionBar().setSelectedNavigationItem(position); - onTabChanged(); - } - }; - - private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() { - - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - mSearchEditText.post(new Runnable() { - - @Override - public void run() { - mSearchEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mSearchEditText, - InputMethodManager.SHOW_IMPLICIT); - } - }); - - return true; - } - - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), - InputMethodManager.HIDE_IMPLICIT_ONLY); - mSearchEditText.setText(""); - filter(null); - return true; - } - }; - private TextWatcher mSearchTextWatcher = new TextWatcher() { - - @Override - public void afterTextChanged(Editable editable) { - filter(editable.toString()); - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - } - }; - private OnRosterUpdate onRosterUpdate = new OnRosterUpdate() { - - @Override - public void onRosterUpdate() { - runOnUiThread(new Runnable() { - - @Override - public void run() { - if (mSearchEditText != null) { - filter(mSearchEditText.getText().toString()); - } - } - }); - } - }; - private MenuItem mMenuSearchView; - private String mInitialJid; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_start_conversation); - mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager); - ActionBar actionBar = getActionBar(); - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); - - mContactsTab = actionBar.newTab().setText(R.string.contacts) - .setTabListener(mTabListener); - mConferencesTab = actionBar.newTab().setText(R.string.conferences) - .setTabListener(mTabListener); - actionBar.addTab(mContactsTab); - actionBar.addTab(mConferencesTab); - - mViewPager.setOnPageChangeListener(mOnPageChangeListener); - mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) { - - @Override - public int getCount() { - return 2; - } - - @Override - public Fragment getItem(int position) { - if (position == 0) { - return mContactsListFragment; - } else { - return mConferenceListFragment; - } - } - }); - - mConferenceAdapter = new ListItemAdapter(this, conferences); - mConferenceListFragment.setListAdapter(mConferenceAdapter); - mConferenceListFragment.setContextMenu(R.menu.conference_context); - mConferenceListFragment - .setOnListItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View arg1, - int position, long arg3) { - openConversationForBookmark(position); - } - }); - - mContactsAdapter = new ListItemAdapter(this, contacts); - mContactsListFragment.setListAdapter(mContactsAdapter); - mContactsListFragment.setContextMenu(R.menu.contact_context); - mContactsListFragment - .setOnListItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View arg1, - int position, long arg3) { - openConversationForContact(position); - } - }); - - } - - @Override - public void onStop() { - super.onStop(); - xmppConnectionService.removeOnRosterUpdateListener(); - } - - protected void openConversationForContact(int position) { - Contact contact = (Contact) contacts.get(position); - Conversation conversation = xmppConnectionService - .findOrCreateConversation(contact.getAccount(), - contact.getJid(), false); - switchToConversation(conversation); - } - - protected void openConversationForContact() { - int position = contact_context_id; - openConversationForContact(position); - } - - protected void openConversationForBookmark() { - openConversationForBookmark(conference_context_id); - } - - protected void openConversationForBookmark(int position) { - Bookmark bookmark = (Bookmark) conferences.get(position); - Conversation conversation = xmppConnectionService - .findOrCreateConversation(bookmark.getAccount(), - bookmark.getJid(), true); - conversation.setBookmark(bookmark); - if (!conversation.getMucOptions().online()) { - xmppConnectionService.joinMuc(conversation); - } - if (!bookmark.autojoin()) { - bookmark.setAutojoin(true); - xmppConnectionService.pushBookmarks(bookmark.getAccount()); - } - switchToConversation(conversation); - } - - protected void openDetailsForContact() { - int position = contact_context_id; - Contact contact = (Contact) contacts.get(position); - switchToContactDetails(contact); - } - - protected void deleteContact() { - int position = contact_context_id; - final Contact contact = (Contact) contacts.get(position); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setNegativeButton(R.string.cancel, null); - builder.setTitle(R.string.action_delete_contact); - builder.setMessage(getString(R.string.remove_contact_text, - contact.getJid())); - builder.setPositiveButton(R.string.delete, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - xmppConnectionService.deleteContactOnServer(contact); - filter(mSearchEditText.getText().toString()); - } - }); - builder.create().show(); - - } - - protected void deleteConference() { - int position = conference_context_id; - final Bookmark bookmark = (Bookmark) conferences.get(position); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setNegativeButton(R.string.cancel, null); - builder.setTitle(R.string.delete_bookmark); - builder.setMessage(getString(R.string.remove_bookmark_text, - bookmark.getJid())); - builder.setPositiveButton(R.string.delete, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - bookmark.unregisterConversation(); - Account account = bookmark.getAccount(); - account.getBookmarks().remove(bookmark); - xmppConnectionService.pushBookmarks(account); - filter(mSearchEditText.getText().toString()); - } - }); - builder.create().show(); - - } - - @SuppressLint("InflateParams") - protected void showCreateContactDialog(String prefilledJid) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.create_contact); - View dialogView = getLayoutInflater().inflate( - R.layout.create_contact_dialog, null); - final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account); - final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView - .findViewById(R.id.jid); - jid.setAdapter(new KnownHostsAdapter(this, - android.R.layout.simple_list_item_1, mKnownHosts)); - if (prefilledJid != null) { - jid.append(prefilledJid); - } - populateAccountSpinner(spinner); - builder.setView(dialogView); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.create, null); - final AlertDialog dialog = builder.create(); - dialog.show(); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( - new View.OnClickListener() { - - @Override - public void onClick(View v) { - if (!xmppConnectionServiceBound) { - return; - } - if (Validator.isValidJid(jid.getText().toString())) { - String accountJid = (String) spinner - .getSelectedItem(); - String contactJid = jid.getText().toString(); - Account account = xmppConnectionService - .findAccountByJid(accountJid); - if (account == null) { - dialog.dismiss(); - return; - } - Contact contact = account.getRoster().getContact( - contactJid); - if (contact.showInRoster()) { - jid.setError(getString(R.string.contact_already_exists)); - } else { - xmppConnectionService.createContact(contact); - dialog.dismiss(); - switchToConversation(contact); - } - } else { - jid.setError(getString(R.string.invalid_jid)); - } - } - }); - - } - - @SuppressLint("InflateParams") - protected void showJoinConferenceDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.join_conference); - View dialogView = getLayoutInflater().inflate( - R.layout.join_conference_dialog, null); - final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account); - final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView - .findViewById(R.id.jid); - jid.setAdapter(new KnownHostsAdapter(this, - android.R.layout.simple_list_item_1, mKnownConferenceHosts)); - populateAccountSpinner(spinner); - final CheckBox bookmarkCheckBox = (CheckBox) dialogView - .findViewById(R.id.bookmark); - builder.setView(dialogView); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.join, null); - final AlertDialog dialog = builder.create(); - dialog.show(); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( - new View.OnClickListener() { - - @Override - public void onClick(View v) { - if (!xmppConnectionServiceBound) { - return; - } - if (Validator.isValidJid(jid.getText().toString())) { - String accountJid = (String) spinner - .getSelectedItem(); - String conferenceJid = jid.getText().toString(); - Account account = xmppConnectionService - .findAccountByJid(accountJid); - if (account == null) { - dialog.dismiss(); - return; - } - if (bookmarkCheckBox.isChecked()) { - if (account.hasBookmarkFor(conferenceJid)) { - jid.setError(getString(R.string.bookmark_already_exists)); - } else { - Bookmark bookmark = new Bookmark(account, - conferenceJid); - bookmark.setAutojoin(true); - account.getBookmarks().add(bookmark); - xmppConnectionService - .pushBookmarks(account); - Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, - conferenceJid, true); - conversation.setBookmark(bookmark); - if (!conversation.getMucOptions().online()) { - xmppConnectionService - .joinMuc(conversation); - } - dialog.dismiss(); - switchToConversation(conversation); - } - } else { - Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, - conferenceJid, true); - if (!conversation.getMucOptions().online()) { - xmppConnectionService.joinMuc(conversation); - } - dialog.dismiss(); - switchToConversation(conversation); - } - } else { - jid.setError(getString(R.string.invalid_jid)); - } - } - }); - } - - protected void switchToConversation(Contact contact) { - Conversation conversation = xmppConnectionService - .findOrCreateConversation(contact.getAccount(), - contact.getJid(), false); - switchToConversation(conversation); - } - - private void populateAccountSpinner(Spinner spinner) { - ArrayAdapter adapter = new ArrayAdapter(this, - android.R.layout.simple_spinner_item, mActivatedAccounts); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - this.mOptionsMenu = menu; - getMenuInflater().inflate(R.menu.start_conversation, menu); - MenuItem menuCreateContact = (MenuItem) menu - .findItem(R.id.action_create_contact); - MenuItem menuCreateConference = (MenuItem) menu - .findItem(R.id.action_join_conference); - mMenuSearchView = (MenuItem) menu.findItem(R.id.action_search); - mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener); - View mSearchView = mMenuSearchView.getActionView(); - mSearchEditText = (EditText) mSearchView - .findViewById(R.id.search_field); - mSearchEditText.addTextChangedListener(mSearchTextWatcher); - if (getActionBar().getSelectedNavigationIndex() == 0) { - menuCreateConference.setVisible(false); - } else { - menuCreateContact.setVisible(false); - } - if (mInitialJid != null) { - mMenuSearchView.expandActionView(); - mSearchEditText.append(mInitialJid); - filter(mInitialJid); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_create_contact: - showCreateContactDialog(null); - break; - case R.id.action_join_conference: - showJoinConferenceDialog(); - break; - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_SEARCH && !event.isLongPress()) { - mOptionsMenu.findItem(R.id.action_search).expandActionView(); - return true; - } - return super.onKeyUp(keyCode, event); - } - - @Override - protected void onBackendConnected() { - xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate); - this.mActivatedAccounts.clear(); - for (Account account : xmppConnectionService.getAccounts()) { - if (account.getStatus() != Account.STATUS_DISABLED) { - this.mActivatedAccounts.add(account.getJid()); - } - } - this.mKnownHosts = xmppConnectionService.getKnownHosts(); - this.mKnownConferenceHosts = xmppConnectionService - .getKnownConferenceHosts(); - if (!startByIntent()) { - if (mSearchEditText != null) { - filter(mSearchEditText.getText().toString()); - } else { - filter(null); - } - } - } - - protected boolean startByIntent() { - if (getIntent() != null - && Intent.ACTION_SENDTO.equals(getIntent().getAction())) { - try { - String jid = URLDecoder.decode( - getIntent().getData().getEncodedPath(), "UTF-8").split( - "/")[1]; - setIntent(null); - return handleJid(jid); - } catch (UnsupportedEncodingException e) { - setIntent(null); - return false; - } - } else if (getIntent() != null - && Intent.ACTION_VIEW.equals(getIntent().getAction())) { - Uri uri = getIntent().getData(); - String jid = uri.getSchemeSpecificPart().split("\\?")[0]; - return handleJid(jid); - } - return false; - } - - private boolean handleJid(String jid) { - List contacts = xmppConnectionService.findContacts(jid); - if (contacts.size() == 0) { - showCreateContactDialog(jid); - return false; - } else if (contacts.size() == 1) { - switchToConversation(contacts.get(0)); - return true; - } else { - if (mMenuSearchView != null) { - mMenuSearchView.expandActionView(); - mSearchEditText.setText(jid); - filter(jid); - } else { - mInitialJid = jid; - } - return true; - } - } - - protected void filter(String needle) { - if (xmppConnectionServiceBound) { - this.filterContacts(needle); - this.filterConferences(needle); - } - } - - protected void filterContacts(String needle) { - this.contacts.clear(); - for (Account account : xmppConnectionService.getAccounts()) { - if (account.getStatus() != Account.STATUS_DISABLED) { - for (Contact contact : account.getRoster().getContacts()) { - if (contact.showInRoster() && contact.match(needle)) { - this.contacts.add(contact); - } - } - } - } - Collections.sort(this.contacts); - mContactsAdapter.notifyDataSetChanged(); - } - - protected void filterConferences(String needle) { - this.conferences.clear(); - for (Account account : xmppConnectionService.getAccounts()) { - if (account.getStatus() != Account.STATUS_DISABLED) { - for (Bookmark bookmark : account.getBookmarks()) { - if (bookmark.match(needle)) { - this.conferences.add(bookmark); - } - } - } - } - Collections.sort(this.conferences); - mConferenceAdapter.notifyDataSetChanged(); - } - - private void onTabChanged() { - invalidateOptionsMenu(); - } - - public static class MyListFragment extends ListFragment { - private AdapterView.OnItemClickListener mOnItemClickListener; - private int mResContextMenu; - - public void setContextMenu(int res) { - this.mResContextMenu = res; - } - - @Override - public void onListItemClick(ListView l, View v, int position, long id) { - if (mOnItemClickListener != null) { - mOnItemClickListener.onItemClick(l, v, position, id); - } - } - - public void setOnListItemClickListener(AdapterView.OnItemClickListener l) { - this.mOnItemClickListener = l; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - registerForContextMenu(getListView()); - getListView().setFastScrollEnabled(true); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - StartConversationActivity activity = (StartConversationActivity) getActivity(); - activity.getMenuInflater().inflate(mResContextMenu, menu); - AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; - if (mResContextMenu == R.menu.conference_context) { - activity.conference_context_id = acmi.position; - } else { - activity.contact_context_id = acmi.position; - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - StartConversationActivity activity = (StartConversationActivity) getActivity(); - switch (item.getItemId()) { - case R.id.context_start_conversation: - activity.openConversationForContact(); - break; - case R.id.context_contact_details: - activity.openDetailsForContact(); - break; - case R.id.context_delete_contact: - activity.deleteContact(); - break; - case R.id.context_join_conference: - activity.openConversationForBookmark(); - break; - case R.id.context_delete_conference: - activity.deleteConference(); - } - return true; - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/UiCallback.java b/conversations/src/main/java/eu/siacs/conversations/ui/UiCallback.java deleted file mode 100644 index c80199e1..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/UiCallback.java +++ /dev/null @@ -1,11 +0,0 @@ -package eu.siacs.conversations.ui; - -import android.app.PendingIntent; - -public interface UiCallback { - public void success(T object); - - public void error(int errorCode, T object); - - public void userInputRequried(PendingIntent pi, T object); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/conversations/src/main/java/eu/siacs/conversations/ui/XmppActivity.java deleted file mode 100644 index d26f0e31..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ /dev/null @@ -1,637 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.io.FileNotFoundException; -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.concurrent.RejectedExecutionException; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.Presences; -import eu.siacs.conversations.services.AvatarService; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; -import eu.siacs.conversations.utils.ExceptionHelper; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.app.AlertDialog.Builder; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.DialogInterface.OnClickListener; -import android.content.IntentSender.SendIntentException; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.content.Intent; -import android.content.ServiceConnection; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.text.InputType; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.ImageView; - -public abstract class XmppActivity extends Activity { - - protected static final int REQUEST_ANNOUNCE_PGP = 0x0101; - protected static final int REQUEST_INVITE_TO_CONVERSATION = 0x0102; - - public XmppConnectionService xmppConnectionService; - public boolean xmppConnectionServiceBound = false; - protected boolean handledViewIntent = false; - - protected int mPrimaryTextColor; - protected int mSecondaryTextColor; - protected int mSecondaryBackgroundColor; - protected int mColorRed; - protected int mColorOrange; - protected int mColorGreen; - protected int mPrimaryColor; - - protected boolean mUseSubject = true; - - private DisplayMetrics metrics; - - protected interface OnValueEdited { - public void onValueEdited(String value); - } - - public interface OnPresenceSelected { - public void onPresenceSelected(); - } - - protected ServiceConnection mConnection = new ServiceConnection() { - - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - XmppConnectionBinder binder = (XmppConnectionBinder) service; - xmppConnectionService = binder.getService(); - xmppConnectionServiceBound = true; - onBackendConnected(); - } - - @Override - public void onServiceDisconnected(ComponentName arg0) { - xmppConnectionServiceBound = false; - } - }; - - @Override - protected void onStart() { - super.onStart(); - if (!xmppConnectionServiceBound) { - connectToBackend(); - } - } - - public void connectToBackend() { - Intent intent = new Intent(this, XmppConnectionService.class); - intent.setAction("ui"); - startService(intent); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - - @Override - protected void onStop() { - super.onStop(); - if (xmppConnectionServiceBound) { - unbindService(mConnection); - xmppConnectionServiceBound = false; - } - } - - protected void hideKeyboard() { - InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - - View focus = getCurrentFocus(); - - if (focus != null) { - - inputManager.hideSoftInputFromWindow(focus.getWindowToken(), - InputMethodManager.HIDE_NOT_ALWAYS); - } - } - - public boolean hasPgp() { - return xmppConnectionService.getPgpEngine() != null; - } - - public void showInstallPgpDialog() { - Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.openkeychain_required)); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage(getText(R.string.openkeychain_required_long)); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setNeutralButton(getString(R.string.restart), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - if (xmppConnectionServiceBound) { - unbindService(mConnection); - xmppConnectionServiceBound = false; - } - stopService(new Intent(XmppActivity.this, - XmppConnectionService.class)); - finish(); - } - }); - builder.setPositiveButton(getString(R.string.install), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Uri uri = Uri - .parse("market://details?id=org.sufficientlysecure.keychain"); - Intent marketIntent = new Intent(Intent.ACTION_VIEW, - uri); - PackageManager manager = getApplicationContext() - .getPackageManager(); - List infos = manager - .queryIntentActivities(marketIntent, 0); - if (infos.size() > 0) { - startActivity(marketIntent); - } else { - uri = Uri.parse("http://www.openkeychain.org/"); - Intent browserIntent = new Intent( - Intent.ACTION_VIEW, uri); - startActivity(browserIntent); - } - finish(); - } - }); - builder.create().show(); - } - - abstract void onBackendConnected(); - - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_settings: - startActivity(new Intent(this, SettingsActivity.class)); - break; - case R.id.action_accounts: - startActivity(new Intent(this, ManageAccountActivity.class)); - break; - case android.R.id.home: - finish(); - break; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - metrics = getResources().getDisplayMetrics(); - ExceptionHelper.init(getApplicationContext()); - mPrimaryTextColor = getResources().getColor(R.color.primarytext); - mSecondaryTextColor = getResources().getColor(R.color.secondarytext); - mColorRed = getResources().getColor(R.color.red); - mColorOrange = getResources().getColor(R.color.orange); - mColorGreen = getResources().getColor(R.color.green); - mPrimaryColor = getResources().getColor(R.color.primary); - mSecondaryBackgroundColor = getResources().getColor( - R.color.secondarybackground); - if (getPreferences().getBoolean("use_larger_font", false)) { - setTheme(R.style.ConversationsTheme_LargerText); - } - mUseSubject = getPreferences().getBoolean("use_subject", true); - } - - protected SharedPreferences getPreferences() { - return PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - } - - public boolean useSubjectToIdentifyConference() { - return mUseSubject; - } - - public void switchToConversation(Conversation conversation) { - switchToConversation(conversation, null, false); - } - - public void switchToConversation(Conversation conversation, String text, - boolean newTask) { - Intent viewConversationIntent = new Intent(this, - ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - conversation.getUuid()); - if (text != null) { - viewConversationIntent.putExtra(ConversationActivity.TEXT, text); - } - viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); - if (newTask) { - viewConversationIntent.setFlags(viewConversationIntent.getFlags() - | Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_SINGLE_TOP); - } else { - viewConversationIntent.setFlags(viewConversationIntent.getFlags() - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - } - startActivity(viewConversationIntent); - finish(); - } - - public void switchToContactDetails(Contact contact) { - Intent intent = new Intent(this, ContactDetailsActivity.class); - intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT); - intent.putExtra("account", contact.getAccount().getJid()); - intent.putExtra("contact", contact.getJid()); - startActivity(intent); - } - - public void switchToAccount(Account account) { - Intent intent = new Intent(this, EditAccountActivity.class); - intent.putExtra("jid", account.getJid()); - startActivity(intent); - } - - protected void inviteToConversation(Conversation conversation) { - Intent intent = new Intent(getApplicationContext(), - ChooseContactActivity.class); - intent.putExtra("conversation", conversation.getUuid()); - startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION); - } - - protected void announcePgp(Account account, final Conversation conversation) { - xmppConnectionService.getPgpEngine().generateSignature(account, - "online", new UiCallback() { - - @Override - public void userInputRequried(PendingIntent pi, - Account account) { - try { - startIntentSenderForResult(pi.getIntentSender(), - REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); - } catch (SendIntentException e) { - } - } - - @Override - public void success(Account account) { - xmppConnectionService.databaseBackend - .updateAccount(account); - xmppConnectionService.sendPresencePacket(account, - xmppConnectionService.getPresenceGenerator() - .sendPresence(account)); - if (conversation != null) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); - xmppConnectionService.databaseBackend - .updateConversation(conversation); - } - } - - @Override - public void error(int error, Account account) { - displayErrorDialog(error); - } - }); - } - - protected void displayErrorDialog(final int errorCode) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder( - XmppActivity.this); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setTitle(getString(R.string.error)); - builder.setMessage(errorCode); - builder.setNeutralButton(R.string.accept, null); - builder.create().show(); - } - }); - - } - - protected void showAddToRosterDialog(final Conversation conversation) { - String jid = conversation.getContactJid(); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(jid); - builder.setMessage(getString(R.string.not_in_roster)); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.add_contact), - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - String jid = conversation.getContactJid(); - Account account = conversation.getAccount(); - Contact contact = account.getRoster().getContact(jid); - xmppConnectionService.createContact(contact); - switchToContactDetails(contact); - } - }); - builder.create().show(); - } - - private void showAskForPresenceDialog(final Contact contact) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(contact.getJid()); - builder.setMessage(R.string.request_presence_updates); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.request_now, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - if (xmppConnectionServiceBound) { - xmppConnectionService.sendPresencePacket(contact - .getAccount(), xmppConnectionService - .getPresenceGenerator() - .requestPresenceUpdatesFrom(contact)); - } - } - }); - builder.create().show(); - } - - private void warnMutalPresenceSubscription(final Conversation conversation, - final OnPresenceSelected listener) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(conversation.getContact().getJid()); - builder.setMessage(R.string.without_mutual_presence_updates); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.ignore, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - conversation.setNextPresence(null); - if (listener != null) { - listener.onPresenceSelected(); - } - } - }); - builder.create().show(); - } - - protected void quickEdit(String previousValue, OnValueEdited callback) { - quickEdit(previousValue, callback, false); - } - - protected void quickPasswordEdit(String previousValue, - OnValueEdited callback) { - quickEdit(previousValue, callback, true); - } - - @SuppressLint("InflateParams") - private void quickEdit(final String previousValue, - final OnValueEdited callback, boolean password) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - View view = (View) getLayoutInflater() - .inflate(R.layout.quickedit, null); - final EditText editor = (EditText) view.findViewById(R.id.editor); - OnClickListener mClickListener = new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - String value = editor.getText().toString(); - if (!previousValue.equals(value) && value.trim().length() > 0) { - callback.onValueEdited(value); - } - } - }; - if (password) { - editor.setInputType(InputType.TYPE_CLASS_TEXT - | InputType.TYPE_TEXT_VARIATION_PASSWORD); - editor.setHint(R.string.password); - builder.setPositiveButton(R.string.accept, mClickListener); - } else { - builder.setPositiveButton(R.string.edit, mClickListener); - } - editor.requestFocus(); - editor.setText(previousValue); - builder.setView(view); - builder.setNegativeButton(R.string.cancel, null); - builder.create().show(); - } - - public void selectPresence(final Conversation conversation, - final OnPresenceSelected listener) { - Contact contact = conversation.getContact(); - if (!contact.showInRoster()) { - showAddToRosterDialog(conversation); - } else { - Presences presences = contact.getPresences(); - if (presences.size() == 0) { - if (!contact.getOption(Contact.Options.TO) - && !contact.getOption(Contact.Options.ASKING) - && contact.getAccount().getStatus() == Account.STATUS_ONLINE) { - showAskForPresenceDialog(contact); - } else if (!contact.getOption(Contact.Options.TO) - || !contact.getOption(Contact.Options.FROM)) { - warnMutalPresenceSubscription(conversation, listener); - } else { - conversation.setNextPresence(null); - listener.onPresenceSelected(); - } - } else if (presences.size() == 1) { - String presence = (String) presences.asStringArray()[0]; - conversation.setNextPresence(presence); - listener.onPresenceSelected(); - } else { - final StringBuilder presence = new StringBuilder(); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.choose_presence)); - final String[] presencesArray = presences.asStringArray(); - int preselectedPresence = 0; - for (int i = 0; i < presencesArray.length; ++i) { - if (presencesArray[i].equals(contact.lastseen.presence)) { - preselectedPresence = i; - break; - } - } - presence.append(presencesArray[preselectedPresence]); - builder.setSingleChoiceItems(presencesArray, - preselectedPresence, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - presence.delete(0, presence.length()); - presence.append(presencesArray[which]); - } - }); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.ok, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - conversation.setNextPresence(presence.toString()); - listener.onPresenceSelected(); - } - }); - builder.create().show(); - } - } - } - - protected void onActivityResult(int requestCode, int resultCode, - final Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_INVITE_TO_CONVERSATION - && resultCode == RESULT_OK) { - String contactJid = data.getStringExtra("contact"); - String conversationUuid = data.getStringExtra("conversation"); - Conversation conversation = xmppConnectionService - .findConversationByUuid(conversationUuid); - if (conversation.getMode() == Conversation.MODE_MULTI) { - xmppConnectionService.invite(conversation, contactJid); - } - Log.d(Config.LOGTAG, "inviting " + contactJid + " to " - + conversation.getName()); - } - } - - public int getSecondaryTextColor() { - return this.mSecondaryTextColor; - } - - public int getPrimaryTextColor() { - return this.mPrimaryTextColor; - } - - public int getWarningTextColor() { - return this.mColorRed; - } - - public int getPrimaryColor() { - return this.mPrimaryColor; - } - - public int getSecondaryBackgroundColor() { - return this.mSecondaryBackgroundColor; - } - - public int getPixel(int dp) { - DisplayMetrics metrics = getResources().getDisplayMetrics(); - return ((int) (dp * metrics.density)); - } - - public AvatarService avatarService() { - return xmppConnectionService.getAvatarService(); - } - - class BitmapWorkerTask extends AsyncTask { - private final WeakReference imageViewReference; - private Message message = null; - - public BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference(imageView); - } - - @Override - protected Bitmap doInBackground(Message... params) { - message = params[0]; - try { - return xmppConnectionService.getFileBackend().getThumbnail( - message, (int) (metrics.density * 288), false); - } catch (FileNotFoundException e) { - return null; - } - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (imageViewReference != null && bitmap != null) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } - - public void loadBitmap(Message message, ImageView imageView) { - Bitmap bm; - try { - bm = xmppConnectionService.getFileBackend().getThumbnail(message, - (int) (metrics.density * 288), true); - } catch (FileNotFoundException e) { - bm = null; - } - if (bm != null) { - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - if (cancelPotentialWork(message, imageView)) { - imageView.setBackgroundColor(0xff333333); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable( - getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(message); - } catch (RejectedExecutionException e) { - return; - } - } - } - } - - public static boolean cancelPotentialWork(Message message, - ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final Message oldMessage = bitmapWorkerTask.message; - if (oldMessage == null || message != oldMessage) { - bitmapWorkerTask.cancel(true); - } else { - return false; - } - } - return true; - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } - - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference bitmapWorkerTaskReference; - - public AsyncDrawable(Resources res, Bitmap bitmap, - BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference( - bitmapWorkerTask); - } - - public BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/conversations/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java deleted file mode 100644 index 4ca21a3b..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ /dev/null @@ -1,102 +0,0 @@ -package eu.siacs.conversations.ui.adapter; - -import java.util.List; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.ui.XmppActivity; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -public class AccountAdapter extends ArrayAdapter { - - private XmppActivity activity; - - public AccountAdapter(XmppActivity activity, List objects) { - super(activity, 0, objects); - this.activity = activity; - } - - @Override - public View getView(int position, View view, ViewGroup parent) { - Account account = getItem(position); - if (view == null) { - LayoutInflater inflater = (LayoutInflater) getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = (View) inflater.inflate(R.layout.account_row, parent, false); - } - TextView jid = (TextView) view.findViewById(R.id.account_jid); - jid.setText(account.getJid()); - TextView statusView = (TextView) view.findViewById(R.id.account_status); - ImageView imageView = (ImageView) view.findViewById(R.id.account_image); - imageView.setImageBitmap(activity.avatarService().get(account, - activity.getPixel(48))); - switch (account.getStatus()) { - case Account.STATUS_DISABLED: - statusView.setText(getContext().getString( - R.string.account_status_disabled)); - statusView.setTextColor(activity.getSecondaryTextColor()); - break; - case Account.STATUS_ONLINE: - statusView.setText(getContext().getString( - R.string.account_status_online)); - statusView.setTextColor(activity.getPrimaryColor()); - break; - case Account.STATUS_CONNECTING: - statusView.setText(getContext().getString( - R.string.account_status_connecting)); - statusView.setTextColor(activity.getSecondaryTextColor()); - break; - case Account.STATUS_OFFLINE: - statusView.setText(getContext().getString( - R.string.account_status_offline)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - case Account.STATUS_UNAUTHORIZED: - statusView.setText(getContext().getString( - R.string.account_status_unauthorized)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - case Account.STATUS_SERVER_NOT_FOUND: - statusView.setText(getContext().getString( - R.string.account_status_not_found)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - case Account.STATUS_NO_INTERNET: - statusView.setText(getContext().getString( - R.string.account_status_no_internet)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - case Account.STATUS_REGISTRATION_FAILED: - statusView.setText(getContext().getString( - R.string.account_status_regis_fail)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - case Account.STATUS_REGISTRATION_CONFLICT: - statusView.setText(getContext().getString( - R.string.account_status_regis_conflict)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - case Account.STATUS_REGISTRATION_SUCCESSFULL: - statusView.setText(getContext().getString( - R.string.account_status_regis_success)); - statusView.setTextColor(activity.getSecondaryTextColor()); - break; - case Account.STATUS_REGISTRATION_NOT_SUPPORTED: - statusView.setText(getContext().getString( - R.string.account_status_regis_not_sup)); - statusView.setTextColor(activity.getWarningTextColor()); - break; - default: - statusView.setText(""); - break; - } - - return view; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/conversations/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java deleted file mode 100644 index 183c89fa..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ /dev/null @@ -1,135 +0,0 @@ -package eu.siacs.conversations.ui.adapter; - -import java.util.List; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.ui.ConversationActivity; -import eu.siacs.conversations.ui.XmppActivity; -import eu.siacs.conversations.utils.UIHelper; -import android.content.Context; -import android.graphics.Color; -import android.graphics.Typeface; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -public class ConversationAdapter extends ArrayAdapter { - - private XmppActivity activity; - - public ConversationAdapter(XmppActivity activity, - List conversations) { - super(activity, 0, conversations); - this.activity = activity; - } - - @Override - public View getView(int position, View view, ViewGroup parent) { - if (view == null) { - LayoutInflater inflater = (LayoutInflater) activity - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = (View) inflater.inflate(R.layout.conversation_list_row, - parent, false); - } - Conversation conversation = getItem(position); - if (this.activity instanceof ConversationActivity) { - ConversationActivity activity = (ConversationActivity) this.activity; - if (!activity.isConversationsOverviewHideable()) { - if (conversation == activity.getSelectedConversation()) { - view.setBackgroundColor(activity - .getSecondaryBackgroundColor()); - } else { - view.setBackgroundColor(Color.TRANSPARENT); - } - } else { - view.setBackgroundColor(Color.TRANSPARENT); - } - } - TextView convName = (TextView) view - .findViewById(R.id.conversation_name); - if (conversation.getMode() == Conversation.MODE_SINGLE - || activity.useSubjectToIdentifyConference()) { - convName.setText(conversation.getName()); - } else { - convName.setText(conversation.getContactJid().split("/")[0]); - } - TextView mLastMessage = (TextView) view - .findViewById(R.id.conversation_lastmsg); - TextView mTimestamp = (TextView) view - .findViewById(R.id.conversation_lastupdate); - ImageView imagePreview = (ImageView) view - .findViewById(R.id.conversation_lastimage); - - Message message = conversation.getLatestMessage(); - - if (!conversation.isRead()) { - convName.setTypeface(null, Typeface.BOLD); - } else { - convName.setTypeface(null, Typeface.NORMAL); - } - - if (message.getType() == Message.TYPE_IMAGE - || message.getDownloadable() != null) { - Downloadable d = message.getDownloadable(); - if (d != null) { - mLastMessage.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - if (conversation.isRead()) { - mLastMessage.setTypeface(null, Typeface.ITALIC); - } else { - mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC); - } - if (d.getStatus() == Downloadable.STATUS_CHECKING) { - mLastMessage.setText(R.string.checking_image); - } else if (d.getStatus() == Downloadable.STATUS_DOWNLOADING) { - mLastMessage.setText(R.string.receiving_image); - } else if (d.getStatus() == Downloadable.STATUS_OFFER) { - mLastMessage.setText(R.string.image_offered_for_download); - } else if (d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { - mLastMessage.setText(R.string.image_offered_for_download); - } else if (d.getStatus() == Downloadable.STATUS_DELETED) { - mLastMessage.setText(R.string.image_file_deleted); - } else { - mLastMessage.setText(""); - } - } else { - mLastMessage.setVisibility(View.GONE); - imagePreview.setVisibility(View.VISIBLE); - activity.loadBitmap(message, imagePreview); - } - } else { - if ((message.getEncryption() != Message.ENCRYPTION_PGP) - && (message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { - String body = Config.PARSE_EMOTICONS ? UIHelper - .transformAsciiEmoticons(message.getBody()) : message - .getBody(); - mLastMessage.setText(body); - } else { - mLastMessage.setText(R.string.encrypted_message_received); - } - if (!conversation.isRead()) { - mLastMessage.setTypeface(null, Typeface.BOLD); - } else { - mLastMessage.setTypeface(null, Typeface.NORMAL); - } - mLastMessage.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - } - mTimestamp.setText(UIHelper.readableTimeDifference(getContext(), - conversation.getLatestMessage().getTimeSent())); - - ImageView profilePicture = (ImageView) view - .findViewById(R.id.conversation_image); - profilePicture.setImageBitmap(activity.avatarService().get( - conversation, activity.getPixel(56))); - - return view; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java b/conversations/src/main/java/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java deleted file mode 100644 index 143dfda1..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -package eu.siacs.conversations.ui.adapter; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import android.content.Context; -import android.widget.ArrayAdapter; -import android.widget.Filter; - -public class KnownHostsAdapter extends ArrayAdapter { - private ArrayList domains; - private Filter domainFilter = new Filter() { - - @Override - protected FilterResults performFiltering(CharSequence constraint) { - if (constraint != null) { - ArrayList suggestions = new ArrayList(); - final String[] split = constraint.toString().split("@"); - if (split.length == 1) { - for (String domain : domains) { - suggestions.add(split[0].toLowerCase(Locale - .getDefault()) + "@" + domain); - } - } else if (split.length == 2) { - for (String domain : domains) { - if (domain.contentEquals(split[1])) { - suggestions.clear(); - break; - } else if (domain.contains(split[1])) { - suggestions.add(split[0].toLowerCase(Locale - .getDefault()) + "@" + domain); - } - } - } else { - return new FilterResults(); - } - FilterResults filterResults = new FilterResults(); - filterResults.values = suggestions; - filterResults.count = suggestions.size(); - return filterResults; - } else { - return new FilterResults(); - } - } - - @Override - protected void publishResults(CharSequence constraint, - FilterResults results) { - ArrayList filteredList = (ArrayList) results.values; - if (results != null && results.count > 0) { - clear(); - for (Object c : filteredList) { - add((String) c); - } - notifyDataSetChanged(); - } - } - }; - - public KnownHostsAdapter(Context context, int viewResourceId, - List mKnownHosts) { - super(context, viewResourceId, mKnownHosts); - domains = new ArrayList(mKnownHosts.size()); - for (String domain : mKnownHosts) { - domains.add(new String(domain)); - } - } - - @Override - public Filter getFilter() { - return domainFilter; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/conversations/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java deleted file mode 100644 index 977aa7b5..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java +++ /dev/null @@ -1,44 +0,0 @@ -package eu.siacs.conversations.ui.adapter; - -import java.util.List; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.ListItem; -import eu.siacs.conversations.ui.XmppActivity; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -public class ListItemAdapter extends ArrayAdapter { - - protected XmppActivity activity; - - public ListItemAdapter(XmppActivity activity, List objects) { - super(activity, 0, objects); - this.activity = activity; - } - - @Override - public View getView(int position, View view, ViewGroup parent) { - LayoutInflater inflater = (LayoutInflater) getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - ListItem item = getItem(position); - if (view == null) { - view = (View) inflater.inflate(R.layout.contact, parent, false); - } - TextView name = (TextView) view.findViewById(R.id.contact_display_name); - TextView jid = (TextView) view.findViewById(R.id.contact_jid); - ImageView picture = (ImageView) view.findViewById(R.id.contact_photo); - - jid.setText(item.getJid()); - name.setText(item.getDisplayName()); - picture.setImageBitmap(activity.avatarService().get(item, - activity.getPixel(48))); - return view; - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/conversations/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java deleted file mode 100644 index a9a55cbf..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ /dev/null @@ -1,560 +0,0 @@ -package eu.siacs.conversations.ui.adapter; - -import java.util.List; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.Message.ImageParams; -import eu.siacs.conversations.ui.ConversationActivity; -import eu.siacs.conversations.utils.UIHelper; -import android.content.Intent; -import android.graphics.Typeface; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; -import android.text.style.StyleSpan; -import android.util.DisplayMetrics; -import android.view.View; -import android.view.ViewGroup; -import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -public class MessageAdapter extends ArrayAdapter { - - private static final int SENT = 0; - private static final int RECEIVED = 1; - private static final int STATUS = 2; - private static final int NULL = 3; - - private ConversationActivity activity; - - private DisplayMetrics metrics; - - private OnContactPictureClicked mOnContactPictureClickedListener; - private OnContactPictureLongClicked mOnContactPictureLongClickedListener; - - public MessageAdapter(ConversationActivity activity, List messages) { - super(activity, 0, messages); - this.activity = activity; - metrics = getContext().getResources().getDisplayMetrics(); - } - - public void setOnContactPictureClicked(OnContactPictureClicked listener) { - this.mOnContactPictureClickedListener = listener; - } - - public void setOnContactPictureLongClicked( - OnContactPictureLongClicked listener) { - this.mOnContactPictureLongClickedListener = listener; - } - - @Override - public int getViewTypeCount() { - return 4; - } - - @Override - public int getItemViewType(int position) { - if (getItem(position).wasMergedIntoPrevious()) { - return NULL; - } else if (getItem(position).getType() == Message.TYPE_STATUS) { - return STATUS; - } else if (getItem(position).getStatus() <= Message.STATUS_RECEIVED) { - return RECEIVED; - } else { - return SENT; - } - } - - private void displayStatus(ViewHolder viewHolder, Message message) { - String filesize = null; - String info = null; - boolean error = false; - if (viewHolder.indicatorReceived != null) { - viewHolder.indicatorReceived.setVisibility(View.GONE); - } - boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI - && message.getMergedStatus() <= Message.STATUS_RECEIVED; - if (message.getType() == Message.TYPE_IMAGE - || message.getDownloadable() != null) { - ImageParams params = message.getImageParams(); - if (params.size != 0) { - filesize = params.size / 1024 + " KB"; - } - } - switch (message.getMergedStatus()) { - case Message.STATUS_WAITING: - info = getContext().getString(R.string.waiting); - break; - case Message.STATUS_UNSEND: - info = getContext().getString(R.string.sending); - break; - case Message.STATUS_OFFERED: - info = getContext().getString(R.string.offering); - break; - case Message.STATUS_SEND_RECEIVED: - if (activity.indicateReceived()) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } - break; - case Message.STATUS_SEND_DISPLAYED: - if (activity.indicateReceived()) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } - break; - case Message.STATUS_SEND_FAILED: - info = getContext().getString(R.string.send_failed); - error = true; - break; - case Message.STATUS_SEND_REJECTED: - info = getContext().getString(R.string.send_rejected); - error = true; - break; - default: - if (multiReceived) { - Contact contact = message.getContact(); - if (contact != null) { - info = contact.getDisplayName(); - } else { - if (message.getPresence() != null) { - info = message.getPresence(); - } else { - info = message.getCounterpart(); - } - } - } - break; - } - if (error) { - viewHolder.time.setTextColor(activity.getWarningTextColor()); - } else { - viewHolder.time.setTextColor(activity.getSecondaryTextColor()); - } - if (message.getEncryption() == Message.ENCRYPTION_NONE) { - viewHolder.indicator.setVisibility(View.GONE); - } else { - viewHolder.indicator.setVisibility(View.VISIBLE); - } - - String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(), - message.getMergedTimeSent()); - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if ((filesize != null) && (info != null)) { - viewHolder.time.setText(filesize + " \u00B7 " + info); - } else if ((filesize == null) && (info != null)) { - viewHolder.time.setText(formatedTime + " \u00B7 " + info); - } else if ((filesize != null) && (info == null)) { - viewHolder.time.setText(formatedTime + " \u00B7 " + filesize); - } else { - viewHolder.time.setText(formatedTime); - } - } else { - if ((filesize != null) && (info != null)) { - viewHolder.time.setText(filesize + " \u00B7 " + info); - } else if ((filesize == null) && (info != null)) { - if (error) { - viewHolder.time.setText(info + " \u00B7 " + formatedTime); - } else { - viewHolder.time.setText(info); - } - } else if ((filesize != null) && (info == null)) { - viewHolder.time.setText(filesize + " \u00B7 " + formatedTime); - } else { - viewHolder.time.setText(formatedTime); - } - } - } - - private void displayInfoMessage(ViewHolder viewHolder, int r) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText(getContext().getString(r)); - viewHolder.messageBody.setTextColor(activity.getSecondaryTextColor()); - viewHolder.messageBody.setTypeface(null, Typeface.ITALIC); - viewHolder.messageBody.setTextIsSelectable(false); - } - - private void displayDecryptionFailed(ViewHolder viewHolder) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText(getContext().getString( - R.string.decryption_failed)); - viewHolder.messageBody.setTextColor(activity.getWarningTextColor()); - viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); - viewHolder.messageBody.setTextIsSelectable(false); - } - - private void displayTextMessage(ViewHolder viewHolder, Message message) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - if (message.getBody() != null) { - if (message.getType() != Message.TYPE_PRIVATE) { - String body = Config.PARSE_EMOTICONS ? UIHelper - .transformAsciiEmoticons(message.getMergedBody()) - : message.getMergedBody(); - viewHolder.messageBody.setText(body); - } else { - String privateMarker; - if (message.getStatus() <= Message.STATUS_RECEIVED) { - privateMarker = activity - .getString(R.string.private_message); - } else { - String to; - if (message.getPresence() != null) { - to = message.getPresence(); - } else { - to = message.getCounterpart(); - } - privateMarker = activity.getString( - R.string.private_message_to, to); - } - SpannableString span = new SpannableString(privateMarker + " " - + message.getBody()); - span.setSpan( - new ForegroundColorSpan(activity - .getSecondaryTextColor()), 0, privateMarker - .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - span.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, - privateMarker.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - viewHolder.messageBody.setText(span); - } - } else { - viewHolder.messageBody.setText(""); - } - viewHolder.messageBody.setTextColor(activity.getPrimaryTextColor()); - viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); - viewHolder.messageBody.setTextIsSelectable(true); - } - - private void displayDownloadableMessage(ViewHolder viewHolder, - final Message message, int resid) { - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(resid); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - startDonwloadable(message); - } - }); - } - - private void displayImageMessage(ViewHolder viewHolder, - final Message message) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.image.setVisibility(View.VISIBLE); - ImageParams params = message.getImageParams(); - double target = metrics.density * 288; - int scalledW; - int scalledH; - if (params.width <= params.height) { - scalledW = (int) (params.width / ((double) params.height / target)); - scalledH = (int) target; - } else { - scalledW = (int) target; - scalledH = (int) (params.height / ((double) params.width / target)); - } - viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams( - scalledW, scalledH)); - activity.loadBitmap(message, viewHolder.image); - viewHolder.image.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(activity.xmppConnectionService - .getFileBackend().getJingleFileUri(message), "image/*"); - getContext().startActivity(intent); - } - }); - viewHolder.image.setOnLongClickListener(new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, - activity.xmppConnectionService.getFileBackend() - .getJingleFileUri(message)); - shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - shareIntent.setType("image/webp"); - getContext().startActivity( - Intent.createChooser(shareIntent, - getContext().getText(R.string.share_with))); - return true; - } - }); - } - - @Override - public View getView(int position, View view, ViewGroup parent) { - final Message item = getItem(position); - int type = getItemViewType(position); - ViewHolder viewHolder; - if (view == null) { - viewHolder = new ViewHolder(); - switch (type) { - case NULL: - view = (View) activity.getLayoutInflater().inflate( - R.layout.message_null, parent, false); - break; - case SENT: - view = (View) activity.getLayoutInflater().inflate( - R.layout.message_sent, parent, false); - viewHolder.message_box = (LinearLayout) view - .findViewById(R.id.message_box); - viewHolder.contact_picture = (ImageView) view - .findViewById(R.id.message_photo); - viewHolder.contact_picture.setImageBitmap(activity - .avatarService().get( - item.getConversation().getAccount(), - activity.getPixel(48))); - viewHolder.download_button = (Button) view - .findViewById(R.id.download_button); - viewHolder.indicator = (ImageView) view - .findViewById(R.id.security_indicator); - viewHolder.image = (ImageView) view - .findViewById(R.id.message_image); - viewHolder.messageBody = (TextView) view - .findViewById(R.id.message_body); - viewHolder.time = (TextView) view - .findViewById(R.id.message_time); - viewHolder.indicatorReceived = (ImageView) view - .findViewById(R.id.indicator_received); - view.setTag(viewHolder); - break; - case RECEIVED: - view = (View) activity.getLayoutInflater().inflate( - R.layout.message_received, parent, false); - viewHolder.message_box = (LinearLayout) view - .findViewById(R.id.message_box); - viewHolder.contact_picture = (ImageView) view - .findViewById(R.id.message_photo); - viewHolder.download_button = (Button) view - .findViewById(R.id.download_button); - if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { - viewHolder.contact_picture.setImageBitmap(activity - .avatarService().get(item.getContact(), - activity.getPixel(48))); - } - viewHolder.indicator = (ImageView) view - .findViewById(R.id.security_indicator); - viewHolder.image = (ImageView) view - .findViewById(R.id.message_image); - viewHolder.messageBody = (TextView) view - .findViewById(R.id.message_body); - viewHolder.time = (TextView) view - .findViewById(R.id.message_time); - view.setTag(viewHolder); - break; - case STATUS: - view = (View) activity.getLayoutInflater().inflate( - R.layout.message_status, parent, false); - viewHolder.contact_picture = (ImageView) view - .findViewById(R.id.message_photo); - if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { - - viewHolder.contact_picture.setImageBitmap(activity - .avatarService().get( - item.getConversation().getContact(), - activity.getPixel(32))); - viewHolder.contact_picture.setAlpha(0.5f); - viewHolder.contact_picture - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - String name = item.getConversation() - .getName(); - String read = getContext() - .getString( - R.string.contact_has_read_up_to_this_point, - name); - Toast.makeText(getContext(), read, - Toast.LENGTH_SHORT).show(); - } - }); - - } - break; - default: - viewHolder = null; - break; - } - } else { - viewHolder = (ViewHolder) view.getTag(); - } - - if (type == STATUS) { - return view; - } - if (type == NULL) { - if (position == getCount() - 1) { - view.getLayoutParams().height = 1; - } else { - view.getLayoutParams().height = 0; - - } - view.setLayoutParams(view.getLayoutParams()); - return view; - } - - if (viewHolder.contact_picture != null) { - viewHolder.contact_picture - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (MessageAdapter.this.mOnContactPictureClickedListener != null) { - MessageAdapter.this.mOnContactPictureClickedListener - .onContactPictureClicked(item); - ; - } - - } - }); - viewHolder.contact_picture - .setOnLongClickListener(new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { - MessageAdapter.this.mOnContactPictureLongClickedListener - .onContactPictureLongClicked(item); - return true; - } else { - return false; - } - } - }); - } - - if (type == RECEIVED) { - if (item.getConversation().getMode() == Conversation.MODE_MULTI) { - Contact contact = item.getContact(); - if (contact != null) { - viewHolder.contact_picture.setImageBitmap(activity - .avatarService() - .get(contact, activity.getPixel(48))); - } else { - String name = item.getPresence(); - if (name == null) { - name = item.getCounterpart(); - } - viewHolder.contact_picture.setImageBitmap(activity - .avatarService().get(name, activity.getPixel(48))); - } - } - } - - if (item.getType() == Message.TYPE_IMAGE - || item.getDownloadable() != null) { - Downloadable d = item.getDownloadable(); - if (d != null && d.getStatus() == Downloadable.STATUS_DOWNLOADING) { - displayInfoMessage(viewHolder, R.string.receiving_image); - } else if (d != null - && d.getStatus() == Downloadable.STATUS_CHECKING) { - displayInfoMessage(viewHolder, R.string.checking_image); - } else if (d != null - && d.getStatus() == Downloadable.STATUS_DELETED) { - displayInfoMessage(viewHolder, R.string.image_file_deleted); - } else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) { - displayDownloadableMessage(viewHolder, item, - R.string.download_image); - } else if (d != null - && d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { - displayDownloadableMessage(viewHolder, item, - R.string.check_image_filesize); - } else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED) - || (item.getEncryption() == Message.ENCRYPTION_NONE) - || (item.getEncryption() == Message.ENCRYPTION_OTR)) { - displayImageMessage(viewHolder, item); - } else if (item.getEncryption() == Message.ENCRYPTION_PGP) { - displayInfoMessage(viewHolder, R.string.encrypted_message); - } else { - displayDecryptionFailed(viewHolder); - } - } else { - if (item.getEncryption() == Message.ENCRYPTION_PGP) { - if (activity.hasPgp()) { - displayInfoMessage(viewHolder, R.string.encrypted_message); - } else { - displayInfoMessage(viewHolder, - R.string.install_openkeychain); - viewHolder.message_box - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - activity.showInstallPgpDialog(); - } - }); - } - } else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { - displayDecryptionFailed(viewHolder); - } else { - displayTextMessage(viewHolder, item); - } - } - - displayStatus(viewHolder, item); - - return view; - } - - public void startDonwloadable(Message message) { - Downloadable downloadable = message.getDownloadable(); - if (downloadable != null) { - if (!downloadable.start()) { - Toast.makeText(activity, R.string.not_connected_try_again, - Toast.LENGTH_SHORT).show(); - } - } - } - - private static class ViewHolder { - - protected LinearLayout message_box; - protected Button download_button; - protected ImageView image; - protected ImageView indicator; - protected ImageView indicatorReceived; - protected TextView time; - protected TextView messageBody; - protected ImageView contact_picture; - - } - - public interface OnContactPictureClicked { - public void onContactPictureClicked(Message message); - } - - public interface OnContactPictureLongClicked { - public void onContactPictureLongClicked(Message message); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/conversations/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java deleted file mode 100644 index 47595c6e..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ /dev/null @@ -1,112 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.math.BigInteger; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -import eu.siacs.conversations.entities.Account; -import android.util.Base64; - -public class CryptoHelper { - public static final String FILETRANSFER = "?FILETRANSFERv1:"; - final protected static char[] hexArray = "0123456789abcdef".toCharArray(); - final protected static char[] vowels = "aeiou".toCharArray(); - final protected static char[] consonants = "bcdfghjklmnpqrstvwxyz" - .toCharArray(); - - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); - } - - public static byte[] hexToBytes(String hexString) { - int len = hexString.length(); - byte[] array = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - array[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character - .digit(hexString.charAt(i + 1), 16)); - } - return array; - } - - public static String saslPlain(String username, String password) { - String sasl = '\u0000' + username + '\u0000' + password; - return Base64.encodeToString(sasl.getBytes(Charset.defaultCharset()), - Base64.NO_WRAP); - } - - private static byte[] concatenateByteArrays(byte[] a, byte[] b) { - byte[] result = new byte[a.length + b.length]; - System.arraycopy(a, 0, result, 0, a.length); - System.arraycopy(b, 0, result, a.length, b.length); - return result; - } - - public static String saslDigestMd5(Account account, String challenge, - SecureRandom random) { - try { - String[] challengeParts = new String(Base64.decode(challenge, - Base64.DEFAULT)).split(","); - String nonce = ""; - for (int i = 0; i < challengeParts.length; ++i) { - String[] parts = challengeParts[i].split("="); - if (parts[0].equals("nonce")) { - nonce = parts[1].replace("\"", ""); - } else if (parts[0].equals("rspauth")) { - return null; - } - } - String digestUri = "xmpp/" + account.getServer(); - String nonceCount = "00000001"; - String x = account.getUsername() + ":" + account.getServer() + ":" - + account.getPassword(); - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] y = md.digest(x.getBytes(Charset.defaultCharset())); - String cNonce = new BigInteger(100, random).toString(32); - byte[] a1 = concatenateByteArrays(y, - (":" + nonce + ":" + cNonce).getBytes(Charset - .defaultCharset())); - String a2 = "AUTHENTICATE:" + digestUri; - String ha1 = bytesToHex(md.digest(a1)); - String ha2 = bytesToHex(md.digest(a2.getBytes(Charset - .defaultCharset()))); - String kd = ha1 + ":" + nonce + ":" + nonceCount + ":" + cNonce - + ":auth:" + ha2; - String response = bytesToHex(md.digest(kd.getBytes(Charset - .defaultCharset()))); - String saslString = "username=\"" + account.getUsername() - + "\",realm=\"" + account.getServer() + "\",nonce=\"" - + nonce + "\",cnonce=\"" + cNonce + "\",nc=" + nonceCount - + ",qop=auth,digest-uri=\"" + digestUri + "\",response=" - + response + ",charset=utf-8"; - return Base64.encodeToString( - saslString.getBytes(Charset.defaultCharset()), - Base64.NO_WRAP); - } catch (NoSuchAlgorithmException e) { - return null; - } - } - - public static String randomMucName(SecureRandom random) { - return randomWord(3, random) + "." + randomWord(7, random); - } - - protected static String randomWord(int lenght, SecureRandom random) { - StringBuilder builder = new StringBuilder(lenght); - for (int i = 0; i < lenght; ++i) { - if (i % 2 == 0) { - builder.append(consonants[random.nextInt(consonants.length)]); - } else { - builder.append(vowels[random.nextInt(vowels.length)]); - } - } - return builder.toString(); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/conversations/src/main/java/eu/siacs/conversations/utils/DNSHelper.java deleted file mode 100644 index c51a75ac..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ /dev/null @@ -1,185 +0,0 @@ -package eu.siacs.conversations.utils; - -import de.measite.minidns.Client; -import de.measite.minidns.DNSMessage; -import de.measite.minidns.Record; -import de.measite.minidns.Record.TYPE; -import de.measite.minidns.Record.CLASS; -import de.measite.minidns.record.SRV; -import de.measite.minidns.record.A; -import de.measite.minidns.record.AAAA; -import de.measite.minidns.record.Data; -import de.measite.minidns.util.NameUtil; -import eu.siacs.conversations.Config; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.SocketTimeoutException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Random; -import java.util.TreeMap; - -import android.os.Bundle; -import android.util.Log; - -public class DNSHelper { - protected static Client client = new Client(); - - public static Bundle getSRVRecord(String host) throws IOException { - String dns[] = client.findDNS(); - - if (dns != null) { - for (String dnsserver : dns) { - InetAddress ip = InetAddress.getByName(dnsserver); - Bundle b = queryDNS(host, ip); - if (b.containsKey("name")) { - return b; - } else if (b.containsKey("error") - && "nosrv".equals(b.getString("error", null))) { - return b; - } - } - } - return queryDNS(host, InetAddress.getByName("8.8.8.8")); - } - - public static Bundle queryDNS(String host, InetAddress dnsServer) { - Bundle namePort = new Bundle(); - try { - String qname = "_xmpp-client._tcp." + host; - Log.d(Config.LOGTAG, - "using dns server: " + dnsServer.getHostAddress() - + " to look up " + host); - DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, - dnsServer.getHostAddress()); - - // How should we handle priorities and weight? - // Wikipedia has a nice article about priorities vs. weights: - // https://en.wikipedia.org/wiki/SRV_record#Provisioning_for_high_service_availability - - // we bucket the SRV records based on priority, pick per priority - // a random order respecting the weight, and dump that priority by - // priority - - TreeMap> priorities = new TreeMap>(); - TreeMap> ips4 = new TreeMap>(); - TreeMap> ips6 = new TreeMap>(); - - for (Record[] rrset : new Record[][] { message.getAnswers(), - message.getAdditionalResourceRecords() }) { - for (Record rr : rrset) { - Data d = rr.getPayload(); - if (d instanceof SRV - && NameUtil.idnEquals(qname, rr.getName())) { - SRV srv = (SRV) d; - if (!priorities.containsKey(srv.getPriority())) { - priorities.put(srv.getPriority(), - new ArrayList(2)); - } - priorities.get(srv.getPriority()).add(srv); - } - if (d instanceof A) { - A arecord = (A) d; - if (!ips4.containsKey(rr.getName())) { - ips4.put(rr.getName(), new ArrayList(3)); - } - ips4.get(rr.getName()).add(arecord.toString()); - } - if (d instanceof AAAA) { - AAAA aaaa = (AAAA) d; - if (!ips6.containsKey(rr.getName())) { - ips6.put(rr.getName(), new ArrayList(3)); - } - ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); - } - } - } - - Random rnd = new Random(); - ArrayList result = new ArrayList( - priorities.size() * 2 + 1); - for (ArrayList s : priorities.values()) { - - // trivial case - if (s.size() <= 1) { - result.addAll(s); - continue; - } - - long totalweight = 0l; - for (SRV srv : s) { - totalweight += srv.getWeight(); - } - - while (totalweight > 0l && s.size() > 0) { - long p = (rnd.nextLong() & 0x7fffffffffffffffl) - % totalweight; - int i = 0; - while (p > 0) { - p -= s.get(i++).getPriority(); - } - i--; - // remove is expensive, but we have only a few entries - // anyway - SRV srv = s.remove(i); - totalweight -= srv.getWeight(); - result.add(srv); - } - - Collections.shuffle(s, rnd); - result.addAll(s); - - } - - if (result.size() == 0) { - namePort.putString("error", "nosrv"); - return namePort; - } - // we now have a list of servers to try :-) - - // classic name/port pair - String resultName = result.get(0).getName(); - namePort.putString("name", resultName); - namePort.putInt("port", result.get(0).getPort()); - - if (ips4.containsKey(resultName)) { - // we have an ip! - ArrayList ip = ips4.get(resultName); - Collections.shuffle(ip, rnd); - namePort.putString("ipv4", ip.get(0)); - } - if (ips6.containsKey(resultName)) { - ArrayList ip = ips6.get(resultName); - Collections.shuffle(ip, rnd); - namePort.putString("ipv6", ip.get(0)); - } - - // add all other records - int i = 0; - for (SRV srv : result) { - namePort.putString("name" + i, srv.getName()); - namePort.putInt("port" + i, srv.getPort()); - i++; - } - - } catch (SocketTimeoutException e) { - namePort.putString("error", "timeout"); - } catch (Exception e) { - namePort.putString("error", "unhandled"); - } - return namePort; - } - - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java b/conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java deleted file mode 100644 index 88fa18ff..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.Thread.UncaughtExceptionHandler; - -import android.content.Context; - -public class ExceptionHandler implements UncaughtExceptionHandler { - - private UncaughtExceptionHandler defaultHandler; - private Context context; - - public ExceptionHandler(Context context) { - this.context = context; - this.defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); - } - - @Override - public void uncaughtException(Thread thread, Throwable ex) { - Writer result = new StringWriter(); - PrintWriter printWriter = new PrintWriter(result); - ex.printStackTrace(printWriter); - String stacktrace = result.toString(); - printWriter.close(); - try { - OutputStream os = context.openFileOutput("stacktrace.txt", - Context.MODE_PRIVATE); - os.write(stacktrace.getBytes()); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.defaultHandler.uncaughtException(thread, ex); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java deleted file mode 100644 index b5fc88bd..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ /dev/null @@ -1,117 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.DialogInterface.OnClickListener; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.preference.PreferenceManager; -import android.text.format.DateUtils; -import android.util.Log; - -public class ExceptionHelper { - public static void init(Context context) { - if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof ExceptionHandler)) { - Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler( - context)); - } - } - - public static void checkForCrash(Context context, - final XmppConnectionService service) { - try { - final SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(context); - boolean neverSend = preferences.getBoolean("never_send", false); - if (neverSend) { - return; - } - List accounts = service.getAccounts(); - Account account = null; - for (int i = 0; i < accounts.size(); ++i) { - if (!accounts.get(i).isOptionSet(Account.OPTION_DISABLED)) { - account = accounts.get(i); - break; - } - } - if (account == null) { - return; - } - final Account finalAccount = account; - FileInputStream file = context.openFileInput("stacktrace.txt"); - InputStreamReader inputStreamReader = new InputStreamReader(file); - BufferedReader stacktrace = new BufferedReader(inputStreamReader); - final StringBuilder report = new StringBuilder(); - PackageManager pm = context.getPackageManager(); - PackageInfo packageInfo = null; - try { - packageInfo = pm.getPackageInfo(context.getPackageName(), 0); - report.append("Version: " + packageInfo.versionName + '\n'); - report.append("Last Update: " - + DateUtils.formatDateTime(context, - packageInfo.lastUpdateTime, - DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_SHOW_DATE) + '\n'); - } catch (NameNotFoundException e) { - } - String line; - while ((line = stacktrace.readLine()) != null) { - report.append(line); - report.append('\n'); - } - file.close(); - context.deleteFile("stacktrace.txt"); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(context.getString(R.string.crash_report_title)); - builder.setMessage(context.getText(R.string.crash_report_message)); - builder.setPositiveButton(context.getText(R.string.send_now), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - - Log.d(Config.LOGTAG, "using account=" - + finalAccount.getJid() - + " to send in stack trace"); - Conversation conversation = service - .findOrCreateConversation(finalAccount, - "bugs@siacs.eu", false); - Message message = new Message(conversation, report - .toString(), Message.ENCRYPTION_NONE); - service.sendMessage(message); - } - }); - builder.setNegativeButton(context.getText(R.string.send_never), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - preferences.edit().putBoolean("never_send", true) - .commit(); - } - }); - builder.create().show(); - } catch (FileNotFoundException e) { - return; - } catch (IOException e) { - return; - } - - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java b/conversations/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java deleted file mode 100644 index 9a689768..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.util.List; - -import android.os.Bundle; - -public interface OnPhoneContactsLoadedListener { - public void onPhoneContactsLoaded(List phoneContacts); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java b/conversations/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java deleted file mode 100644 index 8fe67234..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java +++ /dev/null @@ -1,327 +0,0 @@ -package eu.siacs.conversations.utils; - -import android.os.Build; -import android.os.Process; -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.security.NoSuchAlgorithmException; -import java.security.Provider; -import java.security.SecureRandom; -import java.security.SecureRandomSpi; -import java.security.Security; - -/** - * Fixes for the output of the default PRNG having low entropy. - * - * The fixes need to be applied via {@link #apply()} before any use of Java - * Cryptography Architecture primitives. A good place to invoke them is in the - * application's {@code onCreate}. - */ -public final class PRNGFixes { - - private static final int VERSION_CODE_JELLY_BEAN = 16; - private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; - private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = getBuildFingerprintAndDeviceSerial(); - - /** Hidden constructor to prevent instantiation. */ - private PRNGFixes() { - } - - /** - * Applies all fixes. - * - * @throws SecurityException - * if a fix is needed but could not be applied. - */ - public static void apply() { - applyOpenSSLFix(); - installLinuxPRNGSecureRandom(); - } - - /** - * Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the - * fix is not needed. - * - * @throws SecurityException - * if the fix is needed but could not be applied. - */ - private static void applyOpenSSLFix() throws SecurityException { - if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN) - || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) { - // No need to apply the fix - return; - } - - try { - // Mix in the device- and invocation-specific seed. - Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") - .getMethod("RAND_seed", byte[].class) - .invoke(null, generateSeed()); - - // Mix output of Linux PRNG into OpenSSL's PRNG - int bytesRead = (Integer) Class - .forName( - "org.apache.harmony.xnet.provider.jsse.NativeCrypto") - .getMethod("RAND_load_file", String.class, long.class) - .invoke(null, "/dev/urandom", 1024); - if (bytesRead != 1024) { - throw new IOException( - "Unexpected number of bytes read from Linux PRNG: " - + bytesRead); - } - } catch (Exception e) { - throw new SecurityException("Failed to seed OpenSSL PRNG", e); - } - } - - /** - * Installs a Linux PRNG-backed {@code SecureRandom} implementation as the - * default. Does nothing if the implementation is already the default or if - * there is not need to install the implementation. - * - * @throws SecurityException - * if the fix is needed but could not be applied. - */ - private static void installLinuxPRNGSecureRandom() throws SecurityException { - if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) { - // No need to apply the fix - return; - } - - // Install a Linux PRNG-based SecureRandom implementation as the - // default, if not yet installed. - Provider[] secureRandomProviders = Security - .getProviders("SecureRandom.SHA1PRNG"); - if ((secureRandomProviders == null) - || (secureRandomProviders.length < 1) - || (!LinuxPRNGSecureRandomProvider.class - .equals(secureRandomProviders[0].getClass()))) { - Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1); - } - - // Assert that new SecureRandom() and - // SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed - // by the Linux PRNG-based SecureRandom implementation. - SecureRandom rng1 = new SecureRandom(); - if (!LinuxPRNGSecureRandomProvider.class.equals(rng1.getProvider() - .getClass())) { - throw new SecurityException( - "new SecureRandom() backed by wrong Provider: " - + rng1.getProvider().getClass()); - } - - SecureRandom rng2; - try { - rng2 = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - throw new SecurityException("SHA1PRNG not available", e); - } - if (!LinuxPRNGSecureRandomProvider.class.equals(rng2.getProvider() - .getClass())) { - throw new SecurityException( - "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" - + " Provider: " + rng2.getProvider().getClass()); - } - } - - /** - * {@code Provider} of {@code SecureRandom} engines which pass through all - * requests to the Linux PRNG. - */ - private static class LinuxPRNGSecureRandomProvider extends Provider { - - public LinuxPRNGSecureRandomProvider() { - super("LinuxPRNG", 1.0, - "A Linux-specific random number provider that uses" - + " /dev/urandom"); - // Although /dev/urandom is not a SHA-1 PRNG, some apps - // explicitly request a SHA1PRNG SecureRandom and we thus need to - // prevent them from getting the default implementation whose output - // may have low entropy. - put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName()); - put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); - } - } - - /** - * {@link SecureRandomSpi} which passes all requests to the Linux PRNG ( - * {@code /dev/urandom}). - */ - public static class LinuxPRNGSecureRandom extends SecureRandomSpi { - - /* - * IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed - * are passed through to the Linux PRNG (/dev/urandom). Instances of - * this class seed themselves by mixing in the current time, PID, UID, - * build fingerprint, and hardware serial number (where available) into - * Linux PRNG. - * - * Concurrency: Read requests to the underlying Linux PRNG are - * serialized (on sLock) to ensure that multiple threads do not get - * duplicated PRNG output. - */ - - private static final File URANDOM_FILE = new File("/dev/urandom"); - - private static final Object sLock = new Object(); - - /** - * Input stream for reading from Linux PRNG or {@code null} if not yet - * opened. - * - * @GuardedBy("sLock") - */ - private static DataInputStream sUrandomIn; - - /** - * Output stream for writing to Linux PRNG or {@code null} if not yet - * opened. - * - * @GuardedBy("sLock") - */ - private static OutputStream sUrandomOut; - - /** - * Whether this engine instance has been seeded. This is needed because - * each instance needs to seed itself if the client does not explicitly - * seed it. - */ - private boolean mSeeded; - - @Override - protected void engineSetSeed(byte[] bytes) { - try { - OutputStream out; - synchronized (sLock) { - out = getUrandomOutputStream(); - } - out.write(bytes); - out.flush(); - } catch (IOException e) { - // On a small fraction of devices /dev/urandom is not writable. - // Log and ignore. - Log.w(PRNGFixes.class.getSimpleName(), - "Failed to mix seed into " + URANDOM_FILE); - } finally { - mSeeded = true; - } - } - - @Override - protected void engineNextBytes(byte[] bytes) { - if (!mSeeded) { - // Mix in the device- and invocation-specific seed. - engineSetSeed(generateSeed()); - } - - try { - DataInputStream in; - synchronized (sLock) { - in = getUrandomInputStream(); - } - synchronized (in) { - in.readFully(bytes); - } - } catch (IOException e) { - throw new SecurityException("Failed to read from " - + URANDOM_FILE, e); - } - } - - @Override - protected byte[] engineGenerateSeed(int size) { - byte[] seed = new byte[size]; - engineNextBytes(seed); - return seed; - } - - private DataInputStream getUrandomInputStream() { - synchronized (sLock) { - if (sUrandomIn == null) { - // NOTE: Consider inserting a BufferedInputStream between - // DataInputStream and FileInputStream if you need higher - // PRNG output performance and can live with future PRNG - // output being pulled into this process prematurely. - try { - sUrandomIn = new DataInputStream(new FileInputStream( - URANDOM_FILE)); - } catch (IOException e) { - throw new SecurityException("Failed to open " - + URANDOM_FILE + " for reading", e); - } - } - return sUrandomIn; - } - } - - private OutputStream getUrandomOutputStream() throws IOException { - synchronized (sLock) { - if (sUrandomOut == null) { - sUrandomOut = new FileOutputStream(URANDOM_FILE); - } - return sUrandomOut; - } - } - } - - /** - * Generates a device- and invocation-specific seed to be mixed into the - * Linux PRNG. - */ - private static byte[] generateSeed() { - try { - ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); - DataOutputStream seedBufferOut = new DataOutputStream(seedBuffer); - seedBufferOut.writeLong(System.currentTimeMillis()); - seedBufferOut.writeLong(System.nanoTime()); - seedBufferOut.writeInt(Process.myPid()); - seedBufferOut.writeInt(Process.myUid()); - seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL); - seedBufferOut.close(); - return seedBuffer.toByteArray(); - } catch (IOException e) { - throw new SecurityException("Failed to generate seed", e); - } - } - - /** - * Gets the hardware serial number of this device. - * - * @return serial number or {@code null} if not available. - */ - private static String getDeviceSerialNumber() { - // We're using the Reflection API because Build.SERIAL is only available - // since API Level 9 (Gingerbread, Android 2.3). - try { - return (String) Build.class.getField("SERIAL").get(null); - } catch (Exception ignored) { - return null; - } - } - - private static byte[] getBuildFingerprintAndDeviceSerial() { - StringBuilder result = new StringBuilder(); - String fingerprint = Build.FINGERPRINT; - if (fingerprint != null) { - result.append(fingerprint); - } - String serial = getDeviceSerialNumber(); - if (serial != null) { - result.append(serial); - } - try { - return result.toString().getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 encoding not supported"); - } - } -} \ No newline at end of file diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/conversations/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java deleted file mode 100644 index 5becc7e7..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ /dev/null @@ -1,95 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.RejectedExecutionException; - -import android.content.Context; -import android.content.CursorLoader; -import android.content.Loader; -import android.content.Loader.OnLoadCompleteListener; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.provider.ContactsContract; -import android.provider.ContactsContract.Profile; - -public class PhoneHelper { - - public static void loadPhoneContacts(Context context, - final OnPhoneContactsLoadedListener listener) { - final List phoneContacts = new ArrayList(); - - final String[] PROJECTION = new String[] { ContactsContract.Data._ID, - ContactsContract.Data.DISPLAY_NAME, - ContactsContract.Data.PHOTO_URI, - ContactsContract.Data.LOOKUP_KEY, - ContactsContract.CommonDataKinds.Im.DATA }; - - final String SELECTION = "(" + ContactsContract.Data.MIMETYPE + "=\"" - + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL - + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER - + "\")"; - - CursorLoader mCursorLoader = new CursorLoader(context, - ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, - null); - mCursorLoader.registerListener(0, new OnLoadCompleteListener() { - - @Override - public void onLoadComplete(Loader arg0, Cursor cursor) { - if (cursor == null) { - return; - } - while (cursor.moveToNext()) { - Bundle contact = new Bundle(); - contact.putInt("phoneid", cursor.getInt(cursor - .getColumnIndex(ContactsContract.Data._ID))); - contact.putString( - "displayname", - cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); - contact.putString("photouri", cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.PHOTO_URI))); - contact.putString("lookup", cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.LOOKUP_KEY))); - - contact.putString( - "jid", - cursor.getString(cursor - .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA))); - phoneContacts.add(contact); - } - if (listener != null) { - listener.onPhoneContactsLoaded(phoneContacts); - } - } - }); - try { - mCursorLoader.startLoading(); - } catch (RejectedExecutionException e) { - if (listener != null) { - listener.onPhoneContactsLoaded(phoneContacts); - } - } - } - - public static Uri getSefliUri(Context context) { - String[] mProjection = new String[] { Profile._ID, Profile.PHOTO_URI }; - Cursor mProfileCursor = context.getContentResolver().query( - Profile.CONTENT_URI, mProjection, null, null, null); - - if (mProfileCursor == null || mProfileCursor.getCount() == 0) { - return null; - } else { - mProfileCursor.moveToFirst(); - String uri = mProfileCursor.getString(1); - if (uri == null) { - return null; - } else { - return Uri.parse(uri); - } - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/conversations/src/main/java/eu/siacs/conversations/utils/UIHelper.java deleted file mode 100644 index 5141c83c..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ /dev/null @@ -1,225 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.regex.Pattern; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.ui.ConversationActivity; -import eu.siacs.conversations.ui.ManageAccountActivity; -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.TaskStackBuilder; -import android.text.format.DateFormat; -import android.text.format.DateUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.TextView; - -public class UIHelper { - private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; - private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE; - - public static String readableTimeDifference(Context context, long time) { - return readableTimeDifference(context, time, false); - } - - public static String readableTimeDifferenceFull(Context context, long time) { - return readableTimeDifference(context, time, true); - } - - private static String readableTimeDifference(Context context, long time, - boolean fullDate) { - if (time == 0) { - return context.getString(R.string.just_now); - } - Date date = new Date(time); - long difference = (System.currentTimeMillis() - time) / 1000; - if (difference < 60) { - return context.getString(R.string.just_now); - } else if (difference < 60 * 2) { - return context.getString(R.string.minute_ago); - } else if (difference < 60 * 15) { - return context.getString(R.string.minutes_ago, - Math.round(difference / 60.0)); - } else if (today(date)) { - java.text.DateFormat df = DateFormat.getTimeFormat(context); - return df.format(date); - } else { - if (fullDate) { - return DateUtils.formatDateTime(context, date.getTime(), - FULL_DATE_FLAGS); - } else { - return DateUtils.formatDateTime(context, date.getTime(), - SHORT_DATE_FLAGS); - } - } - } - - private static boolean today(Date date) { - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - cal1.setTime(date); - cal2.setTimeInMillis(System.currentTimeMillis()); - return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) - && cal1.get(Calendar.DAY_OF_YEAR) == cal2 - .get(Calendar.DAY_OF_YEAR); - } - - public static String lastseen(Context context, long time) { - if (time == 0) { - return context.getString(R.string.never_seen); - } - long difference = (System.currentTimeMillis() - time) / 1000; - if (difference < 60) { - return context.getString(R.string.last_seen_now); - } else if (difference < 60 * 2) { - return context.getString(R.string.last_seen_min); - } else if (difference < 60 * 60) { - return context.getString(R.string.last_seen_mins, - Math.round(difference / 60.0)); - } else if (difference < 60 * 60 * 2) { - return context.getString(R.string.last_seen_hour); - } else if (difference < 60 * 60 * 24) { - return context.getString(R.string.last_seen_hours, - Math.round(difference / (60.0 * 60.0))); - } else if (difference < 60 * 60 * 48) { - return context.getString(R.string.last_seen_day); - } else { - return context.getString(R.string.last_seen_days, - Math.round(difference / (60.0 * 60.0 * 24.0))); - } - } - - public static void showErrorNotification(Context context, - List accounts) { - NotificationManager mNotificationManager = (NotificationManager) context - .getSystemService(Context.NOTIFICATION_SERVICE); - List accountsWproblems = new ArrayList(); - for (Account account : accounts) { - if (account.hasErrorStatus()) { - accountsWproblems.add(account); - } - } - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( - context); - if (accountsWproblems.size() == 0) { - mNotificationManager.cancel(1111); - return; - } else if (accountsWproblems.size() == 1) { - mBuilder.setContentTitle(context - .getString(R.string.problem_connecting_to_account)); - mBuilder.setContentText(accountsWproblems.get(0).getJid()); - } else { - mBuilder.setContentTitle(context - .getString(R.string.problem_connecting_to_accounts)); - mBuilder.setContentText(context.getString(R.string.touch_to_fix)); - } - mBuilder.setOngoing(true); - mBuilder.setLights(0xffffffff, 2000, 4000); - mBuilder.setSmallIcon(R.drawable.ic_notification); - TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); - stackBuilder.addParentStack(ConversationActivity.class); - - Intent manageAccountsIntent = new Intent(context, - ManageAccountActivity.class); - stackBuilder.addNextIntent(manageAccountsIntent); - - PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, - PendingIntent.FLAG_UPDATE_CURRENT); - - mBuilder.setContentIntent(resultPendingIntent); - Notification notification = mBuilder.build(); - mNotificationManager.notify(1111, notification); - } - - @SuppressLint("InflateParams") - public static AlertDialog getVerifyFingerprintDialog( - final ConversationActivity activity, - final Conversation conversation, final View msg) { - final Contact contact = conversation.getContact(); - final Account account = conversation.getAccount(); - - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle("Verify fingerprint"); - LayoutInflater inflater = activity.getLayoutInflater(); - View view = inflater.inflate(R.layout.dialog_verify_otr, null); - TextView jid = (TextView) view.findViewById(R.id.verify_otr_jid); - TextView fingerprint = (TextView) view - .findViewById(R.id.verify_otr_fingerprint); - TextView yourprint = (TextView) view - .findViewById(R.id.verify_otr_yourprint); - - jid.setText(contact.getJid()); - fingerprint.setText(conversation.getOtrFingerprint()); - yourprint.setText(account.getOtrFingerprint()); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Verify", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - contact.addOtrFingerprint(conversation.getOtrFingerprint()); - msg.setVisibility(View.GONE); - activity.xmppConnectionService.syncRosterToDisk(account); - } - }); - builder.setView(view); - return builder.create(); - } - - private final static class EmoticonPattern { - Pattern pattern; - String replacement; - - EmoticonPattern(String ascii, int unicode) { - this.pattern = Pattern.compile("(?<=(^|\\s))" + ascii - + "(?=(\\s|$))"); - this.replacement = new String(new int[] { unicode, }, 0, 1); - } - - String replaceAll(String body) { - return pattern.matcher(body).replaceAll(replacement); - } - } - - private static final EmoticonPattern[] patterns = new EmoticonPattern[] { - new EmoticonPattern(":-?D", 0x1f600), - new EmoticonPattern("\\^\\^", 0x1f601), - new EmoticonPattern(":'D", 0x1f602), - new EmoticonPattern("\\]-?D", 0x1f608), - new EmoticonPattern(";-?\\)", 0x1f609), - new EmoticonPattern(":-?\\)", 0x1f60a), - new EmoticonPattern("[B8]-?\\)", 0x1f60e), - new EmoticonPattern(":-?\\|", 0x1f610), - new EmoticonPattern(":-?[/\\\\]", 0x1f615), - new EmoticonPattern(":-?\\*", 0x1f617), - new EmoticonPattern(":-?[Ppb]", 0x1f61b), - new EmoticonPattern(":-?\\(", 0x1f61e), - new EmoticonPattern(":-?[0Oo]", 0x1f62e), - new EmoticonPattern("\\\\o/", 0x1F631), }; - - public static String transformAsciiEmoticons(String body) { - if (body != null) { - for (EmoticonPattern p : patterns) { - body = p.replaceAll(body); - } - body = body.trim(); - } - return body; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/Validator.java b/conversations/src/main/java/eu/siacs/conversations/utils/Validator.java deleted file mode 100644 index 00130fa2..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/Validator.java +++ /dev/null @@ -1,14 +0,0 @@ -package eu.siacs.conversations.utils; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Validator { - public static final Pattern VALID_JID = Pattern.compile( - "^[^@/<>'\"\\s]+@[^@/<>'\"\\s]+$", Pattern.CASE_INSENSITIVE); - - public static boolean isValidJid(String jid) { - Matcher matcher = VALID_JID.matcher(jid); - return matcher.find(); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/XmlHelper.java b/conversations/src/main/java/eu/siacs/conversations/utils/XmlHelper.java deleted file mode 100644 index 4dee07cf..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/XmlHelper.java +++ /dev/null @@ -1,12 +0,0 @@ -package eu.siacs.conversations.utils; - -public class XmlHelper { - public static String encodeEntities(String content) { - content = content.replace("&", "&"); - content = content.replace("<", "<"); - content = content.replace(">", ">"); - content = content.replace("\"", """); - content = content.replace("'", "'"); - return content; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibInputStream.java b/conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibInputStream.java deleted file mode 100644 index b777c10c..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibInputStream.java +++ /dev/null @@ -1,54 +0,0 @@ -package eu.siacs.conversations.utils.zlib; - -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.Inflater; -import java.util.zip.InflaterInputStream; - -/** - * ZLibInputStream is a zlib and input stream compatible version of an - * InflaterInputStream. This class solves the incompatibility between - * {@link InputStream#available()} and {@link InflaterInputStream#available()}. - */ -public class ZLibInputStream extends InflaterInputStream { - - /** - * Construct a ZLibInputStream, reading data from the underlying stream. - * - * @param is - * The {@code InputStream} to read data from. - * @throws IOException - * If an {@code IOException} occurs. - */ - public ZLibInputStream(InputStream is) throws IOException { - super(is, new Inflater(), 512); - } - - /** - * Provide a more InputStream compatible version of available. A return - * value of 1 means that it is likly to read one byte without blocking, 0 - * means that the system is known to block for more input. - * - * @return 0 if no data is available, 1 otherwise - * @throws IOException - */ - @Override - public int available() throws IOException { - /* - * This is one of the funny code blocks. InflaterInputStream.available - * violates the contract of InputStream.available, which breaks kXML2. - * - * I'm not sure who's to blame, oracle/sun for a broken api or the - * google guys for mixing a sun bug with a xml reader that can't handle - * it.... - * - * Anyway, this simple if breaks suns distorted reality, but helps to - * use the api as intended. - */ - if (inf.needsInput()) { - return 0; - } - return super.available(); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java b/conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java deleted file mode 100644 index 8b3f5e68..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java +++ /dev/null @@ -1,95 +0,0 @@ -package eu.siacs.conversations.utils.zlib; - -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.security.NoSuchAlgorithmException; -import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; - -/** - *

- * Android 2.2 includes Java7 FLUSH_SYNC option, which will be used by this - * Implementation, preferable via reflection. The @hide was remove in API level - * 19. This class might thus go away in the future. - *

- *

- * Please use {@link ZLibOutputStream#SUPPORTED} to check for flush - * compatibility. - *

- */ -public class ZLibOutputStream extends DeflaterOutputStream { - - /** - * The reflection based flush method. - */ - - private final static Method method; - /** - * SUPPORTED is true if a flush compatible method exists. - */ - public final static boolean SUPPORTED; - - /** - * Static block to initialize {@link #SUPPORTED} and {@link #method}. - */ - static { - Method m = null; - try { - m = Deflater.class.getMethod("deflate", byte[].class, int.class, - int.class, int.class); - } catch (SecurityException e) { - } catch (NoSuchMethodException e) { - } - method = m; - SUPPORTED = (method != null); - } - - /** - * Create a new ZLib compatible output stream wrapping the given low level - * stream. ZLib compatiblity means we will send a zlib header. - * - * @param os - * OutputStream The underlying stream. - * @throws IOException - * In case of a lowlevel transfer problem. - * @throws NoSuchAlgorithmException - * In case of a {@link Deflater} error. - */ - public ZLibOutputStream(OutputStream os) throws IOException, - NoSuchAlgorithmException { - super(os, new Deflater(Deflater.BEST_COMPRESSION)); - } - - /** - * Flush the given stream, preferring Java7 FLUSH_SYNC if available. - * - * @throws IOException - * In case of a lowlevel exception. - */ - @Override - public void flush() throws IOException { - if (!SUPPORTED) { - super.flush(); - return; - } - try { - int count = 0; - do { - count = (Integer) method.invoke(def, buf, 0, buf.length, 3); - if (count > 0) { - out.write(buf, 0, count); - } - } while (count > 0); - } catch (IllegalArgumentException e) { - throw new IOException("Can't flush"); - } catch (IllegalAccessException e) { - throw new IOException("Can't flush"); - } catch (InvocationTargetException e) { - throw new IOException("Can't flush"); - } - super.flush(); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xml/Element.java b/conversations/src/main/java/eu/siacs/conversations/xml/Element.java deleted file mode 100644 index 4e11ee2c..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xml/Element.java +++ /dev/null @@ -1,148 +0,0 @@ -package eu.siacs.conversations.xml; - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; - -import eu.siacs.conversations.utils.XmlHelper; - -public class Element { - protected String name; - protected Hashtable attributes = new Hashtable(); - protected String content; - protected List children = new ArrayList(); - - public Element(String name) { - this.name = name; - } - - public Element addChild(Element child) { - this.content = null; - children.add(child); - return child; - } - - public Element addChild(String name) { - this.content = null; - Element child = new Element(name); - children.add(child); - return child; - } - - public Element addChild(String name, String xmlns) { - this.content = null; - Element child = new Element(name); - child.setAttribute("xmlns", xmlns); - children.add(child); - return child; - } - - public Element setContent(String content) { - this.content = content; - this.children.clear(); - return this; - } - - public Element findChild(String name) { - for (Element child : this.children) { - if (child.getName().equals(name)) { - return child; - } - } - return null; - } - - public Element findChild(String name, String xmlns) { - for (Element child : this.children) { - if (child.getName().equals(name) - && (child.getAttribute("xmlns").equals(xmlns))) { - return child; - } - } - return null; - } - - public boolean hasChild(String name) { - return findChild(name) != null; - } - - public boolean hasChild(String name, String xmlns) { - return findChild(name, xmlns) != null; - } - - public List getChildren() { - return this.children; - } - - public Element setChildren(List children) { - this.children = children; - return this; - } - - public String getContent() { - return content; - } - - public Element setAttribute(String name, String value) { - if (name != null && value != null) { - this.attributes.put(name, value); - } - return this; - } - - public Element setAttributes(Hashtable attributes) { - this.attributes = attributes; - return this; - } - - public String getAttribute(String name) { - if (this.attributes.containsKey(name)) { - return this.attributes.get(name); - } else { - return null; - } - } - - public Hashtable getAttributes() { - return this.attributes; - } - - public String toString() { - StringBuilder elementOutput = new StringBuilder(); - if ((content == null) && (children.size() == 0)) { - Tag emptyTag = Tag.empty(name); - emptyTag.setAtttributes(this.attributes); - elementOutput.append(emptyTag.toString()); - } else { - Tag startTag = Tag.start(name); - startTag.setAtttributes(this.attributes); - elementOutput.append(startTag); - if (content != null) { - elementOutput.append(XmlHelper.encodeEntities(content)); - } else { - for (Element child : children) { - elementOutput.append(child.toString()); - } - } - Tag endTag = Tag.end(name); - elementOutput.append(endTag); - } - return elementOutput.toString(); - } - - public String getName() { - return name; - } - - public void clearChildren() { - this.children.clear(); - } - - public void setAttribute(String name, long value) { - this.setAttribute(name, Long.toString(value)); - } - - public void setAttribute(String name, int value) { - this.setAttribute(name, Integer.toString(value)); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xml/Tag.java b/conversations/src/main/java/eu/siacs/conversations/xml/Tag.java deleted file mode 100644 index b9ef979f..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xml/Tag.java +++ /dev/null @@ -1,104 +0,0 @@ -package eu.siacs.conversations.xml; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.Set; - -import eu.siacs.conversations.utils.XmlHelper; - -public class Tag { - public static final int NO = -1; - public static final int START = 0; - public static final int END = 1; - public static final int EMPTY = 2; - - protected int type; - protected String name; - protected Hashtable attributes = new Hashtable(); - - protected Tag(int type, String name) { - this.type = type; - this.name = name; - } - - public static Tag no(String text) { - return new Tag(NO, text); - } - - public static Tag start(String name) { - return new Tag(START, name); - } - - public static Tag end(String name) { - return new Tag(END, name); - } - - public static Tag empty(String name) { - return new Tag(EMPTY, name); - } - - public String getName() { - return name; - } - - public String getAttribute(String attrName) { - return this.attributes.get(attrName); - } - - public Tag setAttribute(String attrName, String attrValue) { - this.attributes.put(attrName, attrValue); - return this; - } - - public Tag setAtttributes(Hashtable attributes) { - this.attributes = attributes; - return this; - } - - public boolean isStart(String needle) { - if (needle == null) - return false; - return (this.type == START) && (needle.equals(this.name)); - } - - public boolean isEnd(String needle) { - if (needle == null) - return false; - return (this.type == END) && (needle.equals(this.name)); - } - - public boolean isNo() { - return (this.type == NO); - } - - public String toString() { - StringBuilder tagOutput = new StringBuilder(); - tagOutput.append('<'); - if (type == END) { - tagOutput.append('/'); - } - tagOutput.append(name); - if (type != END) { - Set> attributeSet = attributes.entrySet(); - Iterator> it = attributeSet.iterator(); - while (it.hasNext()) { - Entry entry = it.next(); - tagOutput.append(' '); - tagOutput.append(entry.getKey()); - tagOutput.append("=\""); - tagOutput.append(XmlHelper.encodeEntities(entry.getValue())); - tagOutput.append('"'); - } - } - if (type == EMPTY) { - tagOutput.append('/'); - } - tagOutput.append('>'); - return tagOutput.toString(); - } - - public Hashtable getAttributes() { - return this.attributes; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xml/TagWriter.java b/conversations/src/main/java/eu/siacs/conversations/xml/TagWriter.java deleted file mode 100644 index f11c1846..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xml/TagWriter.java +++ /dev/null @@ -1,114 +0,0 @@ -package eu.siacs.conversations.xml; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.util.concurrent.LinkedBlockingQueue; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class TagWriter { - - private OutputStream plainOutputStream; - private OutputStreamWriter outputStream; - private boolean finshed = false; - private LinkedBlockingQueue writeQueue = new LinkedBlockingQueue(); - private Thread asyncStanzaWriter = new Thread() { - private boolean shouldStop = false; - - @Override - public void run() { - while (!shouldStop) { - if ((finshed) && (writeQueue.size() == 0)) { - return; - } - try { - AbstractStanza output = writeQueue.take(); - if (outputStream == null) { - shouldStop = true; - } else { - outputStream.write(output.toString()); - outputStream.flush(); - } - } catch (IOException e) { - shouldStop = true; - } catch (InterruptedException e) { - shouldStop = true; - } - } - } - }; - - public TagWriter() { - } - - public void setOutputStream(OutputStream out) throws IOException { - if (out == null) { - throw new IOException(); - } - this.plainOutputStream = out; - this.outputStream = new OutputStreamWriter(out); - } - - public OutputStream getOutputStream() throws IOException { - if (this.plainOutputStream == null) { - throw new IOException(); - } - return this.plainOutputStream; - } - - public TagWriter beginDocument() throws IOException { - if (outputStream == null) { - throw new IOException("output stream was null"); - } - outputStream.write(""); - outputStream.flush(); - return this; - } - - public TagWriter writeTag(Tag tag) throws IOException { - if (outputStream == null) { - throw new IOException("output stream was null"); - } - outputStream.write(tag.toString()); - outputStream.flush(); - return this; - } - - public TagWriter writeElement(Element element) throws IOException { - if (outputStream == null) { - throw new IOException("output stream was null"); - } - outputStream.write(element.toString()); - outputStream.flush(); - return this; - } - - public TagWriter writeStanzaAsync(AbstractStanza stanza) { - if (finshed) { - return this; - } else { - if (!asyncStanzaWriter.isAlive()) { - try { - asyncStanzaWriter.start(); - } catch (IllegalThreadStateException e) { - // already started - } - } - writeQueue.add(stanza); - return this; - } - } - - public void finish() { - this.finshed = true; - } - - public boolean finished() { - return (this.writeQueue.size() == 0); - } - - public boolean isActive() { - return outputStream != null; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xml/XmlReader.java b/conversations/src/main/java/eu/siacs/conversations/xml/XmlReader.java deleted file mode 100644 index 52d3d46a..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xml/XmlReader.java +++ /dev/null @@ -1,141 +0,0 @@ -package eu.siacs.conversations.xml; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import eu.siacs.conversations.Config; - -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.util.Log; -import android.util.Xml; - -public class XmlReader { - private XmlPullParser parser; - private PowerManager.WakeLock wakeLock; - private InputStream is; - - public XmlReader(WakeLock wakeLock) { - this.parser = Xml.newPullParser(); - try { - this.parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, - true); - } catch (XmlPullParserException e) { - Log.d(Config.LOGTAG, "error setting namespace feature on parser"); - } - this.wakeLock = wakeLock; - } - - public void setInputStream(InputStream inputStream) throws IOException { - if (inputStream == null) { - throw new IOException(); - } - this.is = inputStream; - try { - parser.setInput(new InputStreamReader(this.is)); - } catch (XmlPullParserException e) { - throw new IOException("error resetting parser"); - } - } - - public InputStream getInputStream() throws IOException { - if (this.is == null) { - throw new IOException(); - } - return is; - } - - public void reset() throws IOException { - if (this.is == null) { - throw new IOException(); - } - try { - parser.setInput(new InputStreamReader(this.is)); - } catch (XmlPullParserException e) { - throw new IOException("error resetting parser"); - } - } - - public Tag readTag() throws XmlPullParserException, IOException { - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - try { - while (this.is != null - && parser.next() != XmlPullParser.END_DOCUMENT) { - wakeLock.acquire(); - if (parser.getEventType() == XmlPullParser.START_TAG) { - Tag tag = Tag.start(parser.getName()); - for (int i = 0; i < parser.getAttributeCount(); ++i) { - tag.setAttribute(parser.getAttributeName(i), - parser.getAttributeValue(i)); - } - String xmlns = parser.getNamespace(); - if (xmlns != null) { - tag.setAttribute("xmlns", xmlns); - } - return tag; - } else if (parser.getEventType() == XmlPullParser.END_TAG) { - Tag tag = Tag.end(parser.getName()); - return tag; - } else if (parser.getEventType() == XmlPullParser.TEXT) { - Tag tag = Tag.no(parser.getText()); - return tag; - } - } - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - } catch (ArrayIndexOutOfBoundsException e) { - throw new IOException( - "xml parser mishandled ArrayIndexOufOfBounds", e); - } catch (StringIndexOutOfBoundsException e) { - throw new IOException( - "xml parser mishandled StringIndexOufOfBounds", e); - } catch (NullPointerException e) { - throw new IOException("xml parser mishandled NullPointerException", - e); - } catch (IndexOutOfBoundsException e) { - throw new IOException("xml parser mishandled IndexOutOfBound", e); - } - return null; - } - - public Element readElement(Tag currentTag) throws XmlPullParserException, - IOException { - Element element = new Element(currentTag.getName()); - element.setAttributes(currentTag.getAttributes()); - Tag nextTag = this.readTag(); - if (nextTag == null) { - throw new IOException("unterupted mid tag"); - } - if (nextTag.isNo()) { - element.setContent(nextTag.getName()); - nextTag = this.readTag(); - if (nextTag == null) { - throw new IOException("unterupted mid tag"); - } - } - while (!nextTag.isEnd(element.getName())) { - if (!nextTag.isNo()) { - Element child = this.readElement(nextTag); - element.addChild(child); - } - nextTag = this.readTag(); - if (nextTag == null) { - throw new IOException("unterupted mid tag"); - } - } - return element; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnBindListener.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnBindListener.java deleted file mode 100644 index f09cf33d..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnBindListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Account; - -public interface OnBindListener { - public void onBind(Account account); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnContactStatusChanged.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnContactStatusChanged.java deleted file mode 100644 index 849e8e76..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnContactStatusChanged.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Contact; - -public interface OnContactStatusChanged { - public void onContactStatusChanged(Contact contact, boolean online); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnIqPacketReceived.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnIqPacketReceived.java deleted file mode 100644 index a4cff986..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnIqPacketReceived.java +++ /dev/null @@ -1,8 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public interface OnIqPacketReceived extends PacketReceived { - public void onIqPacketReceived(Account account, IqPacket packet); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessageAcknowledged.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessageAcknowledged.java deleted file mode 100644 index 5f670d93..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessageAcknowledged.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Account; - -public interface OnMessageAcknowledged { - public void onMessageAcknowledged(Account account, String id); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessagePacketReceived.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessagePacketReceived.java deleted file mode 100644 index 325e945f..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnMessagePacketReceived.java +++ /dev/null @@ -1,8 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; - -public interface OnMessagePacketReceived extends PacketReceived { - public void onMessagePacketReceived(Account account, MessagePacket packet); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnPresencePacketReceived.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnPresencePacketReceived.java deleted file mode 100644 index 95c1acfc..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnPresencePacketReceived.java +++ /dev/null @@ -1,8 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.xmpp.stanzas.PresencePacket; - -public interface OnPresencePacketReceived extends PacketReceived { - public void onPresencePacketReceived(Account account, PresencePacket packet); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnStatusChanged.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/OnStatusChanged.java deleted file mode 100644 index ad1d98cb..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/OnStatusChanged.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import eu.siacs.conversations.entities.Account; - -public interface OnStatusChanged { - public void onStatusChanged(Account account); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/PacketReceived.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/PacketReceived.java deleted file mode 100644 index d4502d73..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/PacketReceived.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.siacs.conversations.xmpp; - -public abstract interface PacketReceived { - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java deleted file mode 100644 index 903dc59d..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ /dev/null @@ -1,1130 +0,0 @@ -package eu.siacs.conversations.xmpp; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.net.Socket; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; - -import javax.net.ssl.X509TrustManager; - -import org.apache.http.conn.ssl.StrictHostnameVerifier; -import org.xmlpull.v1.XmlPullParserException; - -import de.duenndns.ssl.MemorizingTrustManager; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.SystemClock; -import android.preference.PreferenceManager; -import android.util.Log; -import android.util.SparseArray; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; -import eu.siacs.conversations.utils.DNSHelper; -import eu.siacs.conversations.utils.zlib.ZLibOutputStream; -import eu.siacs.conversations.utils.zlib.ZLibInputStream; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xml.Tag; -import eu.siacs.conversations.xml.TagWriter; -import eu.siacs.conversations.xml.XmlReader; -import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived; -import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; -import eu.siacs.conversations.xmpp.stanzas.PresencePacket; -import eu.siacs.conversations.xmpp.stanzas.csi.ActivePacket; -import eu.siacs.conversations.xmpp.stanzas.csi.InactivePacket; -import eu.siacs.conversations.xmpp.stanzas.streammgmt.AckPacket; -import eu.siacs.conversations.xmpp.stanzas.streammgmt.EnablePacket; -import eu.siacs.conversations.xmpp.stanzas.streammgmt.RequestPacket; -import eu.siacs.conversations.xmpp.stanzas.streammgmt.ResumePacket; - -public class XmppConnection implements Runnable { - - protected Account account; - - private WakeLock wakeLock; - - private SecureRandom mRandom; - - private Socket socket; - private XmlReader tagReader; - private TagWriter tagWriter; - - private Features features = new Features(this); - - private boolean shouldBind = true; - private boolean shouldAuthenticate = true; - private Element streamFeatures; - private HashMap> disco = new HashMap>(); - - private String streamId = null; - private int smVersion = 3; - private SparseArray messageReceipts = new SparseArray(); - - private boolean usingCompression = false; - private boolean usingEncryption = false; - - private int stanzasReceived = 0; - private int stanzasSent = 0; - - private long lastPaketReceived = 0; - private long lastPingSent = 0; - private long lastConnect = 0; - private long lastSessionStarted = 0; - - private int attempt = 0; - - private static final int PACKET_IQ = 0; - private static final int PACKET_MESSAGE = 1; - private static final int PACKET_PRESENCE = 2; - - private Hashtable packetCallbacks = new Hashtable(); - private OnPresencePacketReceived presenceListener = null; - private OnJinglePacketReceived jingleListener = null; - private OnIqPacketReceived unregisteredIqListener = null; - private OnMessagePacketReceived messageListener = null; - private OnStatusChanged statusListener = null; - private OnBindListener bindListener = null; - private OnMessageAcknowledged acknowledgedListener = null; - private MemorizingTrustManager mMemorizingTrustManager; - private final Context applicationContext; - - public XmppConnection(Account account, XmppConnectionService service) { - this.mRandom = service.getRNG(); - this.mMemorizingTrustManager = service.getMemorizingTrustManager(); - this.account = account; - this.wakeLock = service.getPowerManager().newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, account.getJid()); - tagWriter = new TagWriter(); - applicationContext = service.getApplicationContext(); - } - - protected void changeStatus(int nextStatus) { - if (account.getStatus() != nextStatus) { - if ((nextStatus == Account.STATUS_OFFLINE) - && (account.getStatus() != Account.STATUS_CONNECTING) - && (account.getStatus() != Account.STATUS_ONLINE) - && (account.getStatus() != Account.STATUS_DISABLED)) { - return; - } - if (nextStatus == Account.STATUS_ONLINE) { - this.attempt = 0; - } - account.setStatus(nextStatus); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - } - } - - protected void connect() { - Log.d(Config.LOGTAG, account.getJid() + ": connecting"); - usingCompression = false; - usingEncryption = false; - lastConnect = SystemClock.elapsedRealtime(); - lastPingSent = SystemClock.elapsedRealtime(); - this.attempt++; - try { - shouldAuthenticate = shouldBind = !account - .isOptionSet(Account.OPTION_REGISTER); - tagReader = new XmlReader(wakeLock); - tagWriter = new TagWriter(); - packetCallbacks.clear(); - this.changeStatus(Account.STATUS_CONNECTING); - Bundle namePort = DNSHelper.getSRVRecord(account.getServer()); - if ("timeout".equals(namePort.getString("error"))) { - Log.d(Config.LOGTAG, account.getJid() + ": dns timeout"); - this.changeStatus(Account.STATUS_OFFLINE); - return; - } - String srvRecordServer = namePort.getString("name"); - String srvIpServer = namePort.getString("ipv4"); - int srvRecordPort = namePort.getInt("port"); - if (srvRecordServer != null) { - if (srvIpServer != null) { - Log.d(Config.LOGTAG, account.getJid() - + ": using values from dns " + srvRecordServer - + "[" + srvIpServer + "]:" + srvRecordPort); - socket = new Socket(srvIpServer, srvRecordPort); - } else { - boolean socketError = true; - int srvIndex = 0; - while (socketError - && namePort.containsKey("name" + srvIndex)) { - try { - srvRecordServer = namePort.getString("name" - + srvIndex); - srvRecordPort = namePort.getInt("port" + srvIndex); - Log.d(Config.LOGTAG, account.getJid() - + ": using values from dns " - + srvRecordServer + ":" + srvRecordPort); - socket = new Socket(srvRecordServer, srvRecordPort); - socketError = false; - } catch (UnknownHostException e) { - srvIndex++; - if (!namePort.containsKey("name" + srvIndex)) { - throw e; - } - } catch (IOException e) { - srvIndex++; - if (!namePort.containsKey("name" + srvIndex)) { - throw e; - } - } - } - } - } else if (namePort.containsKey("error") - && "nosrv".equals(namePort.getString("error", null))) { - socket = new Socket(account.getServer(), 5222); - } else { - Log.d(Config.LOGTAG, account.getJid() - + ": timeout in DNS resolution"); - changeStatus(Account.STATUS_OFFLINE); - return; - } - OutputStream out = socket.getOutputStream(); - tagWriter.setOutputStream(out); - InputStream in = socket.getInputStream(); - tagReader.setInputStream(in); - tagWriter.beginDocument(); - sendStartStream(); - Tag nextTag; - while ((nextTag = tagReader.readTag()) != null) { - if (nextTag.isStart("stream")) { - processStream(nextTag); - break; - } else { - Log.d(Config.LOGTAG, - "found unexpected tag: " + nextTag.getName()); - return; - } - } - if (socket.isConnected()) { - socket.close(); - } - } catch (UnknownHostException e) { - this.changeStatus(Account.STATUS_SERVER_NOT_FOUND); - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - return; - } catch (IOException e) { - this.changeStatus(Account.STATUS_OFFLINE); - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - return; - } catch (NoSuchAlgorithmException e) { - this.changeStatus(Account.STATUS_OFFLINE); - Log.d(Config.LOGTAG, "compression exception " + e.getMessage()); - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - return; - } catch (XmlPullParserException e) { - this.changeStatus(Account.STATUS_OFFLINE); - Log.d(Config.LOGTAG, "xml exception " + e.getMessage()); - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (RuntimeException re) { - } - } - return; - } - - } - - @Override - public void run() { - connect(); - } - - private void processStream(Tag currentTag) throws XmlPullParserException, - IOException, NoSuchAlgorithmException { - Tag nextTag = tagReader.readTag(); - while ((nextTag != null) && (!nextTag.isEnd("stream"))) { - if (nextTag.isStart("error")) { - processStreamError(nextTag); - } else if (nextTag.isStart("features")) { - processStreamFeatures(nextTag); - } else if (nextTag.isStart("proceed")) { - switchOverToTls(nextTag); - } else if (nextTag.isStart("compressed")) { - switchOverToZLib(nextTag); - } else if (nextTag.isStart("success")) { - Log.d(Config.LOGTAG, account.getJid() + ": logged in"); - tagReader.readTag(); - tagReader.reset(); - sendStartStream(); - processStream(tagReader.readTag()); - break; - } else if (nextTag.isStart("failure")) { - tagReader.readElement(nextTag); - changeStatus(Account.STATUS_UNAUTHORIZED); - } else if (nextTag.isStart("challenge")) { - String challange = tagReader.readElement(nextTag).getContent(); - Element response = new Element("response"); - response.setAttribute("xmlns", - "urn:ietf:params:xml:ns:xmpp-sasl"); - response.setContent(CryptoHelper.saslDigestMd5(account, - challange, mRandom)); - tagWriter.writeElement(response); - } else if (nextTag.isStart("enabled")) { - Element enabled = tagReader.readElement(nextTag); - if ("true".equals(enabled.getAttribute("resume"))) { - this.streamId = enabled.getAttribute("id"); - Log.d(Config.LOGTAG, account.getJid() - + ": stream managment(" + smVersion - + ") enabled (resumable)"); - } else { - Log.d(Config.LOGTAG, account.getJid() - + ": stream managment(" + smVersion + ") enabled"); - } - this.lastSessionStarted = SystemClock.elapsedRealtime(); - this.stanzasReceived = 0; - RequestPacket r = new RequestPacket(smVersion); - tagWriter.writeStanzaAsync(r); - } else if (nextTag.isStart("resumed")) { - lastPaketReceived = SystemClock.elapsedRealtime(); - Element resumed = tagReader.readElement(nextTag); - String h = resumed.getAttribute("h"); - try { - int serverCount = Integer.parseInt(h); - if (serverCount != stanzasSent) { - Log.d(Config.LOGTAG, account.getJid() - + ": session resumed with lost packages"); - stanzasSent = serverCount; - } else { - Log.d(Config.LOGTAG, account.getJid() - + ": session resumed"); - } - if (acknowledgedListener != null) { - for (int i = 0; i < messageReceipts.size(); ++i) { - if (serverCount >= messageReceipts.keyAt(i)) { - acknowledgedListener.onMessageAcknowledged( - account, messageReceipts.valueAt(i)); - } - } - } - messageReceipts.clear(); - } catch (NumberFormatException e) { - - } - sendInitialPing(); - - } else if (nextTag.isStart("r")) { - tagReader.readElement(nextTag); - AckPacket ack = new AckPacket(this.stanzasReceived, smVersion); - tagWriter.writeStanzaAsync(ack); - } else if (nextTag.isStart("a")) { - Element ack = tagReader.readElement(nextTag); - lastPaketReceived = SystemClock.elapsedRealtime(); - int serverSequence = Integer.parseInt(ack.getAttribute("h")); - String msgId = this.messageReceipts.get(serverSequence); - if (msgId != null) { - if (this.acknowledgedListener != null) { - this.acknowledgedListener.onMessageAcknowledged( - account, msgId); - } - this.messageReceipts.remove(serverSequence); - } - } else if (nextTag.isStart("failed")) { - tagReader.readElement(nextTag); - Log.d(Config.LOGTAG, account.getJid() + ": resumption failed"); - streamId = null; - if (account.getStatus() != Account.STATUS_ONLINE) { - sendBindRequest(); - } - } else if (nextTag.isStart("iq")) { - processIq(nextTag); - } else if (nextTag.isStart("message")) { - processMessage(nextTag); - } else if (nextTag.isStart("presence")) { - processPresence(nextTag); - } - nextTag = tagReader.readTag(); - } - if (account.getStatus() == Account.STATUS_ONLINE) { - account.setStatus(Account.STATUS_OFFLINE); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - } - } - - private void sendInitialPing() { - Log.d(Config.LOGTAG, account.getJid() + ": sending intial ping"); - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); - iq.setFrom(account.getFullJid()); - iq.addChild("ping", "urn:xmpp:ping"); - this.sendIqPacket(iq, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - Log.d(Config.LOGTAG, account.getJid() - + ": online with resource " + account.getResource()); - changeStatus(Account.STATUS_ONLINE); - } - }); - } - - private Element processPacket(Tag currentTag, int packetType) - throws XmlPullParserException, IOException { - Element element; - switch (packetType) { - case PACKET_IQ: - element = new IqPacket(); - break; - case PACKET_MESSAGE: - element = new MessagePacket(); - break; - case PACKET_PRESENCE: - element = new PresencePacket(); - break; - default: - return null; - } - element.setAttributes(currentTag.getAttributes()); - Tag nextTag = tagReader.readTag(); - if (nextTag == null) { - throw new IOException("interrupted mid tag"); - } - while (!nextTag.isEnd(element.getName())) { - if (!nextTag.isNo()) { - Element child = tagReader.readElement(nextTag); - String type = currentTag.getAttribute("type"); - if (packetType == PACKET_IQ - && "jingle".equals(child.getName()) - && ("set".equalsIgnoreCase(type) || "get" - .equalsIgnoreCase(type))) { - element = new JinglePacket(); - element.setAttributes(currentTag.getAttributes()); - } - element.addChild(child); - } - nextTag = tagReader.readTag(); - if (nextTag == null) { - throw new IOException("interrupted mid tag"); - } - } - ++stanzasReceived; - lastPaketReceived = SystemClock.elapsedRealtime(); - return element; - } - - private void processIq(Tag currentTag) throws XmlPullParserException, - IOException { - IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ); - - if (packet.getId() == null) { - return; // an iq packet without id is definitely invalid - } - - if (packet instanceof JinglePacket) { - if (this.jingleListener != null) { - this.jingleListener.onJinglePacketReceived(account, - (JinglePacket) packet); - } - } else { - if (packetCallbacks.containsKey(packet.getId())) { - if (packetCallbacks.get(packet.getId()) instanceof OnIqPacketReceived) { - ((OnIqPacketReceived) packetCallbacks.get(packet.getId())) - .onIqPacketReceived(account, packet); - } - - packetCallbacks.remove(packet.getId()); - } else if ((packet.getType() == IqPacket.TYPE_GET || packet - .getType() == IqPacket.TYPE_SET) - && this.unregisteredIqListener != null) { - this.unregisteredIqListener.onIqPacketReceived(account, packet); - } - } - } - - private void processMessage(Tag currentTag) throws XmlPullParserException, - IOException { - MessagePacket packet = (MessagePacket) processPacket(currentTag, - PACKET_MESSAGE); - String id = packet.getAttribute("id"); - if ((id != null) && (packetCallbacks.containsKey(id))) { - if (packetCallbacks.get(id) instanceof OnMessagePacketReceived) { - ((OnMessagePacketReceived) packetCallbacks.get(id)) - .onMessagePacketReceived(account, packet); - } - packetCallbacks.remove(id); - } else if (this.messageListener != null) { - this.messageListener.onMessagePacketReceived(account, packet); - } - } - - private void processPresence(Tag currentTag) throws XmlPullParserException, - IOException { - PresencePacket packet = (PresencePacket) processPacket(currentTag, - PACKET_PRESENCE); - String id = packet.getAttribute("id"); - if ((id != null) && (packetCallbacks.containsKey(id))) { - if (packetCallbacks.get(id) instanceof OnPresencePacketReceived) { - ((OnPresencePacketReceived) packetCallbacks.get(id)) - .onPresencePacketReceived(account, packet); - } - packetCallbacks.remove(id); - } else if (this.presenceListener != null) { - this.presenceListener.onPresencePacketReceived(account, packet); - } - } - - private void sendCompressionZlib() throws IOException { - Element compress = new Element("compress"); - compress.setAttribute("xmlns", "http://jabber.org/protocol/compress"); - compress.addChild("method").setContent("zlib"); - tagWriter.writeElement(compress); - } - - private void switchOverToZLib(Tag currentTag) - throws XmlPullParserException, IOException, - NoSuchAlgorithmException { - tagReader.readTag(); // read tag close - tagWriter.setOutputStream(new ZLibOutputStream(tagWriter - .getOutputStream())); - tagReader - .setInputStream(new ZLibInputStream(tagReader.getInputStream())); - - sendStartStream(); - Log.d(Config.LOGTAG, account.getJid() + ": compression enabled"); - usingCompression = true; - processStream(tagReader.readTag()); - } - - private void sendStartTLS() throws IOException { - Tag startTLS = Tag.empty("starttls"); - startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls"); - tagWriter.writeTag(startTLS); - } - - private SharedPreferences getPreferences() { - return PreferenceManager - .getDefaultSharedPreferences(applicationContext); - } - - private boolean enableLegacySSL() { - return getPreferences().getBoolean("enable_legacy_ssl", false); - } - - private void switchOverToTls(Tag currentTag) throws XmlPullParserException, - IOException { - tagReader.readTag(); - try { - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, - new X509TrustManager[] { this.mMemorizingTrustManager }, - mRandom); - SSLSocketFactory factory = sc.getSocketFactory(); - - HostnameVerifier verifier = this.mMemorizingTrustManager - .wrapHostnameVerifier(new StrictHostnameVerifier()); - SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket, - socket.getInetAddress().getHostAddress(), socket.getPort(), - true); - - // Support all protocols except legacy SSL. - // The min SDK version prevents us having to worry about SSLv2. In - // future, this may be - // true of SSLv3 as well. - final String[] supportProtocols; - if (enableLegacySSL()) { - supportProtocols = sslSocket.getSupportedProtocols(); - } else { - final List supportedProtocols = new LinkedList( - Arrays.asList(sslSocket.getSupportedProtocols())); - supportedProtocols.remove("SSLv3"); - supportProtocols = new String[supportedProtocols.size()]; - supportedProtocols.toArray(supportProtocols); - } - sslSocket.setEnabledProtocols(supportProtocols); - - if (verifier != null - && !verifier.verify(account.getServer(), - sslSocket.getSession())) { - Log.d(Config.LOGTAG, account.getJid() - + ": host mismatch in TLS connection"); - sslSocket.close(); - throw new IOException(); - } - tagReader.setInputStream(sslSocket.getInputStream()); - tagWriter.setOutputStream(sslSocket.getOutputStream()); - sendStartStream(); - Log.d(Config.LOGTAG, account.getJid() - + ": TLS connection established"); - usingEncryption = true; - processStream(tagReader.readTag()); - sslSocket.close(); - } catch (NoSuchAlgorithmException e1) { - e1.printStackTrace(); - } catch (KeyManagementException e) { - e.printStackTrace(); - } - } - - private void sendSaslAuthPlain() throws IOException { - String saslString = CryptoHelper.saslPlain(account.getUsername(), - account.getPassword()); - Element auth = new Element("auth"); - auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); - auth.setAttribute("mechanism", "PLAIN"); - auth.setContent(saslString); - tagWriter.writeElement(auth); - } - - private void sendSaslAuthDigestMd5() throws IOException { - Element auth = new Element("auth"); - auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); - auth.setAttribute("mechanism", "DIGEST-MD5"); - tagWriter.writeElement(auth); - } - - private void processStreamFeatures(Tag currentTag) - throws XmlPullParserException, IOException { - this.streamFeatures = tagReader.readElement(currentTag); - if (this.streamFeatures.hasChild("starttls") && !usingEncryption) { - sendStartTLS(); - } else if (compressionAvailable()) { - sendCompressionZlib(); - } else if (this.streamFeatures.hasChild("register") - && account.isOptionSet(Account.OPTION_REGISTER) - && usingEncryption) { - sendRegistryRequest(); - } else if (!this.streamFeatures.hasChild("register") - && account.isOptionSet(Account.OPTION_REGISTER)) { - changeStatus(Account.STATUS_REGISTRATION_NOT_SUPPORTED); - disconnect(true); - } else if (this.streamFeatures.hasChild("mechanisms") - && shouldAuthenticate && usingEncryption) { - List mechanisms = extractMechanisms(streamFeatures - .findChild("mechanisms")); - if (mechanisms.contains("PLAIN")) { - sendSaslAuthPlain(); - } else if (mechanisms.contains("DIGEST-MD5")) { - sendSaslAuthDigestMd5(); - } - } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" - + smVersion) - && streamId != null) { - ResumePacket resume = new ResumePacket(this.streamId, - stanzasReceived, smVersion); - this.tagWriter.writeStanzaAsync(resume); - } else if (this.streamFeatures.hasChild("bind") && shouldBind) { - sendBindRequest(); - } else { - Log.d(Config.LOGTAG, account.getJid() - + ": incompatible server. disconnecting"); - disconnect(true); - } - } - - private boolean compressionAvailable() { - if (!this.streamFeatures.hasChild("compression", - "http://jabber.org/features/compress")) - return false; - if (!ZLibOutputStream.SUPPORTED) - return false; - if (!account.isOptionSet(Account.OPTION_USECOMPRESSION)) - return false; - - Element compression = this.streamFeatures.findChild("compression", - "http://jabber.org/features/compress"); - for (Element child : compression.getChildren()) { - if (!"method".equals(child.getName())) - continue; - - if ("zlib".equalsIgnoreCase(child.getContent())) { - return true; - } - } - return false; - } - - private List extractMechanisms(Element stream) { - ArrayList mechanisms = new ArrayList(stream - .getChildren().size()); - for (Element child : stream.getChildren()) { - mechanisms.add(child.getContent()); - } - return mechanisms; - } - - private void sendRegistryRequest() { - IqPacket register = new IqPacket(IqPacket.TYPE_GET); - register.query("jabber:iq:register"); - register.setTo(account.getServer()); - sendIqPacket(register, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - Element instructions = packet.query().findChild("instructions"); - if (packet.query().hasChild("username") - && (packet.query().hasChild("password"))) { - IqPacket register = new IqPacket(IqPacket.TYPE_SET); - Element username = new Element("username") - .setContent(account.getUsername()); - Element password = new Element("password") - .setContent(account.getPassword()); - register.query("jabber:iq:register").addChild(username); - register.query().addChild(password); - sendIqPacket(register, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { - account.setOption(Account.OPTION_REGISTER, - false); - changeStatus(Account.STATUS_REGISTRATION_SUCCESSFULL); - } else if (packet.hasChild("error") - && (packet.findChild("error") - .hasChild("conflict"))) { - changeStatus(Account.STATUS_REGISTRATION_CONFLICT); - } else { - changeStatus(Account.STATUS_REGISTRATION_FAILED); - Log.d(Config.LOGTAG, packet.toString()); - } - disconnect(true); - } - }); - } else { - changeStatus(Account.STATUS_REGISTRATION_FAILED); - disconnect(true); - Log.d(Config.LOGTAG, account.getJid() - + ": could not register. instructions are" - + instructions.getContent()); - } - } - }); - } - - private void sendBindRequest() throws IOException { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind") - .addChild("resource").setContent(account.getResource()); - this.sendUnboundIqPacket(iq, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - Element bind = packet.findChild("bind"); - if (bind != null) { - Element jid = bind.findChild("jid"); - if (jid != null && jid.getContent() != null) { - account.setResource(jid.getContent().split("/", 2)[1]); - if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) { - smVersion = 3; - EnablePacket enable = new EnablePacket(smVersion); - tagWriter.writeStanzaAsync(enable); - stanzasSent = 0; - messageReceipts.clear(); - } else if (streamFeatures.hasChild("sm", - "urn:xmpp:sm:2")) { - smVersion = 2; - EnablePacket enable = new EnablePacket(smVersion); - tagWriter.writeStanzaAsync(enable); - stanzasSent = 0; - messageReceipts.clear(); - } - sendServiceDiscoveryInfo(account.getServer()); - sendServiceDiscoveryItems(account.getServer()); - if (bindListener != null) { - bindListener.onBind(account); - } - sendInitialPing(); - } else { - disconnect(true); - } - } else { - disconnect(true); - } - } - }); - if (this.streamFeatures.hasChild("session")) { - Log.d(Config.LOGTAG, account.getJid() - + ": sending deprecated session"); - IqPacket startSession = new IqPacket(IqPacket.TYPE_SET); - startSession.addChild("session", - "urn:ietf:params:xml:ns:xmpp-session"); - this.sendUnboundIqPacket(startSession, null); - } - } - - private void sendServiceDiscoveryInfo(final String server) { - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); - iq.setTo(server); - iq.query("http://jabber.org/protocol/disco#info"); - this.sendIqPacket(iq, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - List elements = packet.query().getChildren(); - List features = new ArrayList(); - for (int i = 0; i < elements.size(); ++i) { - if (elements.get(i).getName().equals("feature")) { - features.add(elements.get(i).getAttribute("var")); - } - } - disco.put(server, features); - - if (account.getServer().equals(server)) { - enableAdvancedStreamFeatures(); - } - } - }); - } - - private void enableAdvancedStreamFeatures() { - if (getFeatures().carbons()) { - sendEnableCarbons(); - } - } - - private void sendServiceDiscoveryItems(final String server) { - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); - iq.setTo(server); - iq.query("http://jabber.org/protocol/disco#items"); - this.sendIqPacket(iq, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - List elements = packet.query().getChildren(); - for (int i = 0; i < elements.size(); ++i) { - if (elements.get(i).getName().equals("item")) { - String jid = elements.get(i).getAttribute("jid"); - sendServiceDiscoveryInfo(jid); - } - } - } - }); - } - - private void sendEnableCarbons() { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - iq.addChild("enable", "urn:xmpp:carbons:2"); - this.sendIqPacket(iq, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (!packet.hasChild("error")) { - Log.d(Config.LOGTAG, account.getJid() - + ": successfully enabled carbons"); - } else { - Log.d(Config.LOGTAG, account.getJid() - + ": error enableing carbons " + packet.toString()); - } - } - }); - } - - private void processStreamError(Tag currentTag) - throws XmlPullParserException, IOException { - Element streamError = tagReader.readElement(currentTag); - if (streamError != null && streamError.hasChild("conflict")) { - String resource = account.getResource().split("\\.")[0]; - account.setResource(resource + "." + nextRandomId()); - Log.d(Config.LOGTAG, - account.getJid() + ": switching resource due to conflict (" - + account.getResource() + ")"); - } - } - - private void sendStartStream() throws IOException { - Tag stream = Tag.start("stream:stream"); - stream.setAttribute("from", account.getJid()); - stream.setAttribute("to", account.getServer()); - stream.setAttribute("version", "1.0"); - stream.setAttribute("xml:lang", "en"); - stream.setAttribute("xmlns", "jabber:client"); - stream.setAttribute("xmlns:stream", "http://etherx.jabber.org/streams"); - tagWriter.writeTag(stream); - } - - private String nextRandomId() { - return new BigInteger(50, mRandom).toString(32); - } - - public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) { - if (packet.getId() == null) { - String id = nextRandomId(); - packet.setAttribute("id", id); - } - packet.setFrom(account.getFullJid()); - this.sendPacket(packet, callback); - } - - public void sendUnboundIqPacket(IqPacket packet, OnIqPacketReceived callback) { - if (packet.getId() == null) { - String id = nextRandomId(); - packet.setAttribute("id", id); - } - this.sendPacket(packet, callback); - } - - public void sendMessagePacket(MessagePacket packet) { - this.sendPacket(packet, null); - } - - public void sendPresencePacket(PresencePacket packet) { - this.sendPacket(packet, null); - } - - private synchronized void sendPacket(final AbstractStanza packet, - PacketReceived callback) { - if (packet.getName().equals("iq") || packet.getName().equals("message") - || packet.getName().equals("presence")) { - ++stanzasSent; - } - tagWriter.writeStanzaAsync(packet); - if (packet instanceof MessagePacket && packet.getId() != null - && this.streamId != null) { - Log.d(Config.LOGTAG, "request delivery report for stanza " - + stanzasSent); - this.messageReceipts.put(stanzasSent, packet.getId()); - tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion)); - } - if (callback != null) { - if (packet.getId() == null) { - packet.setId(nextRandomId()); - } - packetCallbacks.put(packet.getId(), callback); - } - } - - public void sendPing() { - if (streamFeatures.hasChild("sm")) { - tagWriter.writeStanzaAsync(new RequestPacket(smVersion)); - } else { - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); - iq.setFrom(account.getFullJid()); - iq.addChild("ping", "urn:xmpp:ping"); - this.sendIqPacket(iq, null); - } - this.lastPingSent = SystemClock.elapsedRealtime(); - } - - public void setOnMessagePacketReceivedListener( - OnMessagePacketReceived listener) { - this.messageListener = listener; - } - - public void setOnUnregisteredIqPacketReceivedListener( - OnIqPacketReceived listener) { - this.unregisteredIqListener = listener; - } - - public void setOnPresencePacketReceivedListener( - OnPresencePacketReceived listener) { - this.presenceListener = listener; - } - - public void setOnJinglePacketReceivedListener( - OnJinglePacketReceived listener) { - this.jingleListener = listener; - } - - public void setOnStatusChangedListener(OnStatusChanged listener) { - this.statusListener = listener; - } - - public void setOnBindListener(OnBindListener listener) { - this.bindListener = listener; - } - - public void setOnMessageAcknowledgeListener(OnMessageAcknowledged listener) { - this.acknowledgedListener = listener; - } - - public void disconnect(boolean force) { - Log.d(Config.LOGTAG, account.getJid() + ": disconnecting"); - try { - if (force) { - socket.close(); - return; - } - new Thread(new Runnable() { - - @Override - public void run() { - if (tagWriter.isActive()) { - tagWriter.finish(); - try { - while (!tagWriter.finished()) { - Log.d(Config.LOGTAG, "not yet finished"); - Thread.sleep(100); - } - tagWriter.writeTag(Tag.end("stream:stream")); - socket.close(); - } catch (IOException e) { - Log.d(Config.LOGTAG, - "io exception during disconnect"); - } catch (InterruptedException e) { - Log.d(Config.LOGTAG, "interrupted"); - } - } - } - }).start(); - } catch (IOException e) { - Log.d(Config.LOGTAG, "io exception during disconnect"); - } - } - - public List findDiscoItemsByFeature(String feature) { - List items = new ArrayList(); - for (Entry> cursor : disco.entrySet()) { - if (cursor.getValue().contains(feature)) { - items.add(cursor.getKey()); - } - } - return items; - } - - public String findDiscoItemByFeature(String feature) { - List items = findDiscoItemsByFeature(feature); - if (items.size() >= 1) { - return items.get(0); - } - return null; - } - - public void r() { - this.tagWriter.writeStanzaAsync(new RequestPacket(smVersion)); - } - - public String getMucServer() { - return findDiscoItemByFeature("http://jabber.org/protocol/muc"); - } - - public int getTimeToNextAttempt() { - int interval = (int) (25 * Math.pow(1.5, attempt)); - int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000); - return interval - secondsSinceLast; - } - - public int getAttempt() { - return this.attempt; - } - - public Features getFeatures() { - return this.features; - } - - public class Features { - XmppConnection connection; - - public Features(XmppConnection connection) { - this.connection = connection; - } - - private boolean hasDiscoFeature(String server, String feature) { - if (!connection.disco.containsKey(server)) { - return false; - } - return connection.disco.get(server).contains(feature); - } - - public boolean carbons() { - return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2"); - } - - public boolean sm() { - return streamId != null; - } - - public boolean csi() { - if (connection.streamFeatures == null) { - return false; - } else { - return connection.streamFeatures.hasChild("csi", - "urn:xmpp:csi:0"); - } - } - - public boolean pubsub() { - return hasDiscoFeature(account.getServer(), - "http://jabber.org/protocol/pubsub#publish"); - } - - public boolean rosterVersioning() { - if (connection.streamFeatures == null) { - return false; - } else { - return connection.streamFeatures.hasChild("ver"); - } - } - - public boolean streamhost() { - return connection - .findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null; - } - - public boolean compression() { - return connection.usingCompression; - } - } - - public long getLastSessionEstablished() { - long diff; - if (this.lastSessionStarted == 0) { - diff = SystemClock.elapsedRealtime() - this.lastConnect; - } else { - diff = SystemClock.elapsedRealtime() - this.lastSessionStarted; - } - return System.currentTimeMillis() - diff; - } - - public long getLastConnect() { - return this.lastConnect; - } - - public long getLastPingSent() { - return this.lastPingSent; - } - - public long getLastPacketReceived() { - return this.lastPaketReceived; - } - - public void sendActive() { - this.sendPacket(new ActivePacket(), null); - } - - public void sendInactive() { - this.sendPacket(new InactivePacket(), null); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java deleted file mode 100644 index 3e7c7b68..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java +++ /dev/null @@ -1,143 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import java.util.ArrayList; -import java.util.List; - -import eu.siacs.conversations.xml.Element; - -public class JingleCandidate { - - public static int TYPE_UNKNOWN; - public static int TYPE_DIRECT = 0; - public static int TYPE_PROXY = 1; - - private boolean ours; - private boolean usedByCounterpart = false; - private String cid; - private String host; - private int port; - private int type; - private String jid; - private int priority; - - public JingleCandidate(String cid, boolean ours) { - this.ours = ours; - this.cid = cid; - } - - public String getCid() { - return cid; - } - - public void setHost(String host) { - this.host = host; - } - - public String getHost() { - return this.host; - } - - public void setJid(String jid) { - this.jid = jid; - } - - public String getJid() { - return this.jid; - } - - public void setPort(int port) { - this.port = port; - } - - public int getPort() { - return this.port; - } - - public void setType(int type) { - this.type = type; - } - - public void setType(String type) { - if ("proxy".equals(type)) { - this.type = TYPE_PROXY; - } else if ("direct".equals(type)) { - this.type = TYPE_DIRECT; - } else { - this.type = TYPE_UNKNOWN; - } - } - - public void setPriority(int i) { - this.priority = i; - } - - public int getPriority() { - return this.priority; - } - - public boolean equals(JingleCandidate other) { - return this.getCid().equals(other.getCid()); - } - - public boolean equalValues(JingleCandidate other) { - return other.getHost().equals(this.getHost()) - && (other.getPort() == this.getPort()); - } - - public boolean isOurs() { - return ours; - } - - public int getType() { - return this.type; - } - - public static List parse(List canditates) { - List parsedCandidates = new ArrayList(); - for (Element c : canditates) { - parsedCandidates.add(JingleCandidate.parse(c)); - } - return parsedCandidates; - } - - public static JingleCandidate parse(Element candidate) { - JingleCandidate parsedCandidate = new JingleCandidate( - candidate.getAttribute("cid"), false); - parsedCandidate.setHost(candidate.getAttribute("host")); - parsedCandidate.setJid(candidate.getAttribute("jid")); - parsedCandidate.setType(candidate.getAttribute("type")); - parsedCandidate.setPriority(Integer.parseInt(candidate - .getAttribute("priority"))); - parsedCandidate - .setPort(Integer.parseInt(candidate.getAttribute("port"))); - return parsedCandidate; - } - - public Element toElement() { - Element element = new Element("candidate"); - element.setAttribute("cid", this.getCid()); - element.setAttribute("host", this.getHost()); - element.setAttribute("port", Integer.toString(this.getPort())); - element.setAttribute("jid", this.getJid()); - element.setAttribute("priority", Integer.toString(this.getPriority())); - if (this.getType() == TYPE_DIRECT) { - element.setAttribute("type", "direct"); - } else if (this.getType() == TYPE_PROXY) { - element.setAttribute("type", "proxy"); - } - return element; - } - - public void flagAsUsedByCounterpart() { - this.usedByCounterpart = true; - } - - public boolean isUsedByCounterpart() { - return this.usedByCounterpart; - } - - public String toString() { - return this.getHost() + ":" + this.getPort() + " (prio=" - + this.getPriority() + ")"; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java deleted file mode 100644 index a0b2feb2..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ /dev/null @@ -1,910 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import android.content.Intent; -import android.graphics.BitmapFactory; -import android.net.Uri; -import android.util.Log; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.jingle.stanzas.Content; -import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; -import eu.siacs.conversations.xmpp.jingle.stanzas.Reason; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public class JingleConnection implements Downloadable { - - private final String[] extensions = { "webp", "jpeg", "jpg", "png" }; - private final String[] cryptoExtensions = { "pgp", "gpg", "otr" }; - - private JingleConnectionManager mJingleConnectionManager; - private XmppConnectionService mXmppConnectionService; - - protected static final int JINGLE_STATUS_INITIATED = 0; - protected static final int JINGLE_STATUS_ACCEPTED = 1; - protected static final int JINGLE_STATUS_TERMINATED = 2; - protected static final int JINGLE_STATUS_CANCELED = 3; - protected static final int JINGLE_STATUS_FINISHED = 4; - protected static final int JINGLE_STATUS_TRANSMITTING = 5; - protected static final int JINGLE_STATUS_FAILED = 99; - - private int ibbBlockSize = 4096; - - private int mJingleStatus = -1; - private int mStatus = -1; - private Message message; - private String sessionId; - private Account account; - private String initiator; - private String responder; - private List candidates = new ArrayList(); - private ConcurrentHashMap connections = new ConcurrentHashMap(); - - private String transportId; - private Element fileOffer; - private DownloadableFile file = null; - - private String contentName; - private String contentCreator; - - private boolean receivedCandidate = false; - private boolean sentCandidate = false; - - private boolean acceptedAutomatically = false; - - private JingleTransport transport = null; - - private OnIqPacketReceived responseListener = new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { - if (initiator.equals(account.getFullJid())) { - mXmppConnectionService.markMessage(message, - Message.STATUS_SEND_FAILED); - } - mJingleStatus = JINGLE_STATUS_FAILED; - } - } - }; - - final OnFileTransmissionStatusChanged onFileTransmissionSatusChanged = new OnFileTransmissionStatusChanged() { - - @Override - public void onFileTransmitted(DownloadableFile file) { - if (responder.equals(account.getFullJid())) { - sendSuccess(); - if (acceptedAutomatically) { - message.markUnread(); - JingleConnection.this.mXmppConnectionService - .getNotificationService().push(message); - } - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(file.getAbsolutePath(), options); - int imageHeight = options.outHeight; - int imageWidth = options.outWidth; - message.setBody(Long.toString(file.getSize()) + ',' - + imageWidth + ',' + imageHeight); - mXmppConnectionService.databaseBackend.createMessage(message); - mXmppConnectionService.markMessage(message, - Message.STATUS_RECEIVED); - } - Log.d(Config.LOGTAG, - "sucessfully transmitted file:" + file.getAbsolutePath()); - if (message.getEncryption() != Message.ENCRYPTION_PGP) { - Intent intent = new Intent( - Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(Uri.fromFile(file)); - mXmppConnectionService.sendBroadcast(intent); - } - } - - @Override - public void onFileTransferAborted() { - JingleConnection.this.sendCancel(); - JingleConnection.this.cancel(); - } - }; - - private OnProxyActivated onProxyActivated = new OnProxyActivated() { - - @Override - public void success() { - if (initiator.equals(account.getFullJid())) { - Log.d(Config.LOGTAG, "we were initiating. sending file"); - transport.send(file, onFileTransmissionSatusChanged); - } else { - transport.receive(file, onFileTransmissionSatusChanged); - Log.d(Config.LOGTAG, "we were responding. receiving file"); - } - } - - @Override - public void failed() { - Log.d(Config.LOGTAG, "proxy activation failed"); - } - }; - - public JingleConnection(JingleConnectionManager mJingleConnectionManager) { - this.mJingleConnectionManager = mJingleConnectionManager; - this.mXmppConnectionService = mJingleConnectionManager - .getXmppConnectionService(); - } - - public String getSessionId() { - return this.sessionId; - } - - public Account getAccount() { - return this.account; - } - - public String getCounterPart() { - return this.message.getCounterpart(); - } - - public void deliverPacket(JinglePacket packet) { - boolean returnResult = true; - if (packet.isAction("session-terminate")) { - Reason reason = packet.getReason(); - if (reason != null) { - if (reason.hasChild("cancel")) { - this.cancel(); - } else if (reason.hasChild("success")) { - this.receiveSuccess(); - } else { - this.cancel(); - } - } else { - this.cancel(); - } - } else if (packet.isAction("session-accept")) { - returnResult = receiveAccept(packet); - } else if (packet.isAction("transport-info")) { - returnResult = receiveTransportInfo(packet); - } else if (packet.isAction("transport-replace")) { - if (packet.getJingleContent().hasIbbTransport()) { - returnResult = this.receiveFallbackToIbb(packet); - } else { - returnResult = false; - Log.d(Config.LOGTAG, "trying to fallback to something unknown" - + packet.toString()); - } - } else if (packet.isAction("transport-accept")) { - returnResult = this.receiveTransportAccept(packet); - } else { - Log.d(Config.LOGTAG, "packet arrived in connection. action was " - + packet.getAction()); - returnResult = false; - } - IqPacket response; - if (returnResult) { - response = packet.generateRespone(IqPacket.TYPE_RESULT); - - } else { - response = packet.generateRespone(IqPacket.TYPE_ERROR); - } - account.getXmppConnection().sendIqPacket(response, null); - } - - public void init(Message message) { - this.contentCreator = "initiator"; - this.contentName = this.mJingleConnectionManager.nextRandomId(); - this.message = message; - this.account = message.getConversation().getAccount(); - this.initiator = this.account.getFullJid(); - this.responder = this.message.getCounterpart(); - this.sessionId = this.mJingleConnectionManager.nextRandomId(); - if (this.candidates.size() > 0) { - this.sendInitRequest(); - } else { - this.mJingleConnectionManager.getPrimaryCandidate(account, - new OnPrimaryCandidateFound() { - - @Override - public void onPrimaryCandidateFound(boolean success, - final JingleCandidate candidate) { - if (success) { - final JingleSocks5Transport socksConnection = new JingleSocks5Transport( - JingleConnection.this, candidate); - connections.put(candidate.getCid(), - socksConnection); - socksConnection - .connect(new OnTransportConnected() { - - @Override - public void failed() { - Log.d(Config.LOGTAG, - "connection to our own primary candidete failed"); - sendInitRequest(); - } - - @Override - public void established() { - Log.d(Config.LOGTAG, - "succesfully connected to our own primary candidate"); - mergeCandidate(candidate); - sendInitRequest(); - } - }); - mergeCandidate(candidate); - } else { - Log.d(Config.LOGTAG, - "no primary candidate of our own was found"); - sendInitRequest(); - } - } - }); - } - - } - - public void init(Account account, JinglePacket packet) { - this.mJingleStatus = JINGLE_STATUS_INITIATED; - Conversation conversation = this.mXmppConnectionService - .findOrCreateConversation(account, - packet.getFrom().split("/", 2)[0], false); - this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); - this.message.setStatus(Message.STATUS_RECEIVED); - this.message.setType(Message.TYPE_IMAGE); - this.mStatus = Downloadable.STATUS_OFFER; - this.message.setDownloadable(this); - String[] fromParts = packet.getFrom().split("/", 2); - this.message.setPresence(fromParts[1]); - this.account = account; - this.initiator = packet.getFrom(); - this.responder = this.account.getFullJid(); - this.sessionId = packet.getSessionId(); - Content content = packet.getJingleContent(); - this.contentCreator = content.getAttribute("creator"); - this.contentName = content.getAttribute("name"); - this.transportId = content.getTransportId(); - this.mergeCandidates(JingleCandidate.parse(content.socks5transport() - .getChildren())); - this.fileOffer = packet.getJingleContent().getFileOffer(); - if (fileOffer != null) { - Element fileSize = fileOffer.findChild("size"); - Element fileNameElement = fileOffer.findChild("name"); - if (fileNameElement != null) { - boolean supportedFile = false; - String[] filename = fileNameElement.getContent() - .toLowerCase(Locale.US).split("\\."); - if (Arrays.asList(this.extensions).contains( - filename[filename.length - 1])) { - supportedFile = true; - } else if (Arrays.asList(this.cryptoExtensions).contains( - filename[filename.length - 1])) { - if (filename.length == 3) { - if (Arrays.asList(this.extensions).contains( - filename[filename.length - 2])) { - supportedFile = true; - if (filename[filename.length - 1].equals("otr")) { - Log.d(Config.LOGTAG, "receiving otr file"); - this.message - .setEncryption(Message.ENCRYPTION_OTR); - } else { - this.message - .setEncryption(Message.ENCRYPTION_PGP); - } - } - } - } - if (supportedFile) { - long size = Long.parseLong(fileSize.getContent()); - message.setBody(Long.toString(size)); - conversation.add(message); - mXmppConnectionService.updateConversationUi(); - if (size <= this.mJingleConnectionManager - .getAutoAcceptFileSize()) { - Log.d(Config.LOGTAG, "auto accepting file from " - + packet.getFrom()); - this.acceptedAutomatically = true; - this.sendAccept(); - } else { - message.markUnread(); - Log.d(Config.LOGTAG, - "not auto accepting new file offer with size: " - + size - + " allowed size:" - + this.mJingleConnectionManager - .getAutoAcceptFileSize()); - this.mXmppConnectionService.getNotificationService() - .push(message); - } - this.file = this.mXmppConnectionService.getFileBackend() - .getFile(message, false); - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - byte[] key = conversation.getSymmetricKey(); - if (key == null) { - this.sendCancel(); - this.cancel(); - return; - } else { - this.file.setKey(key); - } - } - this.file.setExpectedSize(size); - } else { - this.sendCancel(); - this.cancel(); - } - } else { - this.sendCancel(); - this.cancel(); - } - } else { - this.sendCancel(); - this.cancel(); - } - } - - private void sendInitRequest() { - JinglePacket packet = this.bootstrapPacket("session-initiate"); - Content content = new Content(this.contentCreator, this.contentName); - if (message.getType() == Message.TYPE_IMAGE) { - content.setTransportId(this.transportId); - this.file = this.mXmppConnectionService.getFileBackend().getFile( - message, false); - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - Conversation conversation = this.message.getConversation(); - this.mXmppConnectionService.renewSymmetricKey(conversation); - content.setFileOffer(this.file, true); - this.file.setKey(conversation.getSymmetricKey()); - } else { - content.setFileOffer(this.file, false); - } - this.transportId = this.mJingleConnectionManager.nextRandomId(); - content.setTransportId(this.transportId); - content.socks5transport().setChildren(getCandidatesAsElements()); - packet.setContent(content); - this.sendJinglePacket(packet); - this.mJingleStatus = JINGLE_STATUS_INITIATED; - } - } - - private List getCandidatesAsElements() { - List elements = new ArrayList(); - for (JingleCandidate c : this.candidates) { - elements.add(c.toElement()); - } - return elements; - } - - private void sendAccept() { - mJingleStatus = JINGLE_STATUS_ACCEPTED; - this.mStatus = Downloadable.STATUS_DOWNLOADING; - mXmppConnectionService.updateConversationUi(); - this.mJingleConnectionManager.getPrimaryCandidate(this.account, - new OnPrimaryCandidateFound() { - - @Override - public void onPrimaryCandidateFound(boolean success, - final JingleCandidate candidate) { - final JinglePacket packet = bootstrapPacket("session-accept"); - final Content content = new Content(contentCreator, - contentName); - content.setFileOffer(fileOffer); - content.setTransportId(transportId); - if ((success) && (!equalCandidateExists(candidate))) { - final JingleSocks5Transport socksConnection = new JingleSocks5Transport( - JingleConnection.this, candidate); - connections.put(candidate.getCid(), socksConnection); - socksConnection.connect(new OnTransportConnected() { - - @Override - public void failed() { - Log.d(Config.LOGTAG, - "connection to our own primary candidate failed"); - content.socks5transport().setChildren( - getCandidatesAsElements()); - packet.setContent(content); - sendJinglePacket(packet); - connectNextCandidate(); - } - - @Override - public void established() { - Log.d(Config.LOGTAG, - "connected to primary candidate"); - mergeCandidate(candidate); - content.socks5transport().setChildren( - getCandidatesAsElements()); - packet.setContent(content); - sendJinglePacket(packet); - connectNextCandidate(); - } - }); - } else { - Log.d(Config.LOGTAG, - "did not find a primary candidate for ourself"); - content.socks5transport().setChildren( - getCandidatesAsElements()); - packet.setContent(content); - sendJinglePacket(packet); - connectNextCandidate(); - } - } - }); - - } - - private JinglePacket bootstrapPacket(String action) { - JinglePacket packet = new JinglePacket(); - packet.setAction(action); - packet.setFrom(account.getFullJid()); - packet.setTo(this.message.getCounterpart()); - packet.setSessionId(this.sessionId); - packet.setInitiator(this.initiator); - return packet; - } - - private void sendJinglePacket(JinglePacket packet) { - // Log.d(Config.LOGTAG,packet.toString()); - account.getXmppConnection().sendIqPacket(packet, responseListener); - } - - private boolean receiveAccept(JinglePacket packet) { - Content content = packet.getJingleContent(); - mergeCandidates(JingleCandidate.parse(content.socks5transport() - .getChildren())); - this.mJingleStatus = JINGLE_STATUS_ACCEPTED; - mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND); - this.connectNextCandidate(); - return true; - } - - private boolean receiveTransportInfo(JinglePacket packet) { - Content content = packet.getJingleContent(); - if (content.hasSocks5Transport()) { - if (content.socks5transport().hasChild("activated")) { - if ((this.transport != null) - && (this.transport instanceof JingleSocks5Transport)) { - onProxyActivated.success(); - } else { - String cid = content.socks5transport() - .findChild("activated").getAttribute("cid"); - Log.d(Config.LOGTAG, "received proxy activated (" + cid - + ")prior to choosing our own transport"); - JingleSocks5Transport connection = this.connections - .get(cid); - if (connection != null) { - connection.setActivated(true); - } else { - Log.d(Config.LOGTAG, "activated connection not found"); - this.sendCancel(); - this.cancel(); - } - } - return true; - } else if (content.socks5transport().hasChild("proxy-error")) { - onProxyActivated.failed(); - return true; - } else if (content.socks5transport().hasChild("candidate-error")) { - Log.d(Config.LOGTAG, "received candidate error"); - this.receivedCandidate = true; - if ((mJingleStatus == JINGLE_STATUS_ACCEPTED) - && (this.sentCandidate)) { - this.connect(); - } - return true; - } else if (content.socks5transport().hasChild("candidate-used")) { - String cid = content.socks5transport() - .findChild("candidate-used").getAttribute("cid"); - if (cid != null) { - Log.d(Config.LOGTAG, "candidate used by counterpart:" + cid); - JingleCandidate candidate = getCandidate(cid); - candidate.flagAsUsedByCounterpart(); - this.receivedCandidate = true; - if ((mJingleStatus == JINGLE_STATUS_ACCEPTED) - && (this.sentCandidate)) { - this.connect(); - } else { - Log.d(Config.LOGTAG, - "ignoring because file is already in transmission or we havent sent our candidate yet"); - } - return true; - } else { - return false; - } - } else { - return false; - } - } else { - return true; - } - } - - private void connect() { - final JingleSocks5Transport connection = chooseConnection(); - this.transport = connection; - if (connection == null) { - Log.d(Config.LOGTAG, "could not find suitable candidate"); - this.disconnect(); - if (this.initiator.equals(account.getFullJid())) { - this.sendFallbackToIbb(); - } - } else { - this.mJingleStatus = JINGLE_STATUS_TRANSMITTING; - if (connection.needsActivation()) { - if (connection.getCandidate().isOurs()) { - Log.d(Config.LOGTAG, "candidate " - + connection.getCandidate().getCid() - + " was our proxy. going to activate"); - IqPacket activation = new IqPacket(IqPacket.TYPE_SET); - activation.setTo(connection.getCandidate().getJid()); - activation.query("http://jabber.org/protocol/bytestreams") - .setAttribute("sid", this.getSessionId()); - activation.query().addChild("activate") - .setContent(this.getCounterPart()); - this.account.getXmppConnection().sendIqPacket(activation, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { - onProxyActivated.failed(); - } else { - onProxyActivated.success(); - sendProxyActivated(connection - .getCandidate().getCid()); - } - } - }); - } else { - Log.d(Config.LOGTAG, - "candidate " - + connection.getCandidate().getCid() - + " was a proxy. waiting for other party to activate"); - } - } else { - if (initiator.equals(account.getFullJid())) { - Log.d(Config.LOGTAG, "we were initiating. sending file"); - connection.send(file, onFileTransmissionSatusChanged); - } else { - Log.d(Config.LOGTAG, "we were responding. receiving file"); - connection.receive(file, onFileTransmissionSatusChanged); - } - } - } - } - - private JingleSocks5Transport chooseConnection() { - JingleSocks5Transport connection = null; - for (Entry cursor : connections - .entrySet()) { - JingleSocks5Transport currentConnection = cursor.getValue(); - // Log.d(Config.LOGTAG,"comparing candidate: "+currentConnection.getCandidate().toString()); - if (currentConnection.isEstablished() - && (currentConnection.getCandidate().isUsedByCounterpart() || (!currentConnection - .getCandidate().isOurs()))) { - // Log.d(Config.LOGTAG,"is usable"); - if (connection == null) { - connection = currentConnection; - } else { - if (connection.getCandidate().getPriority() < currentConnection - .getCandidate().getPriority()) { - connection = currentConnection; - } else if (connection.getCandidate().getPriority() == currentConnection - .getCandidate().getPriority()) { - // Log.d(Config.LOGTAG,"found two candidates with same priority"); - if (initiator.equals(account.getFullJid())) { - if (currentConnection.getCandidate().isOurs()) { - connection = currentConnection; - } - } else { - if (!currentConnection.getCandidate().isOurs()) { - connection = currentConnection; - } - } - } - } - } - } - return connection; - } - - private void sendSuccess() { - JinglePacket packet = bootstrapPacket("session-terminate"); - Reason reason = new Reason(); - reason.addChild("success"); - packet.setReason(reason); - this.sendJinglePacket(packet); - this.disconnect(); - this.mJingleStatus = JINGLE_STATUS_FINISHED; - this.message.setStatus(Message.STATUS_RECEIVED); - this.message.setDownloadable(null); - this.mXmppConnectionService.updateMessage(message); - this.mJingleConnectionManager.finishConnection(this); - } - - private void sendFallbackToIbb() { - Log.d(Config.LOGTAG, "sending fallback to ibb"); - JinglePacket packet = this.bootstrapPacket("transport-replace"); - Content content = new Content(this.contentCreator, this.contentName); - this.transportId = this.mJingleConnectionManager.nextRandomId(); - content.setTransportId(this.transportId); - content.ibbTransport().setAttribute("block-size", - Integer.toString(this.ibbBlockSize)); - packet.setContent(content); - this.sendJinglePacket(packet); - } - - private boolean receiveFallbackToIbb(JinglePacket packet) { - Log.d(Config.LOGTAG, "receiving fallack to ibb"); - String receivedBlockSize = packet.getJingleContent().ibbTransport() - .getAttribute("block-size"); - if (receivedBlockSize != null) { - int bs = Integer.parseInt(receivedBlockSize); - if (bs > this.ibbBlockSize) { - this.ibbBlockSize = bs; - } - } - this.transportId = packet.getJingleContent().getTransportId(); - this.transport = new JingleInbandTransport(this.account, - this.responder, this.transportId, this.ibbBlockSize); - this.transport.receive(file, onFileTransmissionSatusChanged); - JinglePacket answer = bootstrapPacket("transport-accept"); - Content content = new Content("initiator", "a-file-offer"); - content.setTransportId(this.transportId); - content.ibbTransport().setAttribute("block-size", - Integer.toString(this.ibbBlockSize)); - answer.setContent(content); - this.sendJinglePacket(answer); - return true; - } - - private boolean receiveTransportAccept(JinglePacket packet) { - if (packet.getJingleContent().hasIbbTransport()) { - String receivedBlockSize = packet.getJingleContent().ibbTransport() - .getAttribute("block-size"); - if (receivedBlockSize != null) { - int bs = Integer.parseInt(receivedBlockSize); - if (bs > this.ibbBlockSize) { - this.ibbBlockSize = bs; - } - } - this.transport = new JingleInbandTransport(this.account, - this.responder, this.transportId, this.ibbBlockSize); - this.transport.connect(new OnTransportConnected() { - - @Override - public void failed() { - Log.d(Config.LOGTAG, "ibb open failed"); - } - - @Override - public void established() { - JingleConnection.this.transport.send(file, - onFileTransmissionSatusChanged); - } - }); - return true; - } else { - return false; - } - } - - private void receiveSuccess() { - this.mJingleStatus = JINGLE_STATUS_FINISHED; - this.mXmppConnectionService.markMessage(this.message, - Message.STATUS_SEND); - this.disconnect(); - this.mJingleConnectionManager.finishConnection(this); - } - - public void cancel() { - this.mJingleStatus = JINGLE_STATUS_CANCELED; - this.disconnect(); - if (this.message != null) { - if (this.responder.equals(account.getFullJid())) { - this.mStatus = Downloadable.STATUS_FAILED; - this.mXmppConnectionService.updateConversationUi(); - } else { - if (this.mJingleStatus == JINGLE_STATUS_INITIATED) { - this.mXmppConnectionService.markMessage(this.message, - Message.STATUS_SEND_REJECTED); - } else { - this.mXmppConnectionService.markMessage(this.message, - Message.STATUS_SEND_FAILED); - } - } - } - this.mJingleConnectionManager.finishConnection(this); - } - - private void sendCancel() { - JinglePacket packet = bootstrapPacket("session-terminate"); - Reason reason = new Reason(); - reason.addChild("cancel"); - packet.setReason(reason); - this.sendJinglePacket(packet); - } - - private void connectNextCandidate() { - for (JingleCandidate candidate : this.candidates) { - if ((!connections.containsKey(candidate.getCid()) && (!candidate - .isOurs()))) { - this.connectWithCandidate(candidate); - return; - } - } - this.sendCandidateError(); - } - - private void connectWithCandidate(final JingleCandidate candidate) { - final JingleSocks5Transport socksConnection = new JingleSocks5Transport( - this, candidate); - connections.put(candidate.getCid(), socksConnection); - socksConnection.connect(new OnTransportConnected() { - - @Override - public void failed() { - Log.d(Config.LOGTAG, - "connection failed with " + candidate.getHost() + ":" - + candidate.getPort()); - connectNextCandidate(); - } - - @Override - public void established() { - Log.d(Config.LOGTAG, - "established connection with " + candidate.getHost() - + ":" + candidate.getPort()); - sendCandidateUsed(candidate.getCid()); - } - }); - } - - private void disconnect() { - Iterator> it = this.connections - .entrySet().iterator(); - while (it.hasNext()) { - Entry pairs = it.next(); - pairs.getValue().disconnect(); - it.remove(); - } - } - - private void sendProxyActivated(String cid) { - JinglePacket packet = bootstrapPacket("transport-info"); - Content content = new Content(this.contentCreator, this.contentName); - content.setTransportId(this.transportId); - content.socks5transport().addChild("activated") - .setAttribute("cid", cid); - packet.setContent(content); - this.sendJinglePacket(packet); - } - - private void sendCandidateUsed(final String cid) { - JinglePacket packet = bootstrapPacket("transport-info"); - Content content = new Content(this.contentCreator, this.contentName); - content.setTransportId(this.transportId); - content.socks5transport().addChild("candidate-used") - .setAttribute("cid", cid); - packet.setContent(content); - this.sentCandidate = true; - if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) { - connect(); - } - this.sendJinglePacket(packet); - } - - private void sendCandidateError() { - JinglePacket packet = bootstrapPacket("transport-info"); - Content content = new Content(this.contentCreator, this.contentName); - content.setTransportId(this.transportId); - content.socks5transport().addChild("candidate-error"); - packet.setContent(content); - this.sentCandidate = true; - if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) { - connect(); - } - this.sendJinglePacket(packet); - } - - public String getInitiator() { - return this.initiator; - } - - public String getResponder() { - return this.responder; - } - - public int getJingleStatus() { - return this.mJingleStatus; - } - - private boolean equalCandidateExists(JingleCandidate candidate) { - for (JingleCandidate c : this.candidates) { - if (c.equalValues(candidate)) { - return true; - } - } - return false; - } - - private void mergeCandidate(JingleCandidate candidate) { - for (JingleCandidate c : this.candidates) { - if (c.equals(candidate)) { - return; - } - } - this.candidates.add(candidate); - } - - private void mergeCandidates(List candidates) { - for (JingleCandidate c : candidates) { - mergeCandidate(c); - } - } - - private JingleCandidate getCandidate(String cid) { - for (JingleCandidate c : this.candidates) { - if (c.getCid().equals(cid)) { - return c; - } - } - return null; - } - - interface OnProxyActivated { - public void success(); - - public void failed(); - } - - public boolean hasTransportId(String sid) { - return sid.equals(this.transportId); - } - - public JingleTransport getTransport() { - return this.transport; - } - - public boolean start() { - if (account.getStatus() == Account.STATUS_ONLINE) { - if (mJingleStatus == JINGLE_STATUS_INITIATED) { - new Thread(new Runnable() { - - @Override - public void run() { - sendAccept(); - } - }).start(); - } - return true; - } else { - return false; - } - } - - @Override - public int getStatus() { - return this.mStatus; - } - - @Override - public long getFileSize() { - if (this.file != null) { - return this.file.getExpectedSize(); - } else { - return 0; - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java deleted file mode 100644 index 1e7c84d4..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ /dev/null @@ -1,163 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import android.annotation.SuppressLint; -import android.util.Log; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.AbstractConnectionManager; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public class JingleConnectionManager extends AbstractConnectionManager { - private List connections = new CopyOnWriteArrayList(); - - private HashMap primaryCandidates = new HashMap(); - - @SuppressLint("TrulyRandom") - private SecureRandom random = new SecureRandom(); - - public JingleConnectionManager(XmppConnectionService service) { - super(service); - } - - public void deliverPacket(Account account, JinglePacket packet) { - if (packet.isAction("session-initiate")) { - JingleConnection connection = new JingleConnection(this); - connection.init(account, packet); - connections.add(connection); - } else { - for (JingleConnection connection : connections) { - if (connection.getAccount() == account - && connection.getSessionId().equals( - packet.getSessionId()) - && connection.getCounterPart().equals(packet.getFrom())) { - connection.deliverPacket(packet); - return; - } - } - account.getXmppConnection().sendIqPacket( - packet.generateRespone(IqPacket.TYPE_ERROR), null); - } - } - - public JingleConnection createNewConnection(Message message) { - JingleConnection connection = new JingleConnection(this); - connection.init(message); - this.connections.add(connection); - return connection; - } - - public JingleConnection createNewConnection(JinglePacket packet) { - JingleConnection connection = new JingleConnection(this); - this.connections.add(connection); - return connection; - } - - public void finishConnection(JingleConnection connection) { - this.connections.remove(connection); - } - - public void getPrimaryCandidate(Account account, - final OnPrimaryCandidateFound listener) { - if (!this.primaryCandidates.containsKey(account.getJid())) { - String xmlns = "http://jabber.org/protocol/bytestreams"; - final String proxy = account.getXmppConnection() - .findDiscoItemByFeature(xmlns); - if (proxy != null) { - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); - iq.setTo(proxy); - iq.query(xmlns); - account.getXmppConnection().sendIqPacket(iq, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - Element streamhost = packet - .query() - .findChild("streamhost", - "http://jabber.org/protocol/bytestreams"); - if (streamhost != null) { - JingleCandidate candidate = new JingleCandidate( - nextRandomId(), true); - candidate.setHost(streamhost - .getAttribute("host")); - candidate.setPort(Integer - .parseInt(streamhost - .getAttribute("port"))); - candidate - .setType(JingleCandidate.TYPE_PROXY); - candidate.setJid(proxy); - candidate.setPriority(655360 + 65535); - primaryCandidates.put(account.getJid(), - candidate); - listener.onPrimaryCandidateFound(true, - candidate); - } else { - listener.onPrimaryCandidateFound(false, - null); - } - } - }); - } else { - listener.onPrimaryCandidateFound(false, null); - } - - } else { - listener.onPrimaryCandidateFound(true, - this.primaryCandidates.get(account.getJid())); - } - } - - public String nextRandomId() { - return new BigInteger(50, random).toString(32); - } - - public void deliverIbbPacket(Account account, IqPacket packet) { - String sid = null; - Element payload = null; - if (packet.hasChild("open", "http://jabber.org/protocol/ibb")) { - payload = packet - .findChild("open", "http://jabber.org/protocol/ibb"); - sid = payload.getAttribute("sid"); - } else if (packet.hasChild("data", "http://jabber.org/protocol/ibb")) { - payload = packet - .findChild("data", "http://jabber.org/protocol/ibb"); - sid = payload.getAttribute("sid"); - } - if (sid != null) { - for (JingleConnection connection : connections) { - if (connection.getAccount() == account - && connection.hasTransportId(sid)) { - JingleTransport transport = connection.getTransport(); - if (transport instanceof JingleInbandTransport) { - JingleInbandTransport inbandTransport = (JingleInbandTransport) transport; - inbandTransport.deliverPayload(packet, payload); - return; - } - } - } - Log.d(Config.LOGTAG, - "couldnt deliver payload: " + payload.toString()); - } else { - Log.d(Config.LOGTAG, "no sid found in incomming ibb packet"); - } - } - - public void cancelInTransmission() { - for (JingleConnection connection : this.connections) { - if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) { - connection.cancel(); - } - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java deleted file mode 100644 index cc1e92f6..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ /dev/null @@ -1,191 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -import android.util.Base64; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.utils.CryptoHelper; -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public class JingleInbandTransport extends JingleTransport { - - private Account account; - private String counterpart; - private int blockSize; - private int bufferSize; - private int seq = 0; - private String sessionId; - - private boolean established = false; - - private DownloadableFile file; - - private InputStream fileInputStream = null; - private OutputStream fileOutputStream; - private long remainingSize; - private MessageDigest digest; - - private OnFileTransmissionStatusChanged onFileTransmissionStatusChanged; - - private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { - sendNextBlock(); - } - } - }; - - public JingleInbandTransport(Account account, String counterpart, - String sid, int blocksize) { - this.account = account; - this.counterpart = counterpart; - this.blockSize = blocksize; - this.bufferSize = blocksize / 4; - this.sessionId = sid; - } - - public void connect(final OnTransportConnected callback) { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - iq.setTo(this.counterpart); - Element open = iq.addChild("open", "http://jabber.org/protocol/ibb"); - open.setAttribute("sid", this.sessionId); - open.setAttribute("stanza", "iq"); - open.setAttribute("block-size", Integer.toString(this.blockSize)); - - this.account.getXmppConnection().sendIqPacket(iq, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { - callback.failed(); - } else { - callback.established(); - } - } - }); - } - - @Override - public void receive(DownloadableFile file, - OnFileTransmissionStatusChanged callback) { - this.onFileTransmissionStatusChanged = callback; - this.file = file; - try { - this.digest = MessageDigest.getInstance("SHA-1"); - digest.reset(); - file.getParentFile().mkdirs(); - file.createNewFile(); - this.fileOutputStream = file.createOutputStream(); - if (this.fileOutputStream == null) { - callback.onFileTransferAborted(); - return; - } - this.remainingSize = file.getExpectedSize(); - } catch (NoSuchAlgorithmException e) { - callback.onFileTransferAborted(); - } catch (IOException e) { - callback.onFileTransferAborted(); - } - } - - @Override - public void send(DownloadableFile file, - OnFileTransmissionStatusChanged callback) { - this.onFileTransmissionStatusChanged = callback; - this.file = file; - try { - this.digest = MessageDigest.getInstance("SHA-1"); - this.digest.reset(); - fileInputStream = this.file.createInputStream(); - if (fileInputStream == null) { - callback.onFileTransferAborted(); - return; - } - this.sendNextBlock(); - } catch (NoSuchAlgorithmException e) { - callback.onFileTransferAborted(); - } - } - - private void sendNextBlock() { - byte[] buffer = new byte[this.bufferSize]; - try { - int count = fileInputStream.read(buffer); - if (count == -1) { - file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - fileInputStream.close(); - this.onFileTransmissionStatusChanged.onFileTransmitted(file); - } else { - this.digest.update(buffer); - String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP); - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - iq.setTo(this.counterpart); - Element data = iq.addChild("data", - "http://jabber.org/protocol/ibb"); - data.setAttribute("seq", Integer.toString(this.seq)); - data.setAttribute("block-size", - Integer.toString(this.blockSize)); - data.setAttribute("sid", this.sessionId); - data.setContent(base64); - this.account.getXmppConnection().sendIqPacket(iq, - this.onAckReceived); - this.seq++; - } - } catch (IOException e) { - this.onFileTransmissionStatusChanged.onFileTransferAborted(); - } - } - - private void receiveNextBlock(String data) { - try { - byte[] buffer = Base64.decode(data, Base64.NO_WRAP); - if (this.remainingSize < buffer.length) { - buffer = Arrays - .copyOfRange(buffer, 0, (int) this.remainingSize); - } - this.remainingSize -= buffer.length; - - this.fileOutputStream.write(buffer); - - this.digest.update(buffer); - if (this.remainingSize <= 0) { - file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - fileOutputStream.flush(); - fileOutputStream.close(); - this.onFileTransmissionStatusChanged.onFileTransmitted(file); - } - } catch (IOException e) { - this.onFileTransmissionStatusChanged.onFileTransferAborted(); - } - } - - public void deliverPayload(IqPacket packet, Element payload) { - if (payload.getName().equals("open")) { - if (!established) { - established = true; - this.account.getXmppConnection().sendIqPacket( - packet.generateRespone(IqPacket.TYPE_RESULT), null); - } else { - this.account.getXmppConnection().sendIqPacket( - packet.generateRespone(IqPacket.TYPE_ERROR), null); - } - } else if (payload.getName().equals("data")) { - this.receiveNextBlock(payload.getContent()); - this.account.getXmppConnection().sendIqPacket( - packet.generateRespone(IqPacket.TYPE_RESULT), null); - } else { - // TODO some sort of exception - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java deleted file mode 100644 index 1da2f0cd..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ /dev/null @@ -1,212 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.utils.CryptoHelper; - -public class JingleSocks5Transport extends JingleTransport { - private JingleCandidate candidate; - private String destination; - private OutputStream outputStream; - private InputStream inputStream; - private boolean isEstablished = false; - private boolean activated = false; - protected Socket socket; - - public JingleSocks5Transport(JingleConnection jingleConnection, - JingleCandidate candidate) { - this.candidate = candidate; - try { - MessageDigest mDigest = MessageDigest.getInstance("SHA-1"); - StringBuilder destBuilder = new StringBuilder(); - destBuilder.append(jingleConnection.getSessionId()); - if (candidate.isOurs()) { - destBuilder.append(jingleConnection.getAccount().getFullJid()); - destBuilder.append(jingleConnection.getCounterPart()); - } else { - destBuilder.append(jingleConnection.getCounterPart()); - destBuilder.append(jingleConnection.getAccount().getFullJid()); - } - mDigest.reset(); - this.destination = CryptoHelper.bytesToHex(mDigest - .digest(destBuilder.toString().getBytes())); - } catch (NoSuchAlgorithmException e) { - - } - } - - public void connect(final OnTransportConnected callback) { - new Thread(new Runnable() { - - @Override - public void run() { - try { - socket = new Socket(candidate.getHost(), - candidate.getPort()); - inputStream = socket.getInputStream(); - outputStream = socket.getOutputStream(); - byte[] login = { 0x05, 0x01, 0x00 }; - byte[] expectedReply = { 0x05, 0x00 }; - byte[] reply = new byte[2]; - outputStream.write(login); - inputStream.read(reply); - final String connect = Character.toString('\u0005') - + '\u0001' + '\u0000' + '\u0003' + '\u0028' - + destination + '\u0000' + '\u0000'; - if (Arrays.equals(reply, expectedReply)) { - outputStream.write(connect.getBytes()); - byte[] result = new byte[2]; - inputStream.read(result); - int status = result[1]; - if (status == 0) { - isEstablished = true; - callback.established(); - } else { - callback.failed(); - } - } else { - socket.close(); - callback.failed(); - } - } catch (UnknownHostException e) { - callback.failed(); - } catch (IOException e) { - callback.failed(); - } - } - }).start(); - - } - - public void send(final DownloadableFile file, - final OnFileTransmissionStatusChanged callback) { - new Thread(new Runnable() { - - @Override - public void run() { - InputStream fileInputStream = null; - try { - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.reset(); - fileInputStream = file.createInputStream(); - if (fileInputStream == null) { - callback.onFileTransferAborted(); - return; - } - int count; - byte[] buffer = new byte[8192]; - while ((count = fileInputStream.read(buffer)) > 0) { - outputStream.write(buffer, 0, count); - digest.update(buffer, 0, count); - } - outputStream.flush(); - file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - if (callback != null) { - callback.onFileTransmitted(file); - } - } catch (FileNotFoundException e) { - callback.onFileTransferAborted(); - } catch (IOException e) { - callback.onFileTransferAborted(); - } catch (NoSuchAlgorithmException e) { - callback.onFileTransferAborted(); - } finally { - try { - if (fileInputStream != null) { - fileInputStream.close(); - } - } catch (IOException e) { - callback.onFileTransferAborted(); - } - } - } - }).start(); - - } - - public void receive(final DownloadableFile file, - final OnFileTransmissionStatusChanged callback) { - new Thread(new Runnable() { - - @Override - public void run() { - try { - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.reset(); - inputStream.skip(45); - socket.setSoTimeout(30000); - file.getParentFile().mkdirs(); - file.createNewFile(); - OutputStream fileOutputStream = file.createOutputStream(); - if (fileOutputStream == null) { - callback.onFileTransferAborted(); - return; - } - long remainingSize = file.getExpectedSize(); - byte[] buffer = new byte[8192]; - int count = buffer.length; - while (remainingSize > 0) { - count = inputStream.read(buffer); - if (count == -1) { - callback.onFileTransferAborted(); - return; - } else { - fileOutputStream.write(buffer, 0, count); - digest.update(buffer, 0, count); - remainingSize -= count; - } - } - fileOutputStream.flush(); - fileOutputStream.close(); - file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - callback.onFileTransmitted(file); - } catch (FileNotFoundException e) { - callback.onFileTransferAborted(); - } catch (IOException e) { - callback.onFileTransferAborted(); - } catch (NoSuchAlgorithmException e) { - callback.onFileTransferAborted(); - } - } - }).start(); - } - - public boolean isProxy() { - return this.candidate.getType() == JingleCandidate.TYPE_PROXY; - } - - public boolean needsActivation() { - return (this.isProxy() && !this.activated); - } - - public void disconnect() { - if (this.socket != null) { - try { - this.socket.close(); - } catch (IOException e) { - - } - } - } - - public boolean isEstablished() { - return this.isEstablished; - } - - public JingleCandidate getCandidate() { - return this.candidate; - } - - public void setActivated(boolean activated) { - this.activated = activated; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java deleted file mode 100644 index 1374e61c..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import eu.siacs.conversations.entities.DownloadableFile; - -public abstract class JingleTransport { - public abstract void connect(final OnTransportConnected callback); - - public abstract void receive(final DownloadableFile file, - final OnFileTransmissionStatusChanged callback); - - public abstract void send(final DownloadableFile file, - final OnFileTransmissionStatusChanged callback); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java deleted file mode 100644 index e45e7441..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java +++ /dev/null @@ -1,9 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import eu.siacs.conversations.entities.DownloadableFile; - -public interface OnFileTransmissionStatusChanged { - public void onFileTransmitted(DownloadableFile file); - - public void onFileTransferAborted(); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnJinglePacketReceived.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnJinglePacketReceived.java deleted file mode 100644 index 2aaf62a1..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnJinglePacketReceived.java +++ /dev/null @@ -1,9 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.xmpp.PacketReceived; -import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; - -public interface OnJinglePacketReceived extends PacketReceived { - public void onJinglePacketReceived(Account account, JinglePacket packet); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java deleted file mode 100644 index 03a437b2..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java +++ /dev/null @@ -1,6 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -public interface OnPrimaryCandidateFound { - public void onPrimaryCandidateFound(boolean success, - JingleCandidate canditate); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnTransportConnected.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnTransportConnected.java deleted file mode 100644 index 38f03c5d..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/OnTransportConnected.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle; - -public interface OnTransportConnected { - public void failed(); - - public void established(); -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java deleted file mode 100644 index bcadbe77..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java +++ /dev/null @@ -1,102 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle.stanzas; - -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.xml.Element; - -public class Content extends Element { - - private String transportId; - - private Content(String name) { - super(name); - } - - public Content() { - super("content"); - } - - public Content(String creator, String name) { - super("content"); - this.setAttribute("creator", creator); - this.setAttribute("name", name); - } - - public void setTransportId(String sid) { - this.transportId = sid; - } - - public void setFileOffer(DownloadableFile actualFile, boolean otr) { - Element description = this.addChild("description", - "urn:xmpp:jingle:apps:file-transfer:3"); - Element offer = description.addChild("offer"); - Element file = offer.addChild("file"); - file.addChild("size").setContent(Long.toString(actualFile.getSize())); - if (otr) { - file.addChild("name").setContent(actualFile.getName() + ".otr"); - } else { - file.addChild("name").setContent(actualFile.getName()); - } - } - - public Element getFileOffer() { - Element description = this.findChild("description", - "urn:xmpp:jingle:apps:file-transfer:3"); - if (description == null) { - return null; - } - Element offer = description.findChild("offer"); - if (offer == null) { - return null; - } - return offer.findChild("file"); - } - - public void setFileOffer(Element fileOffer) { - Element description = this.findChild("description", - "urn:xmpp:jingle:apps:file-transfer:3"); - if (description == null) { - description = this.addChild("description", - "urn:xmpp:jingle:apps:file-transfer:3"); - } - description.addChild(fileOffer); - } - - public String getTransportId() { - if (hasSocks5Transport()) { - this.transportId = socks5transport().getAttribute("sid"); - } else if (hasIbbTransport()) { - this.transportId = ibbTransport().getAttribute("sid"); - } - return this.transportId; - } - - public Element socks5transport() { - Element transport = this.findChild("transport", - "urn:xmpp:jingle:transports:s5b:1"); - if (transport == null) { - transport = this.addChild("transport", - "urn:xmpp:jingle:transports:s5b:1"); - transport.setAttribute("sid", this.transportId); - } - return transport; - } - - public Element ibbTransport() { - Element transport = this.findChild("transport", - "urn:xmpp:jingle:transports:ibb:1"); - if (transport == null) { - transport = this.addChild("transport", - "urn:xmpp:jingle:transports:ibb:1"); - transport.setAttribute("sid", this.transportId); - } - return transport; - } - - public boolean hasSocks5Transport() { - return this.hasChild("transport", "urn:xmpp:jingle:transports:s5b:1"); - } - - public boolean hasIbbTransport() { - return this.hasChild("transport", "urn:xmpp:jingle:transports:ibb:1"); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java deleted file mode 100644 index 77a73643..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java +++ /dev/null @@ -1,95 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle.stanzas; - -import eu.siacs.conversations.xml.Element; -import eu.siacs.conversations.xmpp.stanzas.IqPacket; - -public class JinglePacket extends IqPacket { - Content content = null; - Reason reason = null; - Element jingle = new Element("jingle"); - - @Override - public Element addChild(Element child) { - if ("jingle".equals(child.getName())) { - Element contentElement = child.findChild("content"); - if (contentElement != null) { - this.content = new Content(); - this.content.setChildren(contentElement.getChildren()); - this.content.setAttributes(contentElement.getAttributes()); - } - Element reasonElement = child.findChild("reason"); - if (reasonElement != null) { - this.reason = new Reason(); - this.reason.setChildren(reasonElement.getChildren()); - this.reason.setAttributes(reasonElement.getAttributes()); - } - this.jingle.setAttributes(child.getAttributes()); - } - return child; - } - - public JinglePacket setContent(Content content) { - this.content = content; - return this; - } - - public Content getJingleContent() { - if (this.content == null) { - this.content = new Content(); - } - return this.content; - } - - public JinglePacket setReason(Reason reason) { - this.reason = reason; - return this; - } - - public Reason getReason() { - return this.reason; - } - - private void build() { - this.children.clear(); - this.jingle.clearChildren(); - this.jingle.setAttribute("xmlns", "urn:xmpp:jingle:1"); - if (this.content != null) { - jingle.addChild(this.content); - } - if (this.reason != null) { - jingle.addChild(this.reason); - } - this.children.add(jingle); - this.setAttribute("type", "set"); - } - - public String getSessionId() { - return this.jingle.getAttribute("sid"); - } - - public void setSessionId(String sid) { - this.jingle.setAttribute("sid", sid); - } - - @Override - public String toString() { - this.build(); - return super.toString(); - } - - public void setAction(String action) { - this.jingle.setAttribute("action", action); - } - - public String getAction() { - return this.jingle.getAttribute("action"); - } - - public void setInitiator(String initiator) { - this.jingle.setAttribute("initiator", initiator); - } - - public boolean isAction(String action) { - return action.equalsIgnoreCase(this.getAction()); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Reason.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Reason.java deleted file mode 100644 index 610d5e76..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Reason.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.siacs.conversations.xmpp.jingle.stanzas; - -import eu.siacs.conversations.xml.Element; - -public class Reason extends Element { - private Reason(String name) { - super(name); - } - - public Reason() { - super("reason"); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java deleted file mode 100644 index 154fadf6..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java +++ /dev/null @@ -1,71 +0,0 @@ -package eu.siacs.conversations.xmpp.pep; - -import eu.siacs.conversations.xml.Element; -import android.util.Base64; - -public class Avatar { - public String type; - public String sha1sum; - public String image; - public int height; - public int width; - public long size; - public String owner; - - public byte[] getImageAsBytes() { - return Base64.decode(image, Base64.DEFAULT); - } - - public String getFilename() { - if (type == null) { - return sha1sum; - } else if (type.equalsIgnoreCase("image/webp")) { - return sha1sum + ".webp"; - } else if (type.equalsIgnoreCase("image/png")) { - return sha1sum + ".png"; - } else { - return sha1sum; - } - } - - public static Avatar parseMetadata(Element items) { - Element item = items.findChild("item"); - if (item == null) { - return null; - } - Element metadata = item.findChild("metadata"); - if (metadata == null) { - return null; - } - String primaryId = item.getAttribute("id"); - if (primaryId == null) { - return null; - } - for (Element child : metadata.getChildren()) { - if (child.getName().equals("info") - && primaryId.equals(child.getAttribute("id"))) { - Avatar avatar = new Avatar(); - String height = child.getAttribute("height"); - String width = child.getAttribute("width"); - String size = child.getAttribute("bytes"); - try { - if (height != null) { - avatar.height = Integer.parseInt(height); - } - if (width != null) { - avatar.width = Integer.parseInt(width); - } - if (size != null) { - avatar.size = Long.parseLong(size); - } - } catch (NumberFormatException e) { - return null; - } - avatar.type = child.getAttribute("type"); - avatar.sha1sum = child.getAttribute("id"); - return avatar; - } - } - return null; - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java deleted file mode 100644 index eef41c79..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java +++ /dev/null @@ -1,34 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas; - -import eu.siacs.conversations.xml.Element; - -public class AbstractStanza extends Element { - - protected AbstractStanza(String name) { - super(name); - } - - public String getTo() { - return getAttribute("to"); - } - - public String getFrom() { - return getAttribute("from"); - } - - public String getId() { - return this.getAttribute("id"); - } - - public void setTo(String to) { - setAttribute("to", to); - } - - public void setFrom(String from) { - setAttribute("from", from); - } - - public void setId(String id) { - setAttribute("id", id); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java deleted file mode 100644 index 9df05e67..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java +++ /dev/null @@ -1,76 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas; - -import eu.siacs.conversations.xml.Element; - -public class IqPacket extends AbstractStanza { - - public static final int TYPE_ERROR = -1; - public static final int TYPE_SET = 0; - public static final int TYPE_RESULT = 1; - public static final int TYPE_GET = 2; - - private IqPacket(String name) { - super(name); - } - - public IqPacket(int type) { - super("iq"); - switch (type) { - case TYPE_SET: - this.setAttribute("type", "set"); - break; - case TYPE_GET: - this.setAttribute("type", "get"); - break; - case TYPE_RESULT: - this.setAttribute("type", "result"); - break; - case TYPE_ERROR: - this.setAttribute("type", "error"); - break; - default: - break; - } - } - - public IqPacket() { - super("iq"); - } - - public Element query() { - Element query = findChild("query"); - if (query == null) { - query = addChild("query"); - } - return query; - } - - public Element query(String xmlns) { - Element query = query(); - query.setAttribute("xmlns", xmlns); - return query(); - } - - public int getType() { - String type = getAttribute("type"); - if ("error".equals(type)) { - return TYPE_ERROR; - } else if ("result".equals(type)) { - return TYPE_RESULT; - } else if ("set".equals(type)) { - return TYPE_SET; - } else if ("get".equals(type)) { - return TYPE_GET; - } else { - return 1000; - } - } - - public IqPacket generateRespone(int type) { - IqPacket packet = new IqPacket(type); - packet.setTo(this.getFrom()); - packet.setId(this.getId()); - return packet; - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java deleted file mode 100644 index 4e7b532b..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java +++ /dev/null @@ -1,66 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas; - -import eu.siacs.conversations.xml.Element; - -public class MessagePacket extends AbstractStanza { - public static final int TYPE_CHAT = 0; - public static final int TYPE_NORMAL = 2; - public static final int TYPE_GROUPCHAT = 3; - public static final int TYPE_ERROR = 4; - public static final int TYPE_HEADLINE = 5; - - public MessagePacket() { - super("message"); - } - - public String getBody() { - Element body = this.findChild("body"); - if (body != null) { - return body.getContent(); - } else { - return null; - } - } - - public void setBody(String text) { - this.children.remove(findChild("body")); - Element body = new Element("body"); - body.setContent(text); - this.children.add(body); - } - - public void setType(int type) { - switch (type) { - case TYPE_CHAT: - this.setAttribute("type", "chat"); - break; - case TYPE_GROUPCHAT: - this.setAttribute("type", "groupchat"); - break; - case TYPE_NORMAL: - break; - default: - this.setAttribute("type", "chat"); - break; - } - } - - public int getType() { - String type = getAttribute("type"); - if (type == null) { - return TYPE_NORMAL; - } else if (type.equals("normal")) { - return TYPE_NORMAL; - } else if (type.equals("chat")) { - return TYPE_CHAT; - } else if (type.equals("groupchat")) { - return TYPE_GROUPCHAT; - } else if (type.equals("error")) { - return TYPE_ERROR; - } else if (type.equals("headline")) { - return TYPE_HEADLINE; - } else { - return TYPE_NORMAL; - } - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/PresencePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/PresencePacket.java deleted file mode 100644 index 7ea32099..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/PresencePacket.java +++ /dev/null @@ -1,8 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas; - -public class PresencePacket extends AbstractStanza { - - public PresencePacket() { - super("presence"); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/ActivePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/ActivePacket.java deleted file mode 100644 index 78ab66d8..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/ActivePacket.java +++ /dev/null @@ -1,10 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas.csi; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class ActivePacket extends AbstractStanza { - public ActivePacket() { - super("active"); - setAttribute("xmlns", "urn:xmpp:csi:0"); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/InactivePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/InactivePacket.java deleted file mode 100644 index f109280f..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/csi/InactivePacket.java +++ /dev/null @@ -1,10 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas.csi; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class InactivePacket extends AbstractStanza { - public InactivePacket() { - super("inactive"); - setAttribute("xmlns", "urn:xmpp:csi:0"); - } -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/AckPacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/AckPacket.java deleted file mode 100644 index f93b5d87..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/AckPacket.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas.streammgmt; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class AckPacket extends AbstractStanza { - - public AckPacket(int sequence, int smVersion) { - super("a"); - this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion); - this.setAttribute("h", Integer.toString(sequence)); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/EnablePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/EnablePacket.java deleted file mode 100644 index 78cd81ed..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/EnablePacket.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas.streammgmt; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class EnablePacket extends AbstractStanza { - - public EnablePacket(int smVersion) { - super("enable"); - this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion); - this.setAttribute("resume", "true"); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/RequestPacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/RequestPacket.java deleted file mode 100644 index 98cfc748..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/RequestPacket.java +++ /dev/null @@ -1,12 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas.streammgmt; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class RequestPacket extends AbstractStanza { - - public RequestPacket(int smVersion) { - super("r"); - this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion); - } - -} diff --git a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/ResumePacket.java b/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/ResumePacket.java deleted file mode 100644 index 9cdcfa5e..00000000 --- a/conversations/src/main/java/eu/siacs/conversations/xmpp/stanzas/streammgmt/ResumePacket.java +++ /dev/null @@ -1,14 +0,0 @@ -package eu.siacs.conversations.xmpp.stanzas.streammgmt; - -import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; - -public class ResumePacket extends AbstractStanza { - - public ResumePacket(String id, int sequence, int smVersion) { - super("resume"); - this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion); - this.setAttribute("previd", id); - this.setAttribute("h", Integer.toString(sequence)); - } - -} diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_add_group.png b/conversations/src/main/res/drawable-hdpi/ic_action_add_group.png deleted file mode 100644 index 97640355..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_add_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_add_person.png b/conversations/src/main/res/drawable-hdpi/ic_action_add_person.png deleted file mode 100644 index 9d88d0f4..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_add_person.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_chat.png b/conversations/src/main/res/drawable-hdpi/ic_action_chat.png deleted file mode 100644 index 0847ac46..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_chat.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_copy.png b/conversations/src/main/res/drawable-hdpi/ic_action_copy.png deleted file mode 100644 index 22327391..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_copy.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_discard.png b/conversations/src/main/res/drawable-hdpi/ic_action_discard.png deleted file mode 100644 index 703b31f8..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_discard.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_edit.png b/conversations/src/main/res/drawable-hdpi/ic_action_edit.png deleted file mode 100644 index 756db316..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_edit.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_edit_dark.png b/conversations/src/main/res/drawable-hdpi/ic_action_edit_dark.png deleted file mode 100644 index 5f7c6eff..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_edit_dark.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_group.png b/conversations/src/main/res/drawable-hdpi/ic_action_group.png deleted file mode 100644 index 3e7f16d5..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_new.png b/conversations/src/main/res/drawable-hdpi/ic_action_new.png deleted file mode 100644 index d866d616..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_new.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_new_attachment.png b/conversations/src/main/res/drawable-hdpi/ic_action_new_attachment.png deleted file mode 100644 index c01c2b38..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_new_attachment.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_not_secure.png b/conversations/src/main/res/drawable-hdpi/ic_action_not_secure.png deleted file mode 100644 index 2c917615..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_not_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_refresh.png b/conversations/src/main/res/drawable-hdpi/ic_action_refresh.png deleted file mode 100644 index 45b22282..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_refresh.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_remove.png b/conversations/src/main/res/drawable-hdpi/ic_action_remove.png deleted file mode 100644 index 58a56e45..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_remove.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_search.png b/conversations/src/main/res/drawable-hdpi/ic_action_search.png deleted file mode 100644 index 772e3598..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_search.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_secure.png b/conversations/src/main/res/drawable-hdpi/ic_action_secure.png deleted file mode 100644 index 4439d1ae..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_away.png b/conversations/src/main/res/drawable-hdpi/ic_action_send_now_away.png deleted file mode 100644 index 505cbe63..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png b/conversations/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png deleted file mode 100644 index a376524d..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_offline.png b/conversations/src/main/res/drawable-hdpi/ic_action_send_now_offline.png deleted file mode 100644 index d4d2d510..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_online.png b/conversations/src/main/res/drawable-hdpi/ic_action_send_now_online.png deleted file mode 100644 index 48676f7b..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_activity.png b/conversations/src/main/res/drawable-hdpi/ic_activity.png deleted file mode 100644 index 613da683..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_activity.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_indicator.png b/conversations/src/main/res/drawable-hdpi/ic_indicator.png deleted file mode 100644 index 6de8969f..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_launcher.png b/conversations/src/main/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index d48df2c3..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_notification.png b/conversations/src/main/res/drawable-hdpi/ic_notification.png deleted file mode 100644 index 664ba535..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_notification.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_profile.png b/conversations/src/main/res/drawable-hdpi/ic_profile.png deleted file mode 100644 index 3f071dec..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_profile.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_received_indicator.png b/conversations/src/main/res/drawable-hdpi/ic_received_indicator.png deleted file mode 100644 index b1e3f274..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_received_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/ic_secure_indicator.png b/conversations/src/main/res/drawable-hdpi/ic_secure_indicator.png deleted file mode 100644 index 2a2934fb..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/ic_secure_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/tab_selected_conversations.9.png b/conversations/src/main/res/drawable-hdpi/tab_selected_conversations.9.png deleted file mode 100644 index b8f44c21..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/tab_selected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/tab_selected_focused_conversations.9.png b/conversations/src/main/res/drawable-hdpi/tab_selected_focused_conversations.9.png deleted file mode 100644 index 5512dbd3..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/tab_selected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/tab_selected_pressed_conversations.9.png b/conversations/src/main/res/drawable-hdpi/tab_selected_pressed_conversations.9.png deleted file mode 100644 index e5f1df22..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/tab_selected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/tab_unselected_conversations.9.png b/conversations/src/main/res/drawable-hdpi/tab_unselected_conversations.9.png deleted file mode 100644 index 7cd46d63..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/tab_unselected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/tab_unselected_focused_conversations.9.png b/conversations/src/main/res/drawable-hdpi/tab_unselected_focused_conversations.9.png deleted file mode 100644 index 438ecdd8..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/tab_unselected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-hdpi/tab_unselected_pressed_conversations.9.png b/conversations/src/main/res/drawable-hdpi/tab_unselected_pressed_conversations.9.png deleted file mode 100644 index 4f18a95a..00000000 Binary files a/conversations/src/main/res/drawable-hdpi/tab_unselected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_add_group.png b/conversations/src/main/res/drawable-mdpi/ic_action_add_group.png deleted file mode 100644 index 9a655899..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_add_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_add_person.png b/conversations/src/main/res/drawable-mdpi/ic_action_add_person.png deleted file mode 100644 index b7d8f46a..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_add_person.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_chat.png b/conversations/src/main/res/drawable-mdpi/ic_action_chat.png deleted file mode 100644 index 8fdb5d75..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_chat.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_copy.png b/conversations/src/main/res/drawable-mdpi/ic_action_copy.png deleted file mode 100644 index 71348202..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_copy.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_discard.png b/conversations/src/main/res/drawable-mdpi/ic_action_discard.png deleted file mode 100644 index 248fb09c..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_discard.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_edit.png b/conversations/src/main/res/drawable-mdpi/ic_action_edit.png deleted file mode 100644 index 68a45320..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_edit.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_edit_dark.png b/conversations/src/main/res/drawable-mdpi/ic_action_edit_dark.png deleted file mode 100644 index 650b4d89..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_edit_dark.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_group.png b/conversations/src/main/res/drawable-mdpi/ic_action_group.png deleted file mode 100644 index 1ee3cccd..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_new.png b/conversations/src/main/res/drawable-mdpi/ic_action_new.png deleted file mode 100644 index f17e7980..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_new.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_new_attachment.png b/conversations/src/main/res/drawable-mdpi/ic_action_new_attachment.png deleted file mode 100644 index 1d265aac..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_new_attachment.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_not_secure.png b/conversations/src/main/res/drawable-mdpi/ic_action_not_secure.png deleted file mode 100644 index faffa233..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_not_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_refresh.png b/conversations/src/main/res/drawable-mdpi/ic_action_refresh.png deleted file mode 100644 index de008e51..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_refresh.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_remove.png b/conversations/src/main/res/drawable-mdpi/ic_action_remove.png deleted file mode 100644 index 342a79de..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_remove.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_search.png b/conversations/src/main/res/drawable-mdpi/ic_action_search.png deleted file mode 100644 index 4edb1ff9..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_search.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_secure.png b/conversations/src/main/res/drawable-mdpi/ic_action_secure.png deleted file mode 100644 index 05332ebf..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_away.png b/conversations/src/main/res/drawable-mdpi/ic_action_send_now_away.png deleted file mode 100644 index 0fdca901..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png b/conversations/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png deleted file mode 100644 index c0aef36c..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_offline.png b/conversations/src/main/res/drawable-mdpi/ic_action_send_now_offline.png deleted file mode 100644 index 7723f4aa..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_online.png b/conversations/src/main/res/drawable-mdpi/ic_action_send_now_online.png deleted file mode 100644 index 39d00ee4..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_activity.png b/conversations/src/main/res/drawable-mdpi/ic_activity.png deleted file mode 100644 index c8727f57..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_activity.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_indicator.png b/conversations/src/main/res/drawable-mdpi/ic_indicator.png deleted file mode 100644 index bb4fee10..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_launcher.png b/conversations/src/main/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 200daf4c..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_notification.png b/conversations/src/main/res/drawable-mdpi/ic_notification.png deleted file mode 100644 index 5d1aca10..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_notification.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_profile.png b/conversations/src/main/res/drawable-mdpi/ic_profile.png deleted file mode 100644 index 0d056c7c..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_profile.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_received_indicator.png b/conversations/src/main/res/drawable-mdpi/ic_received_indicator.png deleted file mode 100644 index 88ff1efb..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_received_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/ic_secure_indicator.png b/conversations/src/main/res/drawable-mdpi/ic_secure_indicator.png deleted file mode 100644 index 5a73aef4..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/ic_secure_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/tab_selected_conversations.9.png b/conversations/src/main/res/drawable-mdpi/tab_selected_conversations.9.png deleted file mode 100644 index 09d42dc8..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/tab_selected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/tab_selected_focused_conversations.9.png b/conversations/src/main/res/drawable-mdpi/tab_selected_focused_conversations.9.png deleted file mode 100644 index 20af01de..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/tab_selected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/tab_selected_pressed_conversations.9.png b/conversations/src/main/res/drawable-mdpi/tab_selected_pressed_conversations.9.png deleted file mode 100644 index 13a878be..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/tab_selected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/tab_unselected_conversations.9.png b/conversations/src/main/res/drawable-mdpi/tab_unselected_conversations.9.png deleted file mode 100644 index ad2dbae9..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/tab_unselected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/tab_unselected_focused_conversations.9.png b/conversations/src/main/res/drawable-mdpi/tab_unselected_focused_conversations.9.png deleted file mode 100644 index dfff5ac8..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/tab_unselected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-mdpi/tab_unselected_pressed_conversations.9.png b/conversations/src/main/res/drawable-mdpi/tab_unselected_pressed_conversations.9.png deleted file mode 100644 index 4365d178..00000000 Binary files a/conversations/src/main/res/drawable-mdpi/tab_unselected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_add_group.png b/conversations/src/main/res/drawable-xhdpi/ic_action_add_group.png deleted file mode 100644 index c493aa5a..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_add_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_add_person.png b/conversations/src/main/res/drawable-xhdpi/ic_action_add_person.png deleted file mode 100644 index 4e8de1b6..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_add_person.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_chat.png b/conversations/src/main/res/drawable-xhdpi/ic_action_chat.png deleted file mode 100644 index 8a9a4314..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_chat.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_copy.png b/conversations/src/main/res/drawable-xhdpi/ic_action_copy.png deleted file mode 100644 index 5ddf1513..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_copy.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_discard.png b/conversations/src/main/res/drawable-xhdpi/ic_action_discard.png deleted file mode 100644 index 9eeeed12..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_discard.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_edit.png b/conversations/src/main/res/drawable-xhdpi/ic_action_edit.png deleted file mode 100644 index 67e056fe..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_edit.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_edit_dark.png b/conversations/src/main/res/drawable-xhdpi/ic_action_edit_dark.png deleted file mode 100644 index 8ab436d8..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_edit_dark.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_group.png b/conversations/src/main/res/drawable-xhdpi/ic_action_group.png deleted file mode 100644 index fa2af497..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_new.png b/conversations/src/main/res/drawable-xhdpi/ic_action_new.png deleted file mode 100644 index dde2141f..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_new.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_new_attachment.png b/conversations/src/main/res/drawable-xhdpi/ic_action_new_attachment.png deleted file mode 100644 index 41cbab20..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_new_attachment.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_not_secure.png b/conversations/src/main/res/drawable-xhdpi/ic_action_not_secure.png deleted file mode 100644 index c0902a03..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_not_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_refresh.png b/conversations/src/main/res/drawable-xhdpi/ic_action_refresh.png deleted file mode 100644 index cdc160d4..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_refresh.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_remove.png b/conversations/src/main/res/drawable-xhdpi/ic_action_remove.png deleted file mode 100644 index 58e2e3b4..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_remove.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_search.png b/conversations/src/main/res/drawable-xhdpi/ic_action_search.png deleted file mode 100644 index 19658e4a..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_search.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_secure.png b/conversations/src/main/res/drawable-xhdpi/ic_action_secure.png deleted file mode 100644 index 4e08b95a..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_away.png b/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_away.png deleted file mode 100644 index bb999d85..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png b/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png deleted file mode 100644 index a0bf5561..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png b/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png deleted file mode 100644 index 6da9ff7b..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_online.png b/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_online.png deleted file mode 100644 index 348ba657..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_activity.png b/conversations/src/main/res/drawable-xhdpi/ic_activity.png deleted file mode 100644 index 95ffbecf..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_activity.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_indicator.png b/conversations/src/main/res/drawable-xhdpi/ic_indicator.png deleted file mode 100644 index 3e5141c2..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_launcher.png b/conversations/src/main/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 927a2d2a..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_notification.png b/conversations/src/main/res/drawable-xhdpi/ic_notification.png deleted file mode 100644 index dfa643d0..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_notification.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_profile.png b/conversations/src/main/res/drawable-xhdpi/ic_profile.png deleted file mode 100644 index 88a82cf0..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_profile.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_received_indicator.png b/conversations/src/main/res/drawable-xhdpi/ic_received_indicator.png deleted file mode 100644 index 2c871933..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_received_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/ic_secure_indicator.png b/conversations/src/main/res/drawable-xhdpi/ic_secure_indicator.png deleted file mode 100644 index 1f4c9a32..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/ic_secure_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/tab_selected_conversations.9.png b/conversations/src/main/res/drawable-xhdpi/tab_selected_conversations.9.png deleted file mode 100644 index 34eb4ec0..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/tab_selected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/tab_selected_focused_conversations.9.png b/conversations/src/main/res/drawable-xhdpi/tab_selected_focused_conversations.9.png deleted file mode 100644 index 3155ef69..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/tab_selected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/tab_selected_pressed_conversations.9.png b/conversations/src/main/res/drawable-xhdpi/tab_selected_pressed_conversations.9.png deleted file mode 100644 index 5c2440e4..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/tab_selected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/tab_unselected_conversations.9.png b/conversations/src/main/res/drawable-xhdpi/tab_unselected_conversations.9.png deleted file mode 100644 index e9ab742e..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/tab_unselected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/tab_unselected_focused_conversations.9.png b/conversations/src/main/res/drawable-xhdpi/tab_unselected_focused_conversations.9.png deleted file mode 100644 index 42a2191e..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/tab_unselected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xhdpi/tab_unselected_pressed_conversations.9.png b/conversations/src/main/res/drawable-xhdpi/tab_unselected_pressed_conversations.9.png deleted file mode 100644 index a5a2c25e..00000000 Binary files a/conversations/src/main/res/drawable-xhdpi/tab_unselected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_add_group.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_add_group.png deleted file mode 100644 index 2b46dbb9..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_add_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_add_person.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_add_person.png deleted file mode 100644 index e9a58eaf..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_add_person.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_chat.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_chat.png deleted file mode 100644 index 04000fd0..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_chat.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_copy.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_copy.png deleted file mode 100644 index a0508df8..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_copy.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_discard.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_discard.png deleted file mode 100644 index cb1260a4..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_discard.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_edit.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_edit.png deleted file mode 100644 index 3a241ea4..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_edit.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_edit_dark.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_edit_dark.png deleted file mode 100644 index f2b2078b..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_edit_dark.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_group.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_group.png deleted file mode 100644 index 9289b1c8..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_group.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_new.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_new.png deleted file mode 100644 index c42c2bfb..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_new.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_new_attachment.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_new_attachment.png deleted file mode 100644 index ce7536cb..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_new_attachment.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_not_secure.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_not_secure.png deleted file mode 100644 index a186f1fb..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_not_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_refresh.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_refresh.png deleted file mode 100644 index cb847f37..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_refresh.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_remove.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_remove.png deleted file mode 100644 index 331c545b..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_remove.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_search.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_search.png deleted file mode 100644 index a1086388..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_search.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_secure.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_secure.png deleted file mode 100644 index ccf1fb00..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_secure.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png deleted file mode 100644 index 12ec4d33..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png deleted file mode 100644 index 7719f81a..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png deleted file mode 100644 index 18895813..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png b/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png deleted file mode 100644 index 29bde36e..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_activity.png b/conversations/src/main/res/drawable-xxhdpi/ic_activity.png deleted file mode 100644 index 0b642d9b..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_activity.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_indicator.png b/conversations/src/main/res/drawable-xxhdpi/ic_indicator.png deleted file mode 100644 index 2c51b8b7..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_launcher.png b/conversations/src/main/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index 65c1af34..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_notification.png b/conversations/src/main/res/drawable-xxhdpi/ic_notification.png deleted file mode 100644 index ee1e9534..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_notification.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_profile.png b/conversations/src/main/res/drawable-xxhdpi/ic_profile.png deleted file mode 100644 index 309dc513..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_profile.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_received_indicator.png b/conversations/src/main/res/drawable-xxhdpi/ic_received_indicator.png deleted file mode 100644 index 039a9ef9..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_received_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/ic_secure_indicator.png b/conversations/src/main/res/drawable-xxhdpi/ic_secure_indicator.png deleted file mode 100644 index 1ee9b67d..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/ic_secure_indicator.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/tab_selected_conversations.9.png b/conversations/src/main/res/drawable-xxhdpi/tab_selected_conversations.9.png deleted file mode 100644 index e4439e7c..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/tab_selected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/tab_selected_focused_conversations.9.png b/conversations/src/main/res/drawable-xxhdpi/tab_selected_focused_conversations.9.png deleted file mode 100644 index dd2ded89..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/tab_selected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/tab_selected_pressed_conversations.9.png b/conversations/src/main/res/drawable-xxhdpi/tab_selected_pressed_conversations.9.png deleted file mode 100644 index 58c8a576..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/tab_selected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/tab_unselected_conversations.9.png b/conversations/src/main/res/drawable-xxhdpi/tab_unselected_conversations.9.png deleted file mode 100644 index 566062f0..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/tab_unselected_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/tab_unselected_focused_conversations.9.png b/conversations/src/main/res/drawable-xxhdpi/tab_unselected_focused_conversations.9.png deleted file mode 100644 index 432e68c4..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/tab_unselected_focused_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable-xxhdpi/tab_unselected_pressed_conversations.9.png b/conversations/src/main/res/drawable-xxhdpi/tab_unselected_pressed_conversations.9.png deleted file mode 100644 index 8dd01d5c..00000000 Binary files a/conversations/src/main/res/drawable-xxhdpi/tab_unselected_pressed_conversations.9.png and /dev/null differ diff --git a/conversations/src/main/res/drawable/actionbar_tab_indicator.xml b/conversations/src/main/res/drawable/actionbar_tab_indicator.xml deleted file mode 100644 index 5598ee42..00000000 --- a/conversations/src/main/res/drawable/actionbar_tab_indicator.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/drawable/es_slidingpane_shadow.xml b/conversations/src/main/res/drawable/es_slidingpane_shadow.xml deleted file mode 100644 index 44ffd4ea..00000000 --- a/conversations/src/main/res/drawable/es_slidingpane_shadow.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/drawable/grey.xml b/conversations/src/main/res/drawable/grey.xml deleted file mode 100644 index 2e90d96d..00000000 --- a/conversations/src/main/res/drawable/grey.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/drawable/greybackground.xml b/conversations/src/main/res/drawable/greybackground.xml deleted file mode 100644 index bedc4b17..00000000 --- a/conversations/src/main/res/drawable/greybackground.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/drawable/infocard_border.xml b/conversations/src/main/res/drawable/infocard_border.xml deleted file mode 100644 index af7d5d22..00000000 --- a/conversations/src/main/res/drawable/infocard_border.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/drawable/message_border.xml b/conversations/src/main/res/drawable/message_border.xml deleted file mode 100644 index b35693d5..00000000 --- a/conversations/src/main/res/drawable/message_border.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/drawable/snackbar.xml b/conversations/src/main/res/drawable/snackbar.xml deleted file mode 100644 index 13818618..00000000 --- a/conversations/src/main/res/drawable/snackbar.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout-w360dp/fragment_conversations_overview.xml b/conversations/src/main/res/layout-w360dp/fragment_conversations_overview.xml deleted file mode 100644 index a600118d..00000000 --- a/conversations/src/main/res/layout-w360dp/fragment_conversations_overview.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout-w384dp/fragment_conversations_overview.xml b/conversations/src/main/res/layout-w384dp/fragment_conversations_overview.xml deleted file mode 100644 index c3aa67ae..00000000 --- a/conversations/src/main/res/layout-w384dp/fragment_conversations_overview.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout-w600dp/fragment_conversations_overview.xml b/conversations/src/main/res/layout-w600dp/fragment_conversations_overview.xml deleted file mode 100644 index 331fb1f0..00000000 --- a/conversations/src/main/res/layout-w600dp/fragment_conversations_overview.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout-w960dp/fragment_conversations_overview.xml b/conversations/src/main/res/layout-w960dp/fragment_conversations_overview.xml deleted file mode 100644 index 2744f38e..00000000 --- a/conversations/src/main/res/layout-w960dp/fragment_conversations_overview.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout/account_row.xml b/conversations/src/main/res/layout/account_row.xml deleted file mode 100644 index 2d1190a3..00000000 --- a/conversations/src/main/res/layout/account_row.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout/actionview_search.xml b/conversations/src/main/res/layout/actionview_search.xml deleted file mode 100644 index 64b75f0e..00000000 --- a/conversations/src/main/res/layout/actionview_search.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout/activity_choose_contact.xml b/conversations/src/main/res/layout/activity_choose_contact.xml deleted file mode 100644 index 248a7822..00000000 --- a/conversations/src/main/res/layout/activity_choose_contact.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout/activity_contact_details.xml b/conversations/src/main/res/layout/activity_contact_details.xml deleted file mode 100644 index f7cb2198..00000000 --- a/conversations/src/main/res/layout/activity_contact_details.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/conversations/src/main/res/layout/activity_edit_account.xml b/conversations/src/main/res/layout/activity_edit_account.xml deleted file mode 100644 index 97289628..00000000 --- a/conversations/src/main/res/layout/activity_edit_account.xml +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -