From d7ab7715ed5bb16dd5fbd022d0e5f029fd7f7b00 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 8 Mar 2014 20:14:47 +0100 Subject: [PATCH] couple of otr related bug fixes and basic ping --- .../siacs/conversations/crypto/OtrEngine.java | 10 +-- .../conversations/services/EventReceiver.java | 1 + .../services/XmppConnectionService.java | 68 +++++++++++++++++-- .../ui/ConversationFragment.java | 1 + .../conversations/xmpp/XmppConnection.java | 3 + 5 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/eu/siacs/conversations/crypto/OtrEngine.java b/src/eu/siacs/conversations/crypto/OtrEngine.java index eca01a736..23af94e79 100644 --- a/src/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/eu/siacs/conversations/crypto/OtrEngine.java @@ -64,16 +64,12 @@ public class OtrEngine implements OtrEngineHost { PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); return new KeyPair(publicKey, privateKey); } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + return null; } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + return null; } catch (InvalidKeySpecException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + return null; } - return null; } private void saveKey() { diff --git a/src/eu/siacs/conversations/services/EventReceiver.java b/src/eu/siacs/conversations/services/EventReceiver.java index d58fb2ec3..99b9f3c76 100644 --- a/src/eu/siacs/conversations/services/EventReceiver.java +++ b/src/eu/siacs/conversations/services/EventReceiver.java @@ -8,6 +8,7 @@ public class EventReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Intent mIntentForService = new Intent(context, XmppConnectionService.class); + mIntentForService.putExtra("ping", intent.getBooleanExtra("ping",false)); if ((intent.getAction() != null) && (intent.getAction() .equals("android.intent.action.BOOT_COMPLETED"))) { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 64a93ea42..da43cb164 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -44,7 +44,6 @@ import eu.siacs.conversations.xmpp.OnTLSExceptionReceived; import eu.siacs.conversations.xmpp.PresencePacket; import eu.siacs.conversations.xmpp.XmppConnection; import android.app.AlarmManager; -import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; @@ -70,6 +69,9 @@ public class XmppConnectionService extends Service { public long startDate; + private static final int PING_INTERVAL = 300; + private static final int PING_TIMEOUT = 2; + private List accounts; private List conversations = null; @@ -112,7 +114,9 @@ public class XmppConnectionService extends Service { && (packet.getBody().startsWith("?OTR"))) { message = MessageParser.parseOtrChat(packet, account, service); - message.markUnread(); + if (message!=null) { + message.markUnread(); + } } else if (packet.hasChild("body")) { message = MessageParser.parsePlainTextChat(packet, account, service); @@ -197,12 +201,13 @@ public class XmppConnectionService extends Service { // } } + scheduleWakeupCall(PING_INTERVAL, true); } else if (account.getStatus() == Account.STATUS_OFFLINE) { Log.d(LOGTAG,"onStatusChanged offline"); databaseBackend.clearPresences(account); if (!account.isOptionSet(Account.OPTION_DISABLED)) { int timeToReconnect = mRandom.nextInt(50)+10; - scheduleWakeupCall(timeToReconnect); + scheduleWakeupCall(timeToReconnect,false); } } @@ -408,6 +413,11 @@ public class XmppConnectionService extends Service { if (account.getStatus()==Account.STATUS_OFFLINE) { Thread thread = new Thread(account.getXmppConnection()); thread.start(); + } else { + if (intent.getBooleanExtra("ping", false)) { + Log.d(LOGTAG,"start service ping"); + ping(account,PING_TIMEOUT); + } } } } @@ -438,15 +448,21 @@ public class XmppConnectionService extends Service { } } - protected void scheduleWakeupCall(int seconds) { + protected void scheduleWakeupCall(int seconds,boolean ping) { Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, EventReceiver.class); + intent.putExtra("ping", ping); PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + seconds * 1000, alarmIntent); - Log.d(LOGTAG,"wake up call scheduled in "+seconds+" seconds"); + if (ping) { + Log.d(LOGTAG,"schedule ping in "+seconds+" seconds"); + } else { + Log.d(LOGTAG,"schedule reconnect in "+seconds+" seconds"); + } + } public XmppConnection createConnection(Account account) { @@ -912,6 +928,7 @@ public class XmppConnectionService extends Service { } private OnRenameListener renameListener = null; + private boolean pongReceived; public void setOnRenameListener(OnRenameListener listener) { this.renameListener = listener; } @@ -1127,4 +1144,45 @@ public class XmppConnectionService extends Service { thread.start(); } } + + public void ping(final Account account,final int timeout) { + Log.d(LOGTAG,account.getJid()+": sending ping"); + IqPacket iq = new IqPacket(IqPacket.TYPE_GET); + Element ping = new Element("ping"); + iq.setAttribute("from",account.getFullJid()); + ping.setAttribute("xmlns", "urn:xmpp:ping"); + iq.addChild(ping); + pongReceived = false; + account.getXmppConnection().sendIqPacket(iq, new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + pongReceived = true; + } + }); + new Thread(new Runnable() { + + @Override + public void run() { + int i = 0; + while(i <= (5 * timeout)) { + if (pongReceived) { + scheduleWakeupCall(PING_INTERVAL,true); + break; + } + try { + Thread.sleep(200); + } catch (InterruptedException e) { + + } + ++i; + } + if (!pongReceived) { + Log.d("xmppService",account.getJid()+" no pong after "+timeout+" seconds"); + reconnectAccount(account); + } + + } + }).start(); + } } \ No newline at end of file diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index aab712087..62755c6c0 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -378,6 +378,7 @@ public class ConversationFragment extends Fragment { public void updateMessages() { ConversationActivity activity = (ConversationActivity) getActivity(); List encryptedMessages = new LinkedList(); + // TODO this.conversation could be null?! for(Message message : this.conversation.getMessages()) { if (message.getEncryption() == Message.ENCRYPTION_PGP) { encryptedMessages.add(message); diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index bf81897c9..bca5f5aa3 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -87,6 +87,9 @@ public class XmppConnection implements Runnable { protected void connect() { Log.d(LOGTAG, "connecting"); try { + tagReader = new XmlReader(wakeLock); + tagWriter = new TagWriter(); + packetCallbacks.clear(); this.changeStatus(Account.STATUS_CONNECTING); Bundle namePort = DNSHelper.getSRVRecord(account.getServer()); String srvRecordServer = namePort.getString("name");