finished registration

Daniel Gultsch created

Change summary

res/layout/server_info.xml                                     | 78 +++
src/eu/siacs/conversations/crypto/PgpEngine.java               |  2 
src/eu/siacs/conversations/entities/Account.java               |  4 
src/eu/siacs/conversations/services/XmppConnectionService.java |  3 
src/eu/siacs/conversations/ui/ManageAccountActivity.java       | 40 +
src/eu/siacs/conversations/xmpp/XmppConnection.java            | 56 ++
src/eu/siacs/conversations/xmpp/stanzas/IqPacket.java          | 34 +
7 files changed, 202 insertions(+), 15 deletions(-)

Detailed changes

res/layout/server_info.xml 🔗

@@ -5,12 +5,22 @@
     android:padding="8dp" >
 
     <TextView
+        android:id="@+id/stats_header"
+        style="@style/sectionHeader"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingLeft="8dp"
+        android:paddingRight="8dp"
+        android:paddingBottom="8dp"
+        android:text="Statistics" />
+    
+    <TextView
+        android:layout_below="@+id/stats_header"
         android:id="@+id/textView1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Connection age"
         android:textSize="18sp"/>
-    
      <TextView
         android:id="@+id/connection"
         android:layout_width="wrap_content"
@@ -28,7 +38,6 @@
         android:layout_below="@+id/textView1"
         android:text="Session age"
         android:textSize="18sp"/>
-    
         <TextView
         android:id="@+id/session"
         android:layout_width="wrap_content"
@@ -46,7 +55,6 @@
         android:layout_below="@+id/textView2"
         android:text="Packets sent"
         android:textSize="18sp"/>
-
        <TextView
         android:id="@+id/pcks_sent"
         android:layout_width="wrap_content"
@@ -55,8 +63,7 @@
         android:layout_alignBottom="@+id/textView3"
         android:layout_alignParentRight="true"
         android:textSize="18sp"/>
-
-
+       
     <TextView
         android:id="@+id/textView4"
         android:layout_width="wrap_content"
@@ -64,9 +71,6 @@
         android:layout_below="@+id/textView3"
         android:text="Packets received"
         android:textSize="18sp"/>
-
- 
-
     <TextView
         android:id="@+id/pcks_received"
         android:layout_width="wrap_content"
@@ -75,5 +79,63 @@
         android:layout_alignBottom="@+id/textView4"
         android:layout_alignParentRight="true"
         android:textSize="18sp"/>
+    
+    <TextView
+        android:id="@+id/features_header"
+        android:layout_below="@+id/textView4"
+        style="@style/sectionHeader"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="8dp"
+        android:text="Server Features" />
+
+    <TextView
+        android:layout_below="@+id/features_header"
+        android:id="@+id/textView5"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Roster Versioning"
+        android:textSize="18sp"/>
+     <TextView
+        android:id="@+id/roster"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/textView5"
+        android:layout_alignBottom="@+id/textView5"
+        android:layout_alignParentRight="true"
+        android:textSize="18sp"/>
 
+    <TextView
+        android:id="@+id/textView6"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@+id/textView5"
+        android:text="Carbon Messages"
+        android:textSize="18sp"/>
+        <TextView
+        android:id="@+id/carbon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/textView6"
+        android:layout_alignBottom="@+id/textView6"
+        android:layout_alignParentRight="true"
+        android:textSize="18sp"/>
+
+    <TextView
+        android:id="@+id/textView7"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@+id/textView6"
+        android:text="Stream Managment"
+        android:textSize="18sp"/>
+       <TextView
+        android:id="@+id/stream"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/textView7"
+        android:layout_alignBottom="@+id/textView7"
+        android:layout_alignParentRight="true"
+        android:textSize="18sp"/>
 </RelativeLayout>

src/eu/siacs/conversations/crypto/PgpEngine.java 🔗

