aboutsummaryrefslogtreecommitdiffstats
path: root/src/de/gultsch/chat/ui
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel.gultsch@rwth-aachen.de>2014-02-28 00:22:56 +0100
committerDaniel Gultsch <daniel.gultsch@rwth-aachen.de>2014-02-28 00:22:56 +0100
commit37d1a5380634471b11c828cf265d4a39e818a1c1 (patch)
treebbd6d58171beb79369c9c452098286591e6a6eae /src/de/gultsch/chat/ui
parentbfee69b00b2762a910f7f3f1714d18fddc99a9ad (diff)
basic pgp support.
Diffstat (limited to 'src/de/gultsch/chat/ui')
-rw-r--r--src/de/gultsch/chat/ui/ConversationActivity.java19
-rw-r--r--src/de/gultsch/chat/ui/ConversationFragment.java193
-rw-r--r--src/de/gultsch/chat/ui/DialogContactDetails.java2
-rw-r--r--src/de/gultsch/chat/ui/ManageAccountActivity.java30
4 files changed, 203 insertions, 41 deletions
diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java
index f9a924ecf..7fbc432e3 100644
--- a/src/de/gultsch/chat/ui/ConversationActivity.java
+++ b/src/de/gultsch/chat/ui/ConversationActivity.java
@@ -5,8 +5,13 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import org.openintents.openpgp.OpenPgpSignatureResult;
+import org.openintents.openpgp.util.OpenPgpConstants;
+
import de.gultsch.chat.R;
import de.gultsch.chat.R.id;
+import de.gultsch.chat.crypto.PgpEngine;
+import de.gultsch.chat.crypto.PgpEngine.UserInputRequiredException;
import de.gultsch.chat.entities.Account;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation;
@@ -20,6 +25,7 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentSender.SendIntentException;
import android.graphics.Typeface;
import android.support.v4.widget.SlidingPaneLayout;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
@@ -45,7 +51,8 @@ public class ConversationActivity extends XmppActivity {
public static final String VIEW_CONVERSATION = "viewConversation";
public static final String CONVERSATION = "conversationUuid";
- public static final int INSERT_CONTACT = 0x9889;
+ public static final int REQUEST_SEND_MESSAGE = 0x75441;
+ public static final int REQUEST_DECRYPT_PGP = 0x76783;
protected SlidingPaneLayout spl;
@@ -354,6 +361,9 @@ public class ConversationActivity extends XmppActivity {
case Message.ENCRYPTION_PGP:
popup.getMenu().findItem(R.id.encryption_choice_pgp).setChecked(true);
break;
+ case Message.ENCRYPTION_DECRYPTED:
+ popup.getMenu().findItem(R.id.encryption_choice_pgp).setChecked(true);
+ break;
default:
popup.getMenu().findItem(R.id.encryption_choice_none).setChecked(true);
break;
@@ -459,11 +469,4 @@ public class ConversationActivity extends XmppActivity {
}
}
}
-
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode==INSERT_CONTACT) {
- Log.d("xmppService","contact inserted");
- this.contactInserted = true;
- }
- }
}
diff --git a/src/de/gultsch/chat/ui/ConversationFragment.java b/src/de/gultsch/chat/ui/ConversationFragment.java
index b3a6ad774..099f22537 100644
--- a/src/de/gultsch/chat/ui/ConversationFragment.java
+++ b/src/de/gultsch/chat/ui/ConversationFragment.java
@@ -3,17 +3,16 @@ package de.gultsch.chat.ui;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Hashtable;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-import javax.crypto.spec.PSource;
-
-import net.java.otr4j.OtrException;
import net.java.otr4j.session.SessionStatus;
import de.gultsch.chat.R;
+import de.gultsch.chat.crypto.PgpEngine.OpenPgpException;
+import de.gultsch.chat.crypto.PgpEngine.UserInputRequiredException;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.entities.Message;
@@ -23,18 +22,20 @@ import de.gultsch.chat.utils.UIHelper;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
+import android.content.IntentSender;
import android.content.SharedPreferences;
+import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
@@ -42,6 +43,7 @@ import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.ProgressBar;
import android.widget.TextView;
public class ConversationFragment extends Fragment {
@@ -54,27 +56,45 @@ public class ConversationFragment extends Fragment {
protected Contact contact;
protected BitmapCache mBitmapCache = new BitmapCache();
+ protected String queuedPqpMessage = null;
+
private EditText chatMsg;
-
+
protected Bitmap selfBitmap;
+
+ private IntentSender askForPassphraseIntent = null;
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;
Message message = new Message(conversation, chatMsg.getText()
.toString(), conversation.nextMessageEncryption);
if (conversation.nextMessageEncryption == Message.ENCRYPTION_OTR) {
sendOtrMessage(message);
+ } else if (conversation.nextMessageEncryption == Message.ENCRYPTION_PGP) {
+ sendPgpMessage(message);
} else {
sendPlainTextMessage(message);
}
}
};
+ protected OnClickListener clickToDecryptListener = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Log.d("gultsch","clicked to decrypt");
+ if (askForPassphraseIntent!=null) {
+ try {
+ getActivity().startIntentSenderForResult(askForPassphraseIntent, ConversationActivity.REQUEST_DECRYPT_PGP, null, 0, 0, 0);
+ } catch (SendIntentException e) {
+ Log.d("gultsch","couldnt fire intent");
+ }
+ }
+ }
+ };
public void updateChatMsgHint() {
if (conversation.getMode() == Conversation.MODE_MULTI) {
@@ -89,6 +109,10 @@ public class ConversationFragment extends Fragment {
break;
case Message.ENCRYPTION_PGP:
chatMsg.setHint("Send openPGP encryted messeage");
+ break;
+ case Message.ENCRYPTION_DECRYPTED:
+ chatMsg.setHint("Send openPGP encryted messeage");
+ break;
default:
break;
}
@@ -107,9 +131,9 @@ public class ConversationFragment extends Fragment {
ImageButton sendButton = (ImageButton) view
.findViewById(R.id.textSendButton);
sendButton.setOnClickListener(this.sendMsgListener);
-
- messagesView = (ListView) view.findViewById(R.id.messages_view);
+ messagesView = (ListView) view.findViewById(R.id.messages_view);
+
messageListAdapter = new ArrayAdapter<Message>(this.getActivity()
.getApplicationContext(), R.layout.message_sent,
this.messageList) {
@@ -155,23 +179,28 @@ public class ConversationFragment extends Fragment {
viewHolder.imageView = (ImageView) view
.findViewById(R.id.message_photo);
if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
- Uri uri = item.getConversation().getProfilePhotoUri();
+ Uri uri = item.getConversation()
+ .getProfilePhotoUri();
if (uri != null) {
viewHolder.imageView
.setImageBitmap(mBitmapCache.get(item
- .getConversation().getName(), uri));
+ .getConversation().getName(),
+ uri));
} else {
viewHolder.imageView
.setImageBitmap(mBitmapCache.get(item
- .getConversation().getName(), null));
+ .getConversation().getName(),
+ null));
}
}
break;
case ERROR:
- view = (View) inflater.inflate(R.layout.message_error, null);
+ view = (View) inflater.inflate(R.layout.message_error,
+ null);
viewHolder.imageView = (ImageView) view
.findViewById(R.id.message_photo);
- viewHolder.imageView.setImageBitmap(mBitmapCache.getError());
+ viewHolder.imageView.setImageBitmap(mBitmapCache
+ .getError());
break;
default:
viewHolder = null;
@@ -186,7 +215,7 @@ public class ConversationFragment extends Fragment {
viewHolder = (ViewHolder) view.getTag();
}
if (type == RECIEVED) {
- if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
+ if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
if (item.getCounterpart() != null) {
viewHolder.imageView.setImageBitmap(mBitmapCache
.get(item.getCounterpart(), null));
@@ -199,7 +228,15 @@ public class ConversationFragment extends Fragment {
}
String body = item.getBody();
if (body != null) {
- viewHolder.messageBody.setText(body.trim());
+ if (item.getEncryption() == Message.ENCRYPTION_PGP) {
+ viewHolder.messageBody.setText(getString(R.string.encrypted_message));
+ viewHolder.messageBody.setTextColor(0xff33B5E5);
+ viewHolder.messageBody.setOnClickListener(clickToDecryptListener);
+ } else {
+ viewHolder.messageBody.setText(body.trim());
+ viewHolder.messageBody.setTextColor(0xff000000);
+ viewHolder.messageBody.setOnClickListener(null);
+ }
}
if (item.getStatus() == Message.STATUS_UNSEND) {
viewHolder.time.setTypeface(null, Typeface.ITALIC);
@@ -236,7 +273,7 @@ public class ConversationFragment extends Fragment {
if (showPhoneSelfContactPicture) {
Uri selfiUri = PhoneHelper.getSefliUri(getActivity());
- if (selfiUri!=null) {
+ if (selfiUri != null) {
try {
self = BitmapFactory.decodeStream(getActivity()
.getContentResolver().openInputStream(selfiUri));
@@ -245,7 +282,7 @@ public class ConversationFragment extends Fragment {
}
}
}
- if (self==null){
+ if (self == null) {
self = UIHelper.getUnknownContactPicture(conversation.getAccount()
.getJid(), 200);
}
@@ -280,17 +317,38 @@ public class ConversationFragment extends Fragment {
activity.updateConversationList();
}
}
+ if (queuedPqpMessage != null) {
+ this.conversation.nextMessageEncryption = Message.ENCRYPTION_PGP;
+ Message message = new Message(conversation, queuedPqpMessage,
+ Message.ENCRYPTION_PGP);
+ sendPgpMessage(message);
+ }
}
public void updateMessages() {
ConversationActivity activity = (ConversationActivity) getActivity();
+ List<Message> encryptedMessages = new LinkedList<Message>();
+ for(Message message : this.conversation.getMessages()) {
+ if (message.getEncryption() == Message.ENCRYPTION_PGP) {
+ encryptedMessages.add(message);
+ }
+ }
+ if (encryptedMessages.size() > 0) {
+ DecryptMessage task = new DecryptMessage();
+ Message[] msgs = new Message[encryptedMessages.size()];
+ task.execute(encryptedMessages.toArray(msgs));
+ }
this.messageList.clear();
this.messageList.addAll(this.conversation.getMessages());
this.messageListAdapter.notifyDataSetChanged();
if (messageList.size() >= 1) {
int latestEncryption = this.conversation.getLatestMessage()
.getEncryption();
- conversation.nextMessageEncryption = latestEncryption;
+ if (latestEncryption== Message.ENCRYPTION_DECRYPTED) {
+ conversation.nextMessageEncryption = Message.ENCRYPTION_PGP;
+ } else {
+ conversation.nextMessageEncryption = latestEncryption;
+ }
makeFingerprintWarning(latestEncryption);
}
getActivity().invalidateOptionsMenu();
@@ -339,17 +397,47 @@ public class ConversationFragment extends Fragment {
protected void sendPlainTextMessage(Message message) {
ConversationActivity activity = (ConversationActivity) getActivity();
- activity.xmppConnectionService.sendMessage(conversation.getAccount(),
- message, null);
+ activity.xmppConnectionService.sendMessage(message, null);
chatMsg.setText("");
}
+ protected void sendPgpMessage(final Message message) {
+ ConversationActivity activity = (ConversationActivity) getActivity();
+ final XmppConnectionService xmppService = activity.xmppConnectionService;
+ Contact contact = message.getConversation().getContact();
+ if (contact.getPgpKeyId() != 0) {
+ xmppService.sendMessage(message, null);
+ chatMsg.setText("");
+ } else {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle("No openPGP key found");
+ builder.setIconAttribute(android.R.attr.alertDialogIcon);
+ builder.setMessage("There is no openPGP key assoziated with this contact");
+ builder.setNegativeButton("Cancel", null);
+ 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(message, null);
+ chatMsg.setText("");
+ }
+ });
+ builder.create().show();
+ }
+ }
+
+ public void resendPgpMessage(String msg) {
+ this.queuedPqpMessage = msg;
+ }
+
protected void sendOtrMessage(final Message message) {
ConversationActivity activity = (ConversationActivity) getActivity();
final XmppConnectionService xmppService = activity.xmppConnectionService;
if (conversation.hasValidOtrSession()) {
- activity.xmppConnectionService.sendMessage(
- conversation.getAccount(), message, null);
+ activity.xmppConnectionService.sendMessage(message, null);
chatMsg.setText("");
} else {
Hashtable<String, Integer> presences;
@@ -372,17 +460,15 @@ public class ConversationFragment extends Fragment {
int which) {
conversation.nextMessageEncryption = Message.ENCRYPTION_NONE;
message.setEncryption(Message.ENCRYPTION_NONE);
- xmppService.sendMessage(
- conversation.getAccount(), message,
- null);
+ xmppService.sendMessage(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]);
+ xmppService.sendMessage(message, (String) presences.keySet()
+ .toArray()[0]);
chatMsg.setText("");
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(
@@ -396,8 +482,7 @@ public class ConversationFragment extends Fragment {
@Override
public void onClick(DialogInterface dialog,
int which) {
- xmppService.sendMessage(
- conversation.getAccount(), message,
+ xmppService.sendMessage(message,
presencesArray[which]);
chatMsg.setText("");
}
@@ -438,7 +523,7 @@ public class ConversationFragment extends Fragment {
return bm;
}
}
-
+
public Bitmap getError() {
if (error == null) {
error = UIHelper.getErrorPicture(200);
@@ -446,4 +531,48 @@ public class ConversationFragment extends Fragment {
return error;
}
}
+
+ class DecryptMessage extends AsyncTask<Message, Void, Boolean> {
+
+ @Override
+ protected Boolean doInBackground(Message... params) {
+ XmppActivity activity = (XmppActivity) getActivity();
+ askForPassphraseIntent = null;
+ for(int i = 0; i < params.length; ++i) {
+ if (params[i].getEncryption() == Message.ENCRYPTION_PGP) {
+ String body = params[i].getBody();
+ String decrypted = null;
+ try {
+ if (activity==null) {
+ return false;
+ }
+ Log.d("gultsch","calling to decrypt message id #"+params[i].getUuid());
+ decrypted = activity.xmppConnectionService.getPgpEngine().decrypt(body);
+ } catch (UserInputRequiredException e) {
+ askForPassphraseIntent = e.getPendingIntent().getIntentSender();
+ return false;
+
+ } catch (OpenPgpException e) {
+ Log.d("gultsch","error decrypting pgp");
+ }
+ if (decrypted!=null) {
+ params[i].setBody(decrypted);
+ params[i].setEncryption(Message.ENCRYPTION_DECRYPTED);
+ activity.xmppConnectionService.updateMessage(params[i]);
+ }
+ if (activity!=null) {
+ activity.runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ messageListAdapter.notifyDataSetChanged();
+ }
+ });
+ }
+ }
+ }
+ return true;
+ }
+
+ }
}
diff --git a/src/de/gultsch/chat/ui/DialogContactDetails.java b/src/de/gultsch/chat/ui/DialogContactDetails.java
index 8983a8730..324a7aacd 100644
--- a/src/de/gultsch/chat/ui/DialogContactDetails.java
+++ b/src/de/gultsch/chat/ui/DialogContactDetails.java
@@ -63,7 +63,7 @@ public class DialogContactDetails extends DialogFragment {
intent.putExtra(Intents.Insert.IM_HANDLE,contact.getJid());
intent.putExtra(Intents.Insert.IM_PROTOCOL,CommonDataKinds.Im.PROTOCOL_JABBER);
intent.putExtra("finishActivityOnSaveCompleted", true);
- getActivity().startActivityForResult(intent,ConversationActivity.INSERT_CONTACT);
+ getActivity().startActivityForResult(intent,0);
mDetailsDialog.dismiss();
}
};
diff --git a/src/de/gultsch/chat/ui/ManageAccountActivity.java b/src/de/gultsch/chat/ui/ManageAccountActivity.java
index 66a407820..bcc5306d8 100644
--- a/src/de/gultsch/chat/ui/ManageAccountActivity.java
+++ b/src/de/gultsch/chat/ui/ManageAccountActivity.java
@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import de.gultsch.chat.R;
+import de.gultsch.chat.crypto.PgpEngine;
+import de.gultsch.chat.crypto.PgpEngine.UserInputRequiredException;
import de.gultsch.chat.entities.Account;
import de.gultsch.chat.ui.EditAccount.EditAccountListener;
import android.app.Activity;
@@ -12,6 +14,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
+import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
@@ -31,6 +34,8 @@ import android.widget.TextView;
public class ManageAccountActivity extends XmppActivity implements ActionMode.Callback {
+ public static final int REQUEST_ANNOUNCE_PGP = 0x73731;
+
protected boolean isActionMode = false;
protected ActionMode actionMode;
protected Account selectedAccountForActionMode = null;
@@ -231,6 +236,17 @@ public class ManageAccountActivity extends XmppActivity implements ActionMode.Ca
});
builder.setNegativeButton("Cancel",null);
builder.create().show();
+ } else if (item.getItemId()==R.id.announce_pgp) {
+ mode.finish();
+ try {
+ xmppConnectionService.generatePgpAnnouncement(selectedAccountForActionMode);
+ } catch (PgpEngine.UserInputRequiredException e) {
+ try {
+ startIntentSenderForResult(e.getPendingIntent().getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
+ } catch (SendIntentException e1) {
+ Log.d("gultsch","sending intent failed");
+ }
+ }
}
return true;
}
@@ -279,4 +295,18 @@ public class ManageAccountActivity extends XmppActivity implements ActionMode.Ca
}
});
}
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (resultCode == RESULT_OK) {
+ if (requestCode == REQUEST_ANNOUNCE_PGP) {
+ try {
+ xmppConnectionService.generatePgpAnnouncement(selectedAccountForActionMode);
+ } catch (UserInputRequiredException e) {
+ Log.d("gultsch","already came back. ignoring");
+ }
+ }
+ }
+ }
}