aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu/siacs/conversations/utils')
-rw-r--r--src/eu/siacs/conversations/utils/DNSHelper.java93
-rw-r--r--src/eu/siacs/conversations/utils/MessageParser.java149
-rw-r--r--src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java9
-rw-r--r--src/eu/siacs/conversations/utils/PhoneHelper.java87
-rw-r--r--src/eu/siacs/conversations/utils/SASL.java24
-rw-r--r--src/eu/siacs/conversations/utils/UIHelper.java210
-rw-r--r--src/eu/siacs/conversations/utils/Validator.java14
7 files changed, 586 insertions, 0 deletions
diff --git a/src/eu/siacs/conversations/utils/DNSHelper.java b/src/eu/siacs/conversations/utils/DNSHelper.java
new file mode 100644
index 000000000..46fd69286
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/DNSHelper.java
@@ -0,0 +1,93 @@
+package eu.siacs.conversations.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.util.Random;
+
+import android.os.Bundle;
+import android.util.Log;
+
+public class DNSHelper {
+ public static Bundle getSRVRecord(String host) {
+ Bundle namePort = new Bundle();
+ try {
+ String[] hostParts = host.split("\\.");
+ byte[] transId = new byte[2];
+ Random random = new Random();
+ random.nextBytes(transId);
+ byte[] header = { 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70 };
+ byte[] rest = { 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x29,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ output.write(transId);
+ output.write(header);
+ for (int i = 0; i < hostParts.length; ++i) {
+ char[] tmpChars = hostParts[i].toCharArray();
+ byte[] tmp = new byte[tmpChars.length];
+ for (int j = 0; j < tmpChars.length; ++j) {
+ tmp[j] = (byte) tmpChars[j];
+ }
+ output.write(tmp.length);
+ output.write(tmp);
+ }
+ output.write(rest);
+ byte[] sendPaket = output.toByteArray();
+ byte[] addr = { 0x8, 0x8, 0x8, 0x8 };
+ int realLenght = sendPaket.length - 11;
+ DatagramPacket packet = new DatagramPacket(sendPaket,
+ sendPaket.length, InetAddress.getByAddress(addr), 53);
+ DatagramSocket datagramSocket = new DatagramSocket();
+ datagramSocket.send(packet);
+ byte[] receiveData = new byte[1024];
+
+ DatagramPacket receivePacket = new DatagramPacket(receiveData,
+ receiveData.length);
+ datagramSocket.setSoTimeout(2000);
+ datagramSocket.receive(receivePacket);
+ if (receiveData[3]!=-128) {
+ namePort.putString("error", "nosrv");
+ return namePort;
+ }
+ namePort.putInt("port",calcPort(receiveData[realLenght + 16],
+ receiveData[realLenght + 17]));
+ int i = realLenght + 18;
+ int wordLenght = 0;
+ StringBuilder builder = new StringBuilder();
+ while (receiveData[i] != 0) {
+ if (wordLenght > 0) {
+ builder.append((char) receiveData[i]);
+ --wordLenght;
+ } else {
+ wordLenght = receiveData[i];
+ builder.append(".");
+ }
+ ++i;
+ }
+ builder.replace(0, 1, "");
+ namePort.putString("name",builder.toString());
+ } catch (IOException e) {
+ Log.d("xmppService","gut" + e.getMessage());
+ }
+ return namePort;
+ }
+
+ static int calcPort(byte hb, byte lb) {
+ return ((int) hb << 8) | ((int) lb & 0xFF);
+ }
+
+ 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/src/eu/siacs/conversations/utils/MessageParser.java b/src/eu/siacs/conversations/utils/MessageParser.java
new file mode 100644
index 000000000..dc0cd35cf
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/MessageParser.java
@@ -0,0 +1,149 @@
+package eu.siacs.conversations.utils;
+
+import java.util.List;
+
+import net.java.otr4j.session.Session;
+import net.java.otr4j.session.SessionStatus;
+import android.util.Log;
+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.MessagePacket;
+
+public class MessageParser {
+
+ protected static final String LOGTAG = "xmppService";
+
+ public static Message parsePlainTextChat(MessagePacket packet, Account account, XmppConnectionService service) {
+ String[] fromParts = packet.getFrom().split("/");
+ Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false);
+ String body = packet.getBody();
+ return new Message(conversation, packet.getFrom(), body, Message.ENCRYPTION_NONE, Message.STATUS_RECIEVED);
+ }
+
+ public static Message parsePgpChat(String pgpBody, MessagePacket packet, Account account, XmppConnectionService service) {
+ String[] fromParts = packet.getFrom().split("/");
+ Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false);
+ return new Message(conversation, packet.getFrom(), pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECIEVED);
+ }
+
+ public static Message parseOtrChat(MessagePacket packet, Account account, XmppConnectionService service) {
+ String[] fromParts = packet.getFrom().split("/");
+ Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false);
+ String body = packet.getBody();
+ if (!conversation.hasValidOtrSession()) {
+ conversation.startOtrSession(service.getApplicationContext(), fromParts[1]);
+ }
+ try {
+ Session otrSession = conversation.getOtrSession();
+ SessionStatus before = otrSession
+ .getSessionStatus();
+ body = otrSession.transformReceiving(body);
+ SessionStatus after = otrSession.getSessionStatus();
+ if ((before != after)
+ && (after == SessionStatus.ENCRYPTED)) {
+ Log.d(LOGTAG, "otr session etablished");
+ List<Message> messages = conversation
+ .getMessages();
+ for (int i = 0; i < messages.size(); ++i) {
+ Message msg = messages.get(i);
+ if ((msg.getStatus() == Message.STATUS_UNSEND)
+ && (msg.getEncryption() == Message.ENCRYPTION_OTR)) {
+ MessagePacket outPacket = service.prepareMessagePacket(
+ account, msg, otrSession);
+ msg.setStatus(Message.STATUS_SEND);
+ service.databaseBackend.updateMessage(msg);
+ account.getXmppConnection()
+ .sendMessagePacket(outPacket);
+ }
+ }
+ if (service.convChangedListener!=null) {
+ service.convChangedListener.onConversationListChanged();
+ }
+ } else if ((before != after) && (after == SessionStatus.FINISHED)) {
+ conversation.resetOtrSession();
+ Log.d(LOGTAG,"otr session stoped");
+ }
+ } catch (Exception e) {
+ Log.d(LOGTAG, "error receiving otr. resetting");
+ conversation.resetOtrSession();
+ return null;
+ }
+ if (body == null) {
+ return null;
+ }
+ return new Message(conversation, packet.getFrom(), body, Message.ENCRYPTION_OTR,Message.STATUS_RECIEVED);
+ }
+
+ public static Message parseGroupchat(MessagePacket packet, Account account, XmppConnectionService service) {
+ int status;
+ String[] fromParts = packet.getFrom().split("/");
+ Conversation conversation = service.findOrCreateConversation(account, fromParts[0],true);
+ if ((fromParts.length == 1) || (packet.hasChild("subject"))) {
+ return null;
+ }
+ String counterPart = fromParts[1];
+ if (counterPart.equals(account.getUsername())) {
+ status = Message.STATUS_SEND;
+ } else {
+ status = Message.STATUS_RECIEVED;
+ }
+ return new Message(conversation, counterPart, packet.getBody(), Message.ENCRYPTION_NONE, status);
+ }
+
+ public static Message parseCarbonMessage(MessagePacket packet,
+ Account account, XmppConnectionService service) {
+ // TODO Auto-generated method stub
+ int status;
+ String fullJid;
+ Element forwarded;
+ if (packet.hasChild("received")) {
+ forwarded = packet.findChild("received").findChild(
+ "forwarded");
+ status = Message.STATUS_RECIEVED;
+ } else if (packet.hasChild("sent")) {
+ forwarded = packet.findChild("sent").findChild(
+ "forwarded");
+ status = Message.STATUS_SEND;
+ } else {
+ return null;
+ }
+ Element message = forwarded.findChild("message");
+ if ((message == null) || (!message.hasChild("body")))
+ return null; // either malformed or boring
+ if (status == Message.STATUS_RECIEVED) {
+ fullJid = message.getAttribute("from");
+ } else {
+ fullJid = message.getAttribute("to");
+ }
+ String[] parts = fullJid.split("/");
+ Conversation conversation = service.findOrCreateConversation(account, parts[0],false);
+ return new Message(conversation,fullJid, message.findChild("body").getContent(), Message.ENCRYPTION_NONE,status);
+ }
+
+ public static Message parseError(MessagePacket packet, Account account, XmppConnectionService service) {
+
+ String[] fromParts = packet.getFrom().split("/");
+ Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false);
+ Element error = packet.findChild("error");
+ String errorName = error.getChildren().get(0).getName();
+ String displayError;
+ if (errorName.equals("service-unavailable")) {
+ displayError = "Contact is offline and does not have offline storage";
+ } else {
+ displayError = errorName.replace("-", " ");
+ }
+ return new Message(conversation, packet.getFrom(), displayError, Message.ENCRYPTION_NONE, Message.STATUS_ERROR);
+ }
+
+ public static String getPgpBody(MessagePacket packet) {
+ for(Element child : packet.getChildren()) {
+ if (child.getName().equals("x")&&child.getAttribute("xmlns").equals("jabber:x:encrypted")) {
+ return child.getContent();
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java b/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java
new file mode 100644
index 000000000..fa8cea04c
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java
@@ -0,0 +1,9 @@
+package eu.siacs.conversations.utils;
+
+import java.util.Hashtable;
+
+import android.os.Bundle;
+
+public interface OnPhoneContactsLoadedListener {
+ public void onPhoneContactsLoaded(Hashtable<String, Bundle> phoneContacts);
+}
diff --git a/src/eu/siacs/conversations/utils/PhoneHelper.java b/src/eu/siacs/conversations/utils/PhoneHelper.java
new file mode 100644
index 000000000..e28f817e7
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/PhoneHelper.java
@@ -0,0 +1,87 @@
+package eu.siacs.conversations.utils;
+
+import java.util.Hashtable;
+
+import android.app.Activity;
+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.os.Looper;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Profile;
+
+public class PhoneHelper {
+
+ public static void loadPhoneContacts(Context context, final OnPhoneContactsLoadedListener listener) {
+ if (Looper.myLooper()==null) {
+ Looper.prepare();
+ }
+ final Looper mLooper = Looper.myLooper();
+ final Hashtable<String, Bundle> phoneContacts = new Hashtable<String, Bundle>();
+
+ final String[] PROJECTION = new String[] {
+ ContactsContract.Data._ID,
+ ContactsContract.Data.DISPLAY_NAME,
+ ContactsContract.Data.PHOTO_THUMBNAIL_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<Cursor>() {
+
+ @Override
+ public void onLoadComplete(Loader<Cursor> arg0, Cursor cursor) {
+ 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_THUMBNAIL_URI)));
+ contact.putString("lookup",cursor.getString(cursor
+ .getColumnIndex(ContactsContract.Data.LOOKUP_KEY)));
+ phoneContacts.put(
+ cursor.getString(cursor
+ .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)),
+ contact);
+ }
+ if (listener!=null) {
+ listener.onPhoneContactsLoaded(phoneContacts);
+ }
+ mLooper.quit();
+ }
+ });
+ mCursorLoader.startLoading();
+ }
+
+ public static Uri getSefliUri(Activity activity) {
+ String[] mProjection = new String[] { Profile._ID,
+ Profile.PHOTO_THUMBNAIL_URI };
+ Cursor mProfileCursor = activity.getContentResolver().query(
+ Profile.CONTENT_URI, mProjection, null, null, null);
+
+ if (mProfileCursor.getCount()==0) {
+ return null;
+ } else {
+ mProfileCursor.moveToFirst();
+ return Uri.parse(mProfileCursor.getString(1));
+ }
+ }
+}
diff --git a/src/eu/siacs/conversations/utils/SASL.java b/src/eu/siacs/conversations/utils/SASL.java
new file mode 100644
index 000000000..cda1f97be
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/SASL.java
@@ -0,0 +1,24 @@
+package eu.siacs.conversations.utils;
+
+import android.util.Base64;
+
+public class SASL {
+ public static String plain(String username, String password) {
+ byte[] userBytes = username.getBytes();
+ int userLenght = userBytes.length;
+ byte[] passwordBytes = password.getBytes();
+ byte[] saslBytes = new byte[userBytes.length+passwordBytes.length+2];
+ saslBytes[0] = 0x0;
+ for(int i = 1; i < saslBytes.length; ++i) {
+ if (i<=userLenght) {
+ saslBytes[i] = userBytes[i-1];
+ } else if (i==userLenght+1) {
+ saslBytes[i] = 0x0;
+ } else {
+ saslBytes[i] = passwordBytes[i-(userLenght+2)];
+ }
+ }
+
+ return Base64.encodeToString(saslBytes, Base64.DEFAULT);
+ }
+}
diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java
new file mode 100644
index 000000000..f79fe14cf
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/UIHelper.java
@@ -0,0 +1,210 @@
+package eu.siacs.conversations.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+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.ui.ConversationActivity;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.provider.ContactsContract.Contacts;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.TaskStackBuilder;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.QuickContactBadge;
+import android.widget.TextView;
+
+public class UIHelper {
+ public static String readableTimeDifference(long time) {
+ if (time == 0) {
+ return "just now";
+ }
+ Date date = new Date(time);
+ long difference = (System.currentTimeMillis() - time) / 1000;
+ if (difference < 60) {
+ return "just now";
+ } else if (difference < 60 * 10) {
+ return difference / 60 + " min ago";
+ } else if (difference < 60 * 60 * 24) {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+ return sdf.format(date);
+ } else {
+ SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
+ return sdf.format(date);
+ }
+ }
+
+ public static Bitmap getUnknownContactPicture(String name, int size) {
+ String firstLetter = name.substring(0, 1).toUpperCase();
+
+ int holoColors[] = { 0xFF1da9da, 0xFFb368d9, 0xFF83b600, 0xFFffa713,
+ 0xFFe92727 };
+
+ int color = holoColors[Math.abs(name.hashCode()) % holoColors.length];
+
+ Bitmap bitmap = Bitmap
+ .createBitmap(size, size, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+
+ bitmap.eraseColor(color);
+
+ Paint paint = new Paint();
+ paint.setColor(0xffe5e5e5);
+ paint.setTextSize((float) (size * 0.9));
+ paint.setAntiAlias(true);
+ Rect rect = new Rect();
+ paint.getTextBounds(firstLetter, 0, 1, rect);
+ float width = paint.measureText(firstLetter);
+ canvas.drawText(firstLetter, (size / 2) - (width / 2), (size / 2)
+ + (rect.height() / 2), paint);
+
+ return bitmap;
+ }
+
+ public static Bitmap getErrorPicture(int size) {
+ Bitmap bitmap = Bitmap
+ .createBitmap(size, size, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+
+ bitmap.eraseColor(0xFFe92727);
+
+ Paint paint = new Paint();
+ paint.setColor(0xffe5e5e5);
+ paint.setTextSize((float) (size * 0.9));
+ paint.setAntiAlias(true);
+ Rect rect = new Rect();
+ paint.getTextBounds("!", 0, 1, rect);
+ float width = paint.measureText("!");
+ canvas.drawText("!", (size / 2) - (width / 2), (size / 2)
+ + (rect.height() / 2), paint);
+
+ return bitmap;
+ }
+
+ public static Notification getUnreadMessageNotification(Context context,
+ Conversation conversation) {
+
+ SharedPreferences sharedPref = PreferenceManager
+ .getDefaultSharedPreferences(context);
+ String ringtone = sharedPref.getString("notification_ringtone", null);
+
+ Resources res = context.getResources();
+ NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
+ context);
+ mBuilder.setLargeIcon(UIHelper.getUnknownContactPicture(conversation
+ .getName(), (int) res
+ .getDimension(android.R.dimen.notification_large_icon_width)));
+ mBuilder.setContentTitle(conversation.getName());
+ mBuilder.setTicker(conversation.getLatestMessage().getBody().trim());
+ StringBuilder bigText = new StringBuilder();
+ List<Message> messages = conversation.getMessages();
+ String firstLine = "";
+ for(int i = messages.size() -1; i >= 0; --i) {
+ if (!messages.get(i).isRead()) {
+ if (i == messages.size() -1 ) {
+ firstLine = messages.get(i).getBody().trim();
+ bigText.append(firstLine);
+ } else {
+ firstLine = messages.get(i).getBody().trim();
+ bigText.insert(0, firstLine+"\n");
+ }
+ } else {
+ break;
+ }
+ }
+ mBuilder.setContentText(firstLine);
+ mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText.toString()));
+ mBuilder.setSmallIcon(R.drawable.notification);
+ mBuilder.setLights(0xffffffff, 2000, 4000);
+ if (ringtone != null) {
+ mBuilder.setSound(Uri.parse(ringtone));
+ }
+
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
+ stackBuilder.addParentStack(ConversationActivity.class);
+
+ Intent viewConversationIntent = new Intent(context,
+ ConversationActivity.class);
+ viewConversationIntent.setAction(Intent.ACTION_VIEW);
+ viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
+ conversation.getUuid());
+ viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
+
+ stackBuilder.addNextIntent(viewConversationIntent);
+
+ PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ mBuilder.setContentIntent(resultPendingIntent);
+ return mBuilder.build();
+ }
+
+ public static void prepareContactBadge(final Activity activity,
+ QuickContactBadge badge, final Contact contact) {
+ if (contact.getSystemAccount()!=null) {
+ String[] systemAccount = contact.getSystemAccount().split("#");
+ long id = Long.parseLong(systemAccount[0]);
+ badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1]));
+
+ if (contact.getProfilePhoto() != null) {
+ badge.setImageURI(Uri.parse(contact.getProfilePhoto()));
+ } else {
+ badge.setImageBitmap(UIHelper.getUnknownContactPicture(contact.getDisplayName(), 400));
+ }
+ } else {
+ badge.setImageBitmap(UIHelper.getUnknownContactPicture(contact.getDisplayName(), 400));
+ }
+
+ }
+
+ public static AlertDialog getVerifyFingerprintDialog(final ConversationActivity activity,final Conversation conversation, final LinearLayout 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.updateContact(contact);
+ }
+ });
+ builder.setView(view);
+ return builder.create();
+ }
+}
diff --git a/src/eu/siacs/conversations/utils/Validator.java b/src/eu/siacs/conversations/utils/Validator.java
new file mode 100644
index 000000000..fce953aef
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/Validator.java
@@ -0,0 +1,14 @@
+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("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE);
+
+ public static boolean isValidJid(String jid) {
+ Matcher matcher = VALID_JID.matcher(jid);
+ return matcher.find();
+ }
+}