@@ -58,7 +58,7 @@ public class PgpEngine {
 
 	public long fetchKeyId(String status, String signature)
 			throws OpenPgpException {
-		if (signature==null) {
+		if ((signature==null)||(api==null)) {
 			return 0;
 		}
 		if (status==null) {

src/eu/siacs/conversations/entities/Account.java 🔗

@@ -41,6 +41,10 @@ public class Account  extends AbstractEntity{
 	public static final int STATUS_SERVER_NOT_FOUND = 5;
 
 	public static final int STATUS_SERVER_REQUIRES_TLS = 6;
+
+	public static final int STATUS_REGISTRATION_FAILED = 7;
+	public static final int STATUS_REGISTRATION_CONFLICT = 8;
+	public static final int STATUS_REGISTRATION_SUCCESSFULL = 9;
 	
 	protected String username;
 	protected String server;

src/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -208,6 +208,9 @@ public class XmppConnectionService extends Service {
 					scheduleWakeupCall(timeToReconnect, false);
 				}
 
+			} else if (account.getStatus() == Account.STATUS_REGISTRATION_SUCCESSFULL) {
+				databaseBackend.updateAccount(account);
+				reconnectAccount(account, true);
 			}
 		}
 	};

src/eu/siacs/conversations/ui/ManageAccountActivity.java 🔗

@@ -163,7 +163,20 @@ public class ManageAccountActivity extends XmppActivity {
 					statusView.setText("untrusted cerficate");
 					statusView.setTextColor(0xFFe92727);
 					break;
+				case Account.STATUS_REGISTRATION_FAILED:
+					statusView.setText("registration failed");
+					statusView.setTextColor(0xFFe92727);
+					break;
+				case Account.STATUS_REGISTRATION_CONFLICT:
+					statusView.setText("username already in use");
+					statusView.setTextColor(0xFFe92727);
+					break;
+				case  Account.STATUS_REGISTRATION_SUCCESSFULL:
+					statusView.setText("registration completed");
+					statusView.setTextColor(0xFF83b600);
+					break;
 				default:
+					statusView.setText("");
 					break;
 				}
 
@@ -179,7 +192,7 @@ public class ManageAccountActivity extends XmppActivity {
 					int position, long arg3) {
 				if (!isActionMode) {
 					Account account = accountList.get(position);
-					if ((account.getStatus() != Account.STATUS_ONLINE)&&(account.getStatus() != Account.STATUS_CONNECTING)&&(!account.isOptionSet(Account.OPTION_DISABLED))) {
+					if ((account.getStatus() == Account.STATUS_OFFLINE)||(account.getStatus() == Account.STATUS_TLS_ERROR)) {
 						activity.xmppConnectionService.reconnectAccount(accountList.get(position),true);
 					} else if (account.getStatus() == Account.STATUS_ONLINE) {
 						activity.startActivity(new Intent(activity.getApplicationContext(),NewConversationActivity.class));
@@ -281,10 +294,29 @@ public class ManageAccountActivity extends XmppActivity {
 									TextView session = (TextView) view.findViewById(R.id.session);
 									TextView pcks_sent = (TextView) view.findViewById(R.id.pcks_sent);
 									TextView pcks_received = (TextView) view.findViewById(R.id.pcks_received);
+									TextView carbon = (TextView) view.findViewById(R.id.carbon);
+									TextView stream = (TextView) view.findViewById(R.id.stream);
+									TextView roster = (TextView) view.findViewById(R.id.roster);
 									pcks_received.setText(""+xmpp.getReceivedStanzas());
 									pcks_sent.setText(""+xmpp.getSentStanzas());
 									connection.setText(connectionAge+" mins");
-									session.setText(sessionAge+" mins");
+									if (xmpp.hasFeatureStreamManagment()) {
+										session.setText(sessionAge+" mins");
+										stream.setText("Yes");
+									} else {
+										stream.setText("No");
+										session.setText(connectionAge+" mins");
+									}
+									if (xmpp.hasFeaturesCarbon()) {
+										carbon.setText("Yes");
+									} else {
+										carbon.setText("No");
+									}
+									if (xmpp.hasFeatureRosterManagment()) {
+										roster.setText("Yes");
+									} else {
+										roster.setText("No");
+									}
 									builder.setView(view);
 								} else {
 									builder.setMessage("Account is offline");
@@ -356,7 +388,9 @@ public class ManageAccountActivity extends XmppActivity {
 				@Override
 				public void onAccountEdited(Account account) {
 					xmppConnectionService.updateAccount(account);
-					actionMode.finish();
+					if (actionMode != null) { 
+						actionMode.finish();
+					}
 				}
 			});
 			dialog.show(getFragmentManager(), "edit_account");

src/eu/siacs/conversations/xmpp/XmppConnection.java 🔗

@@ -98,6 +98,9 @@ public class XmppConnection implements Runnable {
 
 	protected void changeStatus(int nextStatus) {
 		if (account.getStatus() != nextStatus) {
+			if ((nextStatus == Account.STATUS_OFFLINE)&&(account.getStatus() != Account.STATUS_CONNECTING)&&(account.getStatus() != Account.STATUS_ONLINE)) {
+				return;
+			}
 			account.setStatus(nextStatus);
 			if (statusListener != null) {
 				statusListener.onStatusChanged(account);
@@ -186,9 +189,6 @@ public class XmppConnection implements Runnable {
 						&& (!account.isOptionSet(Account.OPTION_USETLS))) {
 					changeStatus(Account.STATUS_SERVER_REQUIRES_TLS);
 				}
-				if (account.isOptionSet(Account.OPTION_REGISTER)) {
-					Log.d(LOGTAG,account.getJid()+": trying to register");
-				}
 			} else if (nextTag.isStart("proceed")) {
 				switchOverToTls(nextTag);
 			} else if (nextTag.isStart("success")) {
@@ -440,6 +440,43 @@ public class XmppConnection implements Runnable {
 		if (this.streamFeatures.hasChild("starttls")
 				&& account.isOptionSet(Account.OPTION_USETLS)) {
 			sendStartTLS();
+		} else if (this.streamFeatures.hasChild("register")&&(account.isOptionSet(Account.OPTION_REGISTER))) {
+				IqPacket register = new IqPacket(IqPacket.TYPE_GET);
+				register.query("jabber:iq:register");
+				register.setTo(account.getServer());
+				sendIqPacket(register, new OnIqPacketReceived() {
+					
+					@Override
+					public void onIqPacketReceived(Account account, IqPacket packet) {
+						Element instructions = packet.query().findChild("instructions");
+						if (packet.query().hasChild("username")&&(packet.query().hasChild("password"))) {
+							IqPacket register = new IqPacket(IqPacket.TYPE_SET);
+							Element username = new Element("username").setContent(account.getUsername());
+							Element password = new Element("password").setContent(account.getPassword());
+							register.query("jabber:iq:register").addChild(username).addChild(password);
+							sendIqPacket(register, new OnIqPacketReceived() {
+								
+								@Override
+								public void onIqPacketReceived(Account account, IqPacket packet) {
+									if (packet.getType()==IqPacket.TYPE_RESULT) {
+										account.setOption(Account.OPTION_REGISTER, false);
+										changeStatus(Account.STATUS_REGISTRATION_SUCCESSFULL);
+										Log.d(LOGTAG,"successfull");
+									} else if (packet.hasChild("error")&&(packet.findChild("error").hasChild("conflict"))){
+										changeStatus(Account.STATUS_REGISTRATION_CONFLICT);
+									} else {
+										changeStatus(Account.STATUS_REGISTRATION_FAILED);
+										Log.d(LOGTAG,packet.toString());
+									}
+									disconnect(true);
+								}
+							});
+							Log.d(LOGTAG,"registering: "+register.toString());
+						} else {
+							Log.d(LOGTAG,account.getJid()+": could not register. instructions are"+instructions.getContent());
+						}
+					}
+				});
 		} else if (this.streamFeatures.hasChild("mechanisms")
 				&& shouldAuthenticate) {
 			sendSaslAuth();
@@ -651,6 +688,7 @@ public class XmppConnection implements Runnable {
 	}
 
 	public void disconnect(boolean force) {
+		changeStatus(Account.STATUS_OFFLINE);
 		Log.d(LOGTAG,"disconnecting");
 		try {
 		if (force) {
@@ -677,6 +715,18 @@ public class XmppConnection implements Runnable {
 			return this.streamFeatures.hasChild("ver");
 		}
 	}
+	
+	public boolean hasFeatureStreamManagment() {
+		if (this.streamFeatures==null) {
+			return false;
+		} else {
+			return this.streamFeatures.hasChild("has");
+		}
+	}
+	
+	public boolean hasFeaturesCarbon() {
+		return discoFeatures.contains("urn:xmpp:carbons:2");
+	}
 
 	public void r() {
 		this.tagWriter.writeStanzaAsync(new RequestPacket());

src/eu/siacs/conversations/xmpp/stanzas/IqPacket.java 🔗

@@ -1,8 +1,12 @@
 package eu.siacs.conversations.xmpp.stanzas;
 
+import android.graphics.YuvImage;
+import eu.siacs.conversations.xml.Element;
+
 
 public class IqPacket extends AbstractStanza {
 	
+	public static final int TYPE_ERROR = -1;
 	public static final int TYPE_SET = 0;
 	public static final int TYPE_RESULT = 1;
 	public static final int TYPE_GET = 2;
@@ -31,5 +35,35 @@ public class IqPacket extends AbstractStanza {
 	public IqPacket() {
 		super("iq");
 	}
+	
+	public Element query() {
+		Element query = findChild("query");
+		if (query==null) {
+			query = new Element("query");
+			addChild(query);
+		}
+		return query;
+	}
+	
+	public Element query(String xmlns) {
+		Element query = query();
+		query.setAttribute("xmlns", xmlns);
+		return query();
+	}
+	
+	public int getType() {
+		String type = getAttribute("type");
+		if ("error".equals(type)) {
+			return TYPE_ERROR;
+		} else if ("result".equals(type)) {
+			return TYPE_RESULT;
+		} else if ("set".equals(type)) {
+			return TYPE_SET;
+		} else if ("get".equals(type)) {
+			return TYPE_GET;
+		} else {
+			return 1000;
+		}
+	}
 
 }