more code cleanup for xmpp parser. more eventy. nice unknown contact pictures
This commit is contained in:
		
							parent
							
								
									c3e4f0eaac
								
							
						
					
					
						commit
						43531113b7
					
				| 
						 | 
					@ -34,8 +34,7 @@ public final class R {
 | 
				
			||||||
        public static final int ic_launcher=0x7f020006;
 | 
					        public static final int ic_launcher=0x7f020006;
 | 
				
			||||||
        public static final int ic_profile=0x7f020007;
 | 
					        public static final int ic_profile=0x7f020007;
 | 
				
			||||||
        public static final int message_border=0x7f020008;
 | 
					        public static final int message_border=0x7f020008;
 | 
				
			||||||
        public static final int profilemock=0x7f020009;
 | 
					        public static final int section_header=0x7f020009;
 | 
				
			||||||
        public static final int section_header=0x7f02000a;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public static final class id {
 | 
					    public static final class id {
 | 
				
			||||||
        public static final int account_confirm_password_desc=0x7f0a0011;
 | 
					        public static final int account_confirm_password_desc=0x7f0a0011;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 16 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 12 KiB  | 
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					 | 
				
			||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
 | 
					 | 
				
			||||||
<gradient
 | 
					 | 
				
			||||||
    android:centerColor="#8B0000"
 | 
					 | 
				
			||||||
    android:endColor="#34FFDD"
 | 
					 | 
				
			||||||
    android:startColor="#FF00FF" />
 | 
					 | 
				
			||||||
<size android:width="5.0dp" android:height="0.5dp" />
 | 
					 | 
				
			||||||
</shape>
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					 | 
				
			||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
 | 
					 | 
				
			||||||
<gradient
 | 
					 | 
				
			||||||
    android:centerColor="#8B0000"
 | 
					 | 
				
			||||||
    android:endColor="#34FFDD"
 | 
					 | 
				
			||||||
    android:startColor="#FF00FF" />
 | 
					 | 
				
			||||||
<size android:width="5.0dp" android:height="0.5dp" />
 | 
					 | 
				
			||||||
</shape>
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					 | 
				
			||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
 | 
					 | 
				
			||||||
<gradient
 | 
					 | 
				
			||||||
    android:centerColor="#8B0000"
 | 
					 | 
				
			||||||
    android:endColor="#34FFDD"
 | 
					 | 
				
			||||||
    android:startColor="#FF00FF" />
 | 
					 | 
				
			||||||
<size android:width="5.0dp" android:height="0.5dp" />
 | 
					 | 
				
			||||||
</shape>
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,6 @@
 | 
				
			||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
 | 
					<shape xmlns:android="http://schemas.android.com/apk/res/android" >
 | 
				
			||||||
<gradient
 | 
					<gradient
 | 
				
			||||||
    android:endColor="#cccccc"
 | 
					    android:endColor="#cccccc"
 | 
				
			||||||
    android:startColor="#f9f9f9" />
 | 
					    android:startColor="#eeeeee" />
 | 
				
			||||||
<size android:width="3.0dp" android:height="0.5dp" />
 | 
					<size android:width="3.0dp" android:height="0.5dp" />
 | 
				
			||||||
</shape>
 | 
					</shape>
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,9 @@
 | 
				
			||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
					<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
    android:layout_width="336dp"
 | 
					    android:layout_width="336dp"
 | 
				
			||||||
    android:layout_height="match_parent"
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
    android:orientation="vertical">
 | 
					    android:orientation="vertical"
 | 
				
			||||||
 | 
					    android:background="#eeeeee"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    <ListView
 | 
					    <ListView
 | 
				
			||||||
        android:id="@+id/list"
 | 
					        android:id="@+id/list"
 | 
				
			||||||
| 
						 | 
					@ -14,7 +16,7 @@
 | 
				
			||||||
        android:layout_height="wrap_content"
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
        android:divider="#b5b5b5"
 | 
					        android:divider="#b5b5b5"
 | 
				
			||||||
        android:dividerHeight="1dp"
 | 
					        android:dividerHeight="1dp"
 | 
				
			||||||
        android:background="#f9f9f9"
 | 
					        android:background="#eeeeee"
 | 
				
			||||||
     />
 | 
					     />
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
</LinearLayout>
 | 
					</LinearLayout>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,9 +20,8 @@ public class Contact implements Serializable {
 | 
				
			||||||
		return this.display_name;
 | 
							return this.display_name;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Uri getProfilePhoto() {
 | 
						public String getProfilePhoto() {
 | 
				
			||||||
		if (photo == null) return null;
 | 
							return photo;
 | 
				
			||||||
		return Uri.parse(photo);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public String getJid() {
 | 
						public String getJid() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,10 +33,9 @@ public class Conversation extends AbstractEntity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private transient List<Message> messages = null;
 | 
						private transient List<Message> messages = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Conversation(String name, Uri profilePhoto, Account account,
 | 
						public Conversation(String name, String profilePhoto, Account account,
 | 
				
			||||||
			String contactJid) {
 | 
								String contactJid) {
 | 
				
			||||||
		this(java.util.UUID.randomUUID().toString(), name, profilePhoto
 | 
							this(java.util.UUID.randomUUID().toString(), name, profilePhoto, account.getUuid(), contactJid, System
 | 
				
			||||||
				.toString(), account.getUuid(), contactJid, System
 | 
					 | 
				
			||||||
				.currentTimeMillis(), STATUS_AVAILABLE);
 | 
									.currentTimeMillis(), STATUS_AVAILABLE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ import de.gultsch.chat.R;
 | 
				
			||||||
import de.gultsch.chat.R.id;
 | 
					import de.gultsch.chat.R.id;
 | 
				
			||||||
import de.gultsch.chat.entities.Conversation;
 | 
					import de.gultsch.chat.entities.Conversation;
 | 
				
			||||||
import de.gultsch.chat.utils.Beautifier;
 | 
					import de.gultsch.chat.utils.Beautifier;
 | 
				
			||||||
 | 
					import android.net.Uri;
 | 
				
			||||||
import android.os.Bundle;
 | 
					import android.os.Bundle;
 | 
				
			||||||
import android.app.FragmentTransaction;
 | 
					import android.app.FragmentTransaction;
 | 
				
			||||||
import android.content.Context;
 | 
					import android.content.Context;
 | 
				
			||||||
| 
						 | 
					@ -106,6 +107,16 @@ public class ConversationActivity extends XmppActivity {
 | 
				
			||||||
				((TextView) view.findViewById(R.id.conversation_lastmsg)).setText(getItem(position).getLatestMessage());
 | 
									((TextView) view.findViewById(R.id.conversation_lastmsg)).setText(getItem(position).getLatestMessage());
 | 
				
			||||||
				((TextView) view.findViewById(R.id.conversation_lastupdate))
 | 
									((TextView) view.findViewById(R.id.conversation_lastupdate))
 | 
				
			||||||
				.setText(Beautifier.readableTimeDifference(getItem(position).getLatestMessageDate()));
 | 
									.setText(Beautifier.readableTimeDifference(getItem(position).getLatestMessageDate()));
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									Uri profilePhoto = getItem(position).getProfilePhotoUri();
 | 
				
			||||||
 | 
									ImageView imageView = (ImageView) view.findViewById(R.id.conversation_image);
 | 
				
			||||||
 | 
									if (profilePhoto!=null) {
 | 
				
			||||||
 | 
										imageView.setImageURI(profilePhoto);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										imageView.setImageBitmap(Beautifier.getUnknownContactPicture(getItem(position).getName(),200));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									
 | 
				
			||||||
				((ImageView) view.findViewById(R.id.conversation_image))
 | 
									((ImageView) view.findViewById(R.id.conversation_image))
 | 
				
			||||||
						.setImageURI(getItem(position).getProfilePhotoUri());
 | 
											.setImageURI(getItem(position).getProfilePhotoUri());
 | 
				
			||||||
				return view;
 | 
									return view;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,9 @@ import de.gultsch.chat.R;
 | 
				
			||||||
import de.gultsch.chat.entities.Account;
 | 
					import de.gultsch.chat.entities.Account;
 | 
				
			||||||
import de.gultsch.chat.entities.Contact;
 | 
					import de.gultsch.chat.entities.Contact;
 | 
				
			||||||
import de.gultsch.chat.entities.Conversation;
 | 
					import de.gultsch.chat.entities.Conversation;
 | 
				
			||||||
 | 
					import de.gultsch.chat.utils.Beautifier;
 | 
				
			||||||
import de.gultsch.chat.utils.Validator;
 | 
					import de.gultsch.chat.utils.Validator;
 | 
				
			||||||
 | 
					import android.net.Uri;
 | 
				
			||||||
import android.os.Bundle;
 | 
					import android.os.Bundle;
 | 
				
			||||||
import android.provider.ContactsContract;
 | 
					import android.provider.ContactsContract;
 | 
				
			||||||
import android.text.Editable;
 | 
					import android.text.Editable;
 | 
				
			||||||
| 
						 | 
					@ -74,8 +76,7 @@ public class NewConversationActivity extends XmppActivity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (Validator.isValidJid(searchString)) {
 | 
								if (Validator.isValidJid(searchString)) {
 | 
				
			||||||
				String name = searchString.split("@")[0];
 | 
									String name = searchString.split("@")[0];
 | 
				
			||||||
				Contact newContact = new Contact(name, searchString,
 | 
									Contact newContact = new Contact(name, searchString,null);
 | 
				
			||||||
						DEFAULT_PROFILE_PHOTO);
 | 
					 | 
				
			||||||
				aggregatedContacts.add(newContact);
 | 
									aggregatedContacts.add(newContact);
 | 
				
			||||||
				contactsHeader.setText("Create new contact");
 | 
									contactsHeader.setText("Create new contact");
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
| 
						 | 
					@ -100,8 +101,6 @@ public class NewConversationActivity extends XmppActivity {
 | 
				
			||||||
			+ "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL
 | 
								+ "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL
 | 
				
			||||||
			+ "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER
 | 
								+ "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER
 | 
				
			||||||
			+ "\")";
 | 
								+ "\")";
 | 
				
			||||||
	protected static final String DEFAULT_PROFILE_PHOTO = "android.resource://de.gultsch.chat/"
 | 
					 | 
				
			||||||
			+ R.drawable.ic_profile;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	protected void onCreate(Bundle savedInstanceState) {
 | 
						protected void onCreate(Bundle savedInstanceState) {
 | 
				
			||||||
| 
						 | 
					@ -150,8 +149,13 @@ public class NewConversationActivity extends XmppActivity {
 | 
				
			||||||
						.setText(getItem(position).getDisplayName());
 | 
											.setText(getItem(position).getDisplayName());
 | 
				
			||||||
				((TextView) view.findViewById(R.id.contact_jid))
 | 
									((TextView) view.findViewById(R.id.contact_jid))
 | 
				
			||||||
						.setText(getItem(position).getJid());
 | 
											.setText(getItem(position).getJid());
 | 
				
			||||||
				((ImageView) view.findViewById(R.id.contact_photo))
 | 
									String profilePhoto = getItem(position).getProfilePhoto();
 | 
				
			||||||
						.setImageURI(getItem(position).getProfilePhoto());
 | 
									ImageView imageView = (ImageView) view.findViewById(R.id.contact_photo);
 | 
				
			||||||
 | 
									if (profilePhoto!=null) {
 | 
				
			||||||
 | 
										imageView.setImageURI(Uri.parse(profilePhoto));
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										imageView.setImageBitmap(Beautifier.getUnknownContactPicture(getItem(position).getDisplayName(),90));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return view;
 | 
									return view;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					@ -222,9 +226,9 @@ public class NewConversationActivity extends XmppActivity {
 | 
				
			||||||
				while (cursor.moveToNext()) {
 | 
									while (cursor.moveToNext()) {
 | 
				
			||||||
					String profilePhoto = cursor.getString(cursor
 | 
										String profilePhoto = cursor.getString(cursor
 | 
				
			||||||
							.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI));
 | 
												.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI));
 | 
				
			||||||
					if (profilePhoto == null) {
 | 
										/*if (profilePhoto == null) {
 | 
				
			||||||
						profilePhoto = DEFAULT_PROFILE_PHOTO;
 | 
											profilePhoto = DEFAULT_PROFILE_PHOTO;
 | 
				
			||||||
					}
 | 
										}*/
 | 
				
			||||||
					Contact contact = new Contact(
 | 
										Contact contact = new Contact(
 | 
				
			||||||
							cursor.getString(cursor
 | 
												cursor.getString(cursor
 | 
				
			||||||
									.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)),
 | 
														.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,18 +3,24 @@ package de.gultsch.chat.utils;
 | 
				
			||||||
import java.text.SimpleDateFormat;
 | 
					import java.text.SimpleDateFormat;
 | 
				
			||||||
import java.util.Date;
 | 
					import java.util.Date;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.graphics.Bitmap;
 | 
				
			||||||
 | 
					import android.graphics.Canvas;
 | 
				
			||||||
 | 
					import android.graphics.Paint;
 | 
				
			||||||
 | 
					import android.graphics.Rect;
 | 
				
			||||||
 | 
					import android.util.DisplayMetrics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Beautifier {
 | 
					public class Beautifier {
 | 
				
			||||||
	public static String readableTimeDifference(long time) {
 | 
						public static String readableTimeDifference(long time) {
 | 
				
			||||||
		if (time==0) {
 | 
							if (time == 0) {
 | 
				
			||||||
			return "just now";
 | 
								return "just now";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Date date = new Date(time);
 | 
							Date date = new Date(time);
 | 
				
			||||||
		long difference = (System.currentTimeMillis() - time) / 1000;
 | 
							long difference = (System.currentTimeMillis() - time) / 1000;
 | 
				
			||||||
		if (difference<60) {
 | 
							if (difference < 60) {
 | 
				
			||||||
			return "just now";
 | 
								return "just now";
 | 
				
			||||||
		} else if (difference<60*10) {
 | 
							} else if (difference < 60 * 10) {
 | 
				
			||||||
			return difference / 60 + " min ago";
 | 
								return difference / 60 + " min ago";
 | 
				
			||||||
		} else if (difference<60*60*24) {
 | 
							} else if (difference < 60 * 60 * 24) {
 | 
				
			||||||
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
 | 
								SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
 | 
				
			||||||
			return sdf.format(date);
 | 
								return sdf.format(date);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					@ -22,4 +28,33 @@ public class Beautifier {
 | 
				
			||||||
			return sdf.format(date);
 | 
								return sdf.format(date);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static Bitmap getUnknownContactPicture(String name, int size) {
 | 
				
			||||||
 | 
							String firstLetter = name.substring(0, 1).toUpperCase();
 | 
				
			||||||
 | 
							String centerLetter = name.substring(name.length() / 2,
 | 
				
			||||||
 | 
									(name.length() / 2) + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int holoColors[] = { 0xFF1da9da, 0xFFb368d9, 0xFF83b600, 0xFFffa713,
 | 
				
			||||||
 | 
									0xFFe92727 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int color = holoColors[centerLetter.charAt(0) % 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;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,8 @@ import java.util.ArrayList;
 | 
				
			||||||
import java.util.Hashtable;
 | 
					import java.util.Hashtable;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Element {
 | 
					public class Element {
 | 
				
			||||||
	protected String name;
 | 
						protected String name;
 | 
				
			||||||
	protected Hashtable<String, String> attributes = new Hashtable<String, String>();
 | 
						protected Hashtable<String, String> attributes = new Hashtable<String, String>();
 | 
				
			||||||
| 
						 | 
					@ -26,6 +28,15 @@ public class Element {
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						public boolean hasChild(String name) {
 | 
				
			||||||
 | 
							for(Element child : this.children) {
 | 
				
			||||||
 | 
								if (child.getName().equals(name)) {
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	public Element setAttribute(String name, String value) {
 | 
						public Element setAttribute(String name, String value) {
 | 
				
			||||||
		this.attributes.put(name, value);
 | 
							this.attributes.put(name, value);
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
| 
						 | 
					@ -36,6 +47,14 @@ public class Element {
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						public String getAttribute(String name) {
 | 
				
			||||||
 | 
							if (this.attributes.containsKey(name)) {
 | 
				
			||||||
 | 
								return this.attributes.get(name);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	public String toString() {
 | 
						public String toString() {
 | 
				
			||||||
		StringBuilder elementOutput = new StringBuilder();
 | 
							StringBuilder elementOutput = new StringBuilder();
 | 
				
			||||||
		if ((content==null)&&(children.size() == 0)) {
 | 
							if ((content==null)&&(children.size() == 0)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,9 +12,8 @@ public class IqPacket extends Element {
 | 
				
			||||||
		super(name);
 | 
							super(name);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public IqPacket(String id, int type) {
 | 
						public IqPacket(int type) {
 | 
				
			||||||
		super("iq");
 | 
							super("iq");
 | 
				
			||||||
		this.setAttribute("id",id);
 | 
					 | 
				
			||||||
		switch (type) {
 | 
							switch (type) {
 | 
				
			||||||
		case TYPE_SET:
 | 
							case TYPE_SET:
 | 
				
			||||||
			this.setAttribute("type", "set");
 | 
								this.setAttribute("type", "set");
 | 
				
			||||||
| 
						 | 
					@ -34,4 +33,8 @@ public class IqPacket extends Element {
 | 
				
			||||||
		super("iq");
 | 
							super("iq");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public String getId() {
 | 
				
			||||||
 | 
							return this.getAttribute("id");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					package de.gultsch.chat.xmpp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface OnIqPacketReceived {
 | 
				
			||||||
 | 
						public void onIqPacketReceived(IqPacket packet);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					package de.gultsch.chat.xmpp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface OnMessagePacketReceived {
 | 
				
			||||||
 | 
						public void onMessagePacketReceived(MessagePacket packet);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					package de.gultsch.chat.xmpp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface OnPresencePacketReceived {
 | 
				
			||||||
 | 
						public void onPresencePacketReceived(PresencePacket packet);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import java.math.BigInteger;
 | 
				
			||||||
import java.net.Socket;
 | 
					import java.net.Socket;
 | 
				
			||||||
import java.net.UnknownHostException;
 | 
					import java.net.UnknownHostException;
 | 
				
			||||||
import java.security.SecureRandom;
 | 
					import java.security.SecureRandom;
 | 
				
			||||||
 | 
					import java.util.Hashtable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.net.ssl.SSLSocket;
 | 
					import javax.net.ssl.SSLSocket;
 | 
				
			||||||
import javax.net.ssl.SSLSocketFactory;
 | 
					import javax.net.ssl.SSLSocketFactory;
 | 
				
			||||||
| 
						 | 
					@ -35,12 +36,19 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
	private XmlReader tagReader;
 | 
						private XmlReader tagReader;
 | 
				
			||||||
	private TagWriter tagWriter;
 | 
						private TagWriter tagWriter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private boolean isTlsEncrypted = true;
 | 
						private boolean isTlsEncrypted = false;
 | 
				
			||||||
	private boolean isAuthenticated = false;
 | 
						private boolean isAuthenticated = false;
 | 
				
			||||||
 | 
						private boolean shouldUseTLS = false;
 | 
				
			||||||
 | 
						private boolean shouldReConnect = true;
 | 
				
			||||||
 | 
						private boolean shouldBind = true;
 | 
				
			||||||
 | 
						private boolean shouldAuthenticate = true;
 | 
				
			||||||
 | 
						private Element streamFeatures;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private static final int PACKET_IQ = 0;
 | 
						private static final int PACKET_IQ = 0;
 | 
				
			||||||
	private static final int PACKET_MESSAGE = 1;
 | 
						private static final int PACKET_MESSAGE = 1;
 | 
				
			||||||
	private static final int PACKET_PRESENCE = 2;
 | 
						private static final int PACKET_PRESENCE = 2;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private Hashtable<String, OnIqPacketReceived> iqPacketCallbacks = new Hashtable<String, OnIqPacketReceived>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public XmppConnection(Account account, PowerManager pm) {
 | 
						public XmppConnection(Account account, PowerManager pm) {
 | 
				
			||||||
		this.account = account;
 | 
							this.account = account;
 | 
				
			||||||
| 
						 | 
					@ -58,17 +66,6 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
			tagWriter.setOutputStream(out);
 | 
								tagWriter.setOutputStream(out);
 | 
				
			||||||
			InputStream in = socket.getInputStream();
 | 
								InputStream in = socket.getInputStream();
 | 
				
			||||||
			tagReader.setInputStream(in);
 | 
								tagReader.setInputStream(in);
 | 
				
			||||||
		} catch (UnknownHostException e) {
 | 
					 | 
				
			||||||
			Log.d(LOGTAG, "error during connect. unknown host");
 | 
					 | 
				
			||||||
		} catch (IOException e) {
 | 
					 | 
				
			||||||
			Log.d(LOGTAG, "error during connect. io exception. falscher port?");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override
 | 
					 | 
				
			||||||
	public void run() {
 | 
					 | 
				
			||||||
		connect();
 | 
					 | 
				
			||||||
		try {
 | 
					 | 
				
			||||||
			tagWriter.beginDocument();
 | 
								tagWriter.beginDocument();
 | 
				
			||||||
			sendStartStream();
 | 
								sendStartStream();
 | 
				
			||||||
			Tag nextTag;
 | 
								Tag nextTag;
 | 
				
			||||||
| 
						 | 
					@ -77,14 +74,25 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
					processStream(nextTag);
 | 
										processStream(nextTag);
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName());
 | 
										Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName());
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (XmlPullParserException e) {
 | 
							} catch (UnknownHostException e) {
 | 
				
			||||||
			Log.d(LOGTAG,
 | 
								Log.d(LOGTAG, "error during connect. unknown host");
 | 
				
			||||||
					"xml error during normal read. maybe missformed xml? "
 | 
								return;
 | 
				
			||||||
							+ e.getMessage());
 | 
					 | 
				
			||||||
		} catch (IOException e) {
 | 
							} catch (IOException e) {
 | 
				
			||||||
			Log.d(LOGTAG, "io exception during read. connection lost?");
 | 
								Log.d(LOGTAG, "error during connect. io exception. falscher port?");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} catch (XmlPullParserException e) {
 | 
				
			||||||
 | 
								Log.d(LOGTAG,"xml exception "+e.getMessage());
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void run() {
 | 
				
			||||||
 | 
							while(shouldReConnect) {
 | 
				
			||||||
 | 
								connect();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,20 +100,11 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
			IOException {
 | 
								IOException {
 | 
				
			||||||
		Log.d(LOGTAG, "process Stream");
 | 
							Log.d(LOGTAG, "process Stream");
 | 
				
			||||||
		Tag nextTag;
 | 
							Tag nextTag;
 | 
				
			||||||
		while ((nextTag = tagReader.readTag()) != null) {
 | 
							while (!(nextTag = tagReader.readTag()).isEnd("stream")) {
 | 
				
			||||||
			if (nextTag.isStart("error")) {
 | 
								if (nextTag.isStart("error")) {
 | 
				
			||||||
				processStreamError(nextTag);
 | 
									processStreamError(nextTag);
 | 
				
			||||||
			} else if (nextTag.isStart("features")) {
 | 
								} else if (nextTag.isStart("features")) {
 | 
				
			||||||
				processStreamFeatures(nextTag);
 | 
									processStreamFeatures(nextTag);
 | 
				
			||||||
				if (!isTlsEncrypted) {
 | 
					 | 
				
			||||||
					sendStartTLS();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if ((!isAuthenticated) && (isTlsEncrypted)) {
 | 
					 | 
				
			||||||
					sendSaslAuth();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if ((isAuthenticated)&&(isTlsEncrypted)) {
 | 
					 | 
				
			||||||
					sendBindRequest();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else if (nextTag.isStart("proceed")) {
 | 
								} else if (nextTag.isStart("proceed")) {
 | 
				
			||||||
				switchOverToTls(nextTag);
 | 
									switchOverToTls(nextTag);
 | 
				
			||||||
			} else if (nextTag.isStart("success")) {
 | 
								} else if (nextTag.isStart("success")) {
 | 
				
			||||||
| 
						 | 
					@ -121,8 +120,6 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
				Log.d(LOGTAG,processMessage(nextTag).toString());
 | 
									Log.d(LOGTAG,processMessage(nextTag).toString());
 | 
				
			||||||
			} else if (nextTag.isStart("presence")) {
 | 
								} else if (nextTag.isStart("presence")) {
 | 
				
			||||||
				Log.d(LOGTAG,processPresence(nextTag).toString());
 | 
									Log.d(LOGTAG,processPresence(nextTag).toString());
 | 
				
			||||||
			} else if (nextTag.isEnd("stream")) {
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName()
 | 
									Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName()
 | 
				
			||||||
						+ " as child of " + currentTag.getName());
 | 
											+ " as child of " + currentTag.getName());
 | 
				
			||||||
| 
						 | 
					@ -159,7 +156,12 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private IqPacket processIq(Tag currentTag) throws XmlPullParserException, IOException {
 | 
						private IqPacket processIq(Tag currentTag) throws XmlPullParserException, IOException {
 | 
				
			||||||
		return (IqPacket) processPacket(currentTag,PACKET_IQ);
 | 
							IqPacket packet = (IqPacket) processPacket(currentTag,PACKET_IQ);
 | 
				
			||||||
 | 
							if (iqPacketCallbacks.containsKey(packet.getId())) {
 | 
				
			||||||
 | 
								iqPacketCallbacks.get(packet.getId()).onIqPacketReceived(packet);
 | 
				
			||||||
 | 
								iqPacketCallbacks.remove(packet.getId());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return packet;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private MessagePacket processMessage(Tag currentTag) throws XmlPullParserException, IOException {
 | 
						private MessagePacket processMessage(Tag currentTag) throws XmlPullParserException, IOException {
 | 
				
			||||||
| 
						 | 
					@ -212,47 +214,44 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void processStreamFeatures(Tag currentTag)
 | 
						private void processStreamFeatures(Tag currentTag)
 | 
				
			||||||
			throws XmlPullParserException, IOException {
 | 
								throws XmlPullParserException, IOException {
 | 
				
			||||||
		Log.d(LOGTAG, "processStreamFeatures");
 | 
							this.streamFeatures = tagReader.readElement(currentTag);
 | 
				
			||||||
		
 | 
							Log.d(LOGTAG,"process stream features "+streamFeatures);
 | 
				
			||||||
		Element streamFeatures = new Element("features");
 | 
							if (this.streamFeatures.hasChild("starttls")&&shouldUseTLS) {
 | 
				
			||||||
		
 | 
								sendStartTLS();
 | 
				
			||||||
		Tag nextTag = tagReader.readTag();
 | 
							}
 | 
				
			||||||
		while(!nextTag.isEnd("features")) {
 | 
							if (this.streamFeatures.hasChild("mechanisms")&&shouldAuthenticate) {
 | 
				
			||||||
			Element element = tagReader.readElement(nextTag);
 | 
								sendSaslAuth();
 | 
				
			||||||
			streamFeatures.addChild(element);
 | 
							}
 | 
				
			||||||
			nextTag = tagReader.readTag();
 | 
							if (this.streamFeatures.hasChild("bind")&&shouldBind) {
 | 
				
			||||||
 | 
								sendBindRequest();
 | 
				
			||||||
 | 
								if (this.streamFeatures.hasChild("session")) {
 | 
				
			||||||
 | 
									IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
 | 
				
			||||||
 | 
									Element session = new Element("session");
 | 
				
			||||||
 | 
									session.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-session");
 | 
				
			||||||
 | 
									session.setContent("");
 | 
				
			||||||
 | 
									startSession.addChild(session);
 | 
				
			||||||
 | 
									sendIqPacket(startSession, null);
 | 
				
			||||||
 | 
									tagWriter.writeElement(startSession);
 | 
				
			||||||
 | 
									tagWriter.flush();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								Element presence = new Element("presence");
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								tagWriter.writeElement(presence);
 | 
				
			||||||
 | 
								tagWriter.flush();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Log.d(LOGTAG,streamFeatures.toString());
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void sendBindRequest() throws IOException {
 | 
						private void sendBindRequest() throws IOException {
 | 
				
			||||||
		IqPacket iq = new IqPacket(nextRandomId(),IqPacket.TYPE_SET);
 | 
							IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
 | 
				
			||||||
		Element bind = new Element("bind");
 | 
							Element bind = new Element("bind");
 | 
				
			||||||
		bind.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-bind");
 | 
							bind.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-bind");
 | 
				
			||||||
		iq.addChild(bind);
 | 
							iq.addChild(bind);
 | 
				
			||||||
		//Element resource = new Element("resource");
 | 
							this.sendIqPacket(iq, new OnIqPacketReceived() {	
 | 
				
			||||||
		//resource.setContent("mobile");
 | 
								@Override
 | 
				
			||||||
		//bind.addChild(resource);
 | 
								public void onIqPacketReceived(IqPacket packet) {
 | 
				
			||||||
		Log.d(LOGTAG,"sending bind request: "+iq.toString());
 | 
									Log.d(LOGTAG,"answer for our bind was: "+packet.toString());
 | 
				
			||||||
		tagWriter.writeElement(iq);
 | 
								}
 | 
				
			||||||
		tagWriter.flush();
 | 
							});
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		//technically not bind stuff
 | 
					 | 
				
			||||||
		IqPacket startSession = new IqPacket(this.nextRandomId(), IqPacket.TYPE_SET);
 | 
					 | 
				
			||||||
		Element session = new Element("session");
 | 
					 | 
				
			||||||
		session.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-session");
 | 
					 | 
				
			||||||
		session.setContent("");
 | 
					 | 
				
			||||||
		startSession.addChild(session);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		tagWriter.writeElement(startSession);
 | 
					 | 
				
			||||||
		tagWriter.flush();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		Element presence = new Element("presence");
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		tagWriter.writeElement(presence);
 | 
					 | 
				
			||||||
		tagWriter.flush();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void processStreamError(Tag currentTag) {
 | 
						private void processStreamError(Tag currentTag) {
 | 
				
			||||||
| 
						 | 
					@ -273,4 +272,15 @@ public class XmppConnection implements Runnable {
 | 
				
			||||||
	private String nextRandomId() {
 | 
						private String nextRandomId() {
 | 
				
			||||||
		return new BigInteger(50, random).toString(32);
 | 
							return new BigInteger(50, random).toString(32);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) throws IOException {
 | 
				
			||||||
 | 
							String id = nextRandomId();
 | 
				
			||||||
 | 
							packet.setAttribute("id",id);
 | 
				
			||||||
 | 
							tagWriter.writeElement(packet);
 | 
				
			||||||
 | 
							tagWriter.flush();
 | 
				
			||||||
 | 
							if (callback != null) {
 | 
				
			||||||
 | 
								iqPacketCallbacks.put(id, callback);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Log.d(LOGTAG,"sending: "+packet.toString());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue