diff --git a/res/layout/server_info.xml b/res/layout/server_info.xml index be317f9e2..8f19cae13 100644 --- a/res/layout/server_info.xml +++ b/res/layout/server_info.xml @@ -5,12 +5,22 @@ android:padding="8dp" > + + - - - - - + - - - + + + + + + + + + + \ No newline at end of file diff --git a/src/eu/siacs/conversations/crypto/PgpEngine.java b/src/eu/siacs/conversations/crypto/PgpEngine.java index 45bc6572b..d071f7dfd 100644 --- a/src/eu/siacs/conversations/crypto/PgpEngine.java +++ b/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) { diff --git a/src/eu/siacs/conversations/entities/Account.java b/src/eu/siacs/conversations/entities/Account.java index 36e204c50..5d2e3ccc8 100644 --- a/src/eu/siacs/conversations/entities/Account.java +++ b/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; diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 811074264..183ca00c6 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/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); } } }; diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java index 23de4ed5c..0d3adc857 100644 --- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/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"); diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index d653e06a2..5a29ad622 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/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()); diff --git a/src/eu/siacs/conversations/xmpp/stanzas/IqPacket.java b/src/eu/siacs/conversations/xmpp/stanzas/IqPacket.java index 1675d19d6..f70a74ddc 100644 --- a/src/eu/siacs/conversations/xmpp/stanzas/IqPacket.java +++ b/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; + } + } }