From 9c7cacdbddf6ba1a34fd56b71718ba4e44e20efa Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 16 Feb 2014 16:32:15 +0100 Subject: show unknown otr fingerprint warining --- src/de/gultsch/chat/ui/ConversationActivity.java | 59 +++++- src/de/gultsch/chat/ui/ConversationFragment.java | 225 +++++++++++++++++------ 2 files changed, 217 insertions(+), 67 deletions(-) (limited to 'src/de/gultsch/chat/ui') diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java index 011261e7a..b1464031b 100644 --- a/src/de/gultsch/chat/ui/ConversationActivity.java +++ b/src/de/gultsch/chat/ui/ConversationActivity.java @@ -32,6 +32,8 @@ import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; +import android.widget.PopupMenu; +import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.TextView; import android.widget.ImageView; @@ -295,6 +297,56 @@ public class ConversationActivity extends XmppActivity { } else { Log.d("xmppService","contact was null - means not in roster"); } + break; + case R.id.action_security: + final Conversation selConv = getSelectedConversation(); + View menuItemView = findViewById(R.id.action_security); + 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: + selConv.nextMessageEncryption = Message.ENCRYPTION_NONE; + item.setChecked(true); + break; + case R.id.encryption_choice_otr: + selConv.nextMessageEncryption = Message.ENCRYPTION_OTR; + item.setChecked(true); + break; + case R.id.encryption_choice_pgp: + selConv.nextMessageEncryption = Message.ENCRYPTION_PGP; + item.setChecked(true); + break; + default: + selConv.nextMessageEncryption = Message.ENCRYPTION_NONE; + break; + } + fragment.updateChatMsgHint(); + return true; + } + }); + popup.inflate(R.menu.encryption_choices); + switch (selConv.nextMessageEncryption) { + case Message.ENCRYPTION_NONE: + popup.getMenu().findItem(R.id.encryption_choice_none).setChecked(true); + break; + case Message.ENCRYPTION_OTR: + popup.getMenu().findItem(R.id.encryption_choice_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(); + } + break; default: break; @@ -344,13 +396,6 @@ public class ConversationActivity extends XmppActivity { @Override void onBackendConnected() { - - if (contactInserted) { - Log.d("xmppService","merge phone contacts with roster"); - contactInserted = false; - xmppConnectionService.mergePhoneContactsWithRoster(); - } - xmppConnectionService.setOnConversationListChangedListener(this.onConvChanged); if (conversationList.size()==0) { diff --git a/src/de/gultsch/chat/ui/ConversationFragment.java b/src/de/gultsch/chat/ui/ConversationFragment.java index 8ec511fc2..1f125ab07 100644 --- a/src/de/gultsch/chat/ui/ConversationFragment.java +++ b/src/de/gultsch/chat/ui/ConversationFragment.java @@ -1,15 +1,23 @@ package de.gultsch.chat.ui; import java.util.ArrayList; +import java.util.Hashtable; import java.util.List; +import java.util.Set; + +import net.java.otr4j.OtrException; +import net.java.otr4j.session.SessionStatus; import de.gultsch.chat.R; import de.gultsch.chat.entities.Contact; import de.gultsch.chat.entities.Conversation; import de.gultsch.chat.entities.Message; +import de.gultsch.chat.services.XmppConnectionService; import de.gultsch.chat.utils.PhoneHelper; import de.gultsch.chat.utils.UIHelper; +import android.app.AlertDialog; import android.app.Fragment; +import android.content.DialogInterface; import android.content.SharedPreferences; import android.graphics.Typeface; import android.net.Uri; @@ -21,23 +29,97 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; public class ConversationFragment extends Fragment { - + protected Conversation conversation; protected ListView messagesView; protected LayoutInflater inflater; protected List messageList = new ArrayList(); protected ArrayAdapter messageListAdapter; protected Contact contact; - + private EditText chatMsg; - private int nextMessageEncryption = Message.ENCRYPTION_NONE; - + + private OnClickListener sendMsgListener = new OnClickListener() { + + @Override + public void onClick(View v) { + ConversationActivity activity = (ConversationActivity) getActivity(); + final XmppConnectionService xmppService = activity.xmppConnectionService; + if (chatMsg.getText().length() < 1) + return; + final Message message = new Message(conversation, chatMsg.getText() + .toString(), conversation.nextMessageEncryption); + if (conversation.nextMessageEncryption == Message.ENCRYPTION_OTR) { + if (conversation.hasValidOtrSession()) { + activity.xmppConnectionService.sendMessage( + conversation.getAccount(), message, null); + chatMsg.setText(""); + } else { + Hashtable presences = conversation + .getContact().getPresences(); + if (presences.size() == 0) { + AlertDialog.Builder builder = new AlertDialog.Builder( + getActivity()); + builder.setTitle("Contact is offline"); + builder.setIconAttribute(android.R.attr.alertDialogIcon); + builder.setMessage("Sending OTR encrypted messages to an offline contact is impossible."); + builder.setPositiveButton("Send plain text", + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, + int which) { + conversation.nextMessageEncryption = Message.ENCRYPTION_NONE; + message.setEncryption(Message.ENCRYPTION_NONE); + xmppService.sendMessage( + conversation.getAccount(), + message, null); + chatMsg.setText(""); + } + }); + builder.setNegativeButton("Cancel", null); + builder.create().show(); + } else if (presences.size() == 1) { + xmppService.sendMessage(conversation.getAccount(), + message, + (String) presences.keySet().toArray()[0]); + chatMsg.setText(""); + } + } + } else { + xmppService.sendMessage(conversation.getAccount(), message, + null); + chatMsg.setText(""); + } + } + }; + + public void updateChatMsgHint() { + if (conversation.getMode() == Conversation.MODE_MULTI) { + chatMsg.setHint("Send message to conference"); + } else { + switch (conversation.nextMessageEncryption) { + case Message.ENCRYPTION_NONE: + chatMsg.setHint("Send plain text message"); + break; + case Message.ENCRYPTION_OTR: + chatMsg.setHint("Send OTR encrypted message"); + break; + case Message.ENCRYPTION_PGP: + chatMsg.setHint("Send openPGP encryted messeage"); + default: + break; + } + } + } + @Override public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -47,40 +129,32 @@ public class ConversationFragment extends Fragment { final View view = inflater.inflate(R.layout.fragment_conversation, container, false); chatMsg = (EditText) view.findViewById(R.id.textinput); - ((ImageButton) view.findViewById(R.id.textSendButton)) - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - ConversationActivity activity = (ConversationActivity) getActivity(); - if (chatMsg.getText().length() < 1) - return; - Message message = new Message(conversation, chatMsg - .getText().toString(), nextMessageEncryption); - activity.xmppConnectionService.sendMessage(conversation.getAccount(),message); - chatMsg.setText(""); - } - }); + ImageButton sendButton = (ImageButton) view + .findViewById(R.id.textSendButton); + sendButton.setOnClickListener(this.sendMsgListener); messagesView = (ListView) view.findViewById(R.id.messages_view); - + SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(getActivity().getApplicationContext()); - boolean showPhoneSelfContactPicture = sharedPref.getBoolean("show_phone_selfcontact_picture",true); - + .getDefaultSharedPreferences(getActivity() + .getApplicationContext()); + boolean showPhoneSelfContactPicture = sharedPref.getBoolean( + "show_phone_selfcontact_picture", true); + final Uri selfiUri; if (showPhoneSelfContactPicture) { - selfiUri = PhoneHelper.getSefliUri(getActivity()); + selfiUri = PhoneHelper.getSefliUri(getActivity()); } else { selfiUri = null; } - + messageListAdapter = new ArrayAdapter(this.getActivity() - .getApplicationContext(), R.layout.message_sent, this.messageList) { + .getApplicationContext(), R.layout.message_sent, + this.messageList) { private static final int SENT = 0; private static final int RECIEVED = 1; - + @Override public int getViewTypeCount() { return 2; @@ -111,32 +185,42 @@ public class ConversationFragment extends Fragment { break; } } - ImageView imageView = (ImageView) view.findViewById(R.id.message_photo); + ImageView imageView = (ImageView) view + .findViewById(R.id.message_photo); if (type == RECIEVED) { - if(item.getConversation().getMode()==Conversation.MODE_SINGLE) { + if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { Uri uri = item.getConversation().getProfilePhotoUri(); - if (uri!=null) { + if (uri != null) { imageView.setImageURI(uri); } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getConversation().getName(), 200)); + imageView.setImageBitmap(UIHelper + .getUnknownContactPicture(item + .getConversation().getName(), 200)); } - } else if (item.getConversation().getMode()==Conversation.MODE_MULTI) { - if (item.getCounterpart()!=null) { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getCounterpart(), 200)); + } else if (item.getConversation().getMode() == Conversation.MODE_MULTI) { + if (item.getCounterpart() != null) { + imageView.setImageBitmap(UIHelper + .getUnknownContactPicture( + item.getCounterpart(), 200)); } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getConversation().getName(), 200)); + imageView.setImageBitmap(UIHelper + .getUnknownContactPicture(item + .getConversation().getName(), 200)); } } } else { - if (selfiUri!=null) { + if (selfiUri != null) { imageView.setImageURI(selfiUri); } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(conversation.getAccount().getJid(),200)); + imageView.setImageBitmap(UIHelper + .getUnknownContactPicture(conversation + .getAccount().getJid(), 200)); } } - TextView messageBody = (TextView) view.findViewById(R.id.message_body); + TextView messageBody = (TextView) view + .findViewById(R.id.message_body); String body = item.getBody(); - if (body!=null) { + if (body != null) { messageBody.setText(body.trim()); } TextView time = (TextView) view.findViewById(R.id.message_time); @@ -144,13 +228,16 @@ public class ConversationFragment extends Fragment { time.setTypeface(null, Typeface.ITALIC); time.setText("sending\u2026"); } else { - time.setTypeface(null,Typeface.NORMAL); - if ((item.getConversation().getMode()==Conversation.MODE_SINGLE)||(type != RECIEVED)) { + time.setTypeface(null, Typeface.NORMAL); + if ((item.getConversation().getMode() == Conversation.MODE_SINGLE) + || (type != RECIEVED)) { time.setText(UIHelper.readableTimeDifference(item - .getTimeSent())); - } else { - time.setText(item.getCounterpart()+" \u00B7 "+UIHelper.readableTimeDifference(item .getTimeSent())); + } else { + time.setText(item.getCounterpart() + + " \u00B7 " + + UIHelper.readableTimeDifference(item + .getTimeSent())); } } return view; @@ -165,7 +252,7 @@ public class ConversationFragment extends Fragment { public void onStart() { super.onStart(); final ConversationActivity activity = (ConversationActivity) getActivity(); - + if (activity.xmppConnectionServiceBound) { this.conversation = activity.getSelectedConversation(); updateMessages(); @@ -182,7 +269,7 @@ public class ConversationFragment extends Fragment { } } } - + public void onBackendConnected() { final ConversationActivity activity = (ConversationActivity) getActivity(); this.conversation = activity.getSelectedConversation(); @@ -201,32 +288,50 @@ public class ConversationFragment extends Fragment { } public void updateMessages() { + ConversationActivity activity = (ConversationActivity) getActivity(); this.messageList.clear(); this.messageList.addAll(this.conversation.getMessages()); this.messageListAdapter.notifyDataSetChanged(); - if (messageList.size()>=1) { - nextMessageEncryption = this.conversation.getLatestMessage().getEncryption(); + if (messageList.size() >= 1) { + int latestEncryption = this.conversation.getLatestMessage() + .getEncryption(); + conversation.nextMessageEncryption = latestEncryption; + makeFingerprintWarning(latestEncryption); } getActivity().invalidateOptionsMenu(); - switch (nextMessageEncryption) { - case Message.ENCRYPTION_NONE: - chatMsg.setHint("Send plain text message"); - break; - case Message.ENCRYPTION_OTR: - chatMsg.setHint("Send OTR encrypted message"); - break; - case Message.ENCRYPTION_PGP: - chatMsg.setHint("Send openPGP encryted messeage"); - default: - break; - } + updateChatMsgHint(); int size = this.messageList.size(); if (size >= 1) messagesView.setSelection(size - 1); - ConversationActivity activity = (ConversationActivity) getActivity(); if (!activity.shouldPaneBeOpen()) { conversation.markRead(); activity.updateConversationList(); } } + + protected void makeFingerprintWarning(int latestEncryption) { + final LinearLayout fingerprintWarning = (LinearLayout) getView() + .findViewById(R.id.new_fingerprint); + Set knownFingerprints = conversation.getContact() + .getOtrFingerprints(); + if ((latestEncryption == Message.ENCRYPTION_OTR) + && (conversation.hasValidOtrSession() + && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints + .contains(conversation.getOtrFingerprint())))) { + fingerprintWarning.setVisibility(View.VISIBLE); + TextView fingerprint = (TextView) getView().findViewById( + R.id.otr_fingerprint); + fingerprint.setText(conversation.getOtrFingerprint()); + fingerprintWarning.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + AlertDialog dialog = UIHelper.getVerifyFingerprintDialog((ConversationActivity) getActivity(),conversation,fingerprintWarning); + dialog.show(); + } + }); + } else { + fingerprintWarning.setVisibility(View.GONE); + } + } } -- cgit v1.2.3