aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/eu/siacs/conversations/parser/IqParser.java1
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java93
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java10
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java50
4 files changed, 66 insertions, 88 deletions
diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java
index 3b501f33..6430c296 100644
--- a/src/main/java/eu/siacs/conversations/parser/IqParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java
@@ -92,6 +92,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
// Otherwise, just update the existing blocklist.
if (packet.getType() == IqPacket.TYPE.RESULT) {
account.clearBlocklist();
+ account.getXmppConnection().getFeatures().setBlockListRequested(true);
}
if (items != null) {
final Collection<Jid> jids = new ArrayList<>(items.size());
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 59cb3bb2..1192d5b9 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -188,12 +188,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
syncDirtyContacts(account);
- scheduleWakeupCall(Config.PING_MAX_INTERVAL, true);
+ scheduleWakeUpCall(Config.PING_MAX_INTERVAL,account.getUuid().hashCode());
} else if (account.getStatus() == Account.State.OFFLINE) {
resetSendingToWaiting(account);
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
int timeToReconnect = mRandom.nextInt(50) + 10;
- scheduleWakeupCall(timeToReconnect, false);
+ scheduleWakeUpCall(timeToReconnect,account.getUuid().hashCode());
}
} else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) {
databaseBackend.updateAccount(account);
@@ -206,7 +206,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
+ ": error connecting account. try again in "
+ next + "s for the "
+ (connection.getAttempt() + 1) + " time");
- scheduleWakeupCall((int) (next * 1.2), false);
+ scheduleWakeUpCall(next,account.getUuid().hashCode());
}
}
getNotificationService().updateErrorNotification();
@@ -241,8 +241,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
private OpenPgpServiceConnection pgpServiceConnection;
private PgpEngine mPgpEngine = null;
- private Intent pingIntent;
- private PendingIntent pendingPingIntent = null;
private WakeLock wakeLock;
private PowerManager pm;
private final OnBindListener mOnBindListener = new OnBindListener() {
@@ -388,16 +386,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- if (intent != null && intent.getAction() != null) {
- if (intent.getAction().equals(ACTION_MERGE_PHONE_CONTACTS)) {
+ final String action = intent == null ? null : intent.getAction();
+ if (action != null) {
+ if (action.equals(ACTION_MERGE_PHONE_CONTACTS)) {
PhoneHelper.loadPhoneContacts(getApplicationContext(), new ArrayList<Bundle>(), this);
return START_STICKY;
- } else if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
+ } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
logoutAndSave();
return START_NOT_STICKY;
- } else if (intent.getAction().equals(ACTION_CLEAR_NOTIFICATION)) {
+ } else if (action.equals(ACTION_CLEAR_NOTIFICATION)) {
mNotificationService.clear();
- } else if (intent.getAction().equals(ACTION_DISABLE_FOREGROUND)) {
+ } else if (action.equals(ACTION_DISABLE_FOREGROUND)) {
getPreferences().edit().putBoolean("keep_foreground_service",false).commit();
toggleForegroundService();
}
@@ -419,37 +418,36 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
if (account.getStatus() == Account.State.ONLINE) {
- long lastReceived = account.getXmppConnection()
- .getLastPacketReceived();
- long lastSent = account.getXmppConnection()
- .getLastPingSent();
- if (lastSent - lastReceived >= Config.PING_TIMEOUT * 1000) {
- Log.d(Config.LOGTAG, account.getJid()
- + ": ping timeout");
+ long lastReceived = account.getXmppConnection().getLastPacketReceived();
+ long lastSent = account.getXmppConnection().getLastPingSent();
+ long pingInterval = "ui".equals(action) ? Config.PING_MIN_INTERVAL * 1000 : Config.PING_MAX_INTERVAL * 1000;
+ long secondsToNextPing = ((lastReceived + pingInterval) - SystemClock.elapsedRealtime()) / 1000;
+ if (lastSent > lastReceived && (lastSent + Config.PING_TIMEOUT * 1000) < SystemClock.elapsedRealtime()) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": ping timeout");
this.reconnectAccount(account, true);
- } else if (SystemClock.elapsedRealtime() - lastReceived >= Config.PING_MIN_INTERVAL * 1000) {
+ } else if (secondsToNextPing <= 0) {
account.getXmppConnection().sendPing();
- this.scheduleWakeupCall(2, false);
+ Log.d(Config.LOGTAG, account.getJid().toBareJid()+" send ping");
+ this.scheduleWakeUpCall(Config.PING_TIMEOUT,account.getUuid().hashCode());
+ } else {
+ this.scheduleWakeUpCall((int) secondsToNextPing, account.getUuid().hashCode());
}
} else if (account.getStatus() == Account.State.OFFLINE) {
if (account.getXmppConnection() == null) {
- account.setXmppConnection(this
- .createConnection(account));
+ account.setXmppConnection(this.createConnection(account));
}
new Thread(account.getXmppConnection()).start();
} else if ((account.getStatus() == Account.State.CONNECTING)
&& ((SystemClock.elapsedRealtime() - account
.getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) {
- Log.d(Config.LOGTAG, account.getJid()
- + ": time out during connect reconnecting");
+ Log.d(Config.LOGTAG, account.getJid()+ ": time out during connect reconnecting");
reconnectAccount(account, true);
} else {
if (account.getXmppConnection().getTimeToNextAttempt() <= 0) {
reconnectAccount(account, true);
}
}
- // in any case. reschedule wakup call
- this.scheduleWakeupCall(Config.PING_MAX_INTERVAL, true);
+
}
if (mOnAccountUpdate != null) {
mOnAccountUpdate.onAccountUpdate();
@@ -546,42 +544,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
stopSelf();
}
- protected void scheduleWakeupCall(int seconds, boolean ping) {
- long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000;
- Context context = getApplicationContext();
- AlarmManager alarmManager = (AlarmManager) context
- .getSystemService(Context.ALARM_SERVICE);
+ protected void scheduleWakeUpCall(int seconds, int requestCode) {
+ final long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000;
- if (ping) {
- if (this.pingIntent == null) {
- this.pingIntent = new Intent(context, EventReceiver.class);
- this.pingIntent.setAction("ping");
- this.pingIntent.putExtra("time", timeToWake);
- this.pendingPingIntent = PendingIntent.getBroadcast(context, 0,
- this.pingIntent, 0);
- alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- timeToWake, pendingPingIntent);
- } else {
- long scheduledTime = this.pingIntent.getLongExtra("time", 0);
- if (scheduledTime < SystemClock.elapsedRealtime()
- || (scheduledTime > timeToWake)) {
- this.pingIntent.putExtra("time", timeToWake);
- alarmManager.cancel(this.pendingPingIntent);
- this.pendingPingIntent = PendingIntent.getBroadcast(
- context, 0, this.pingIntent, 0);
- alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- timeToWake, pendingPingIntent);
- }
- }
- } else {
- Intent intent = new Intent(context, EventReceiver.class);
- intent.setAction("ping_check");
- PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0,
- intent, 0);
- alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake,
- alarmIntent);
- }
+ Context context = getApplicationContext();
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent intent = new Intent(context, EventReceiver.class);
+ intent.setAction("ping");
+ PendingIntent alarmIntent = PendingIntent.getBroadcast(context, requestCode, intent, 0);
+ alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, alarmIntent);
}
public XmppConnection createConnection(final Account account) {
@@ -1862,8 +1834,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
Thread thread = new Thread(account.getXmppConnection());
thread.start();
- scheduleWakeupCall((int) (Config.CONNECT_TIMEOUT * 1.2),
- false);
+ scheduleWakeUpCall(Config.CONNECT_TIMEOUT,account.getUuid().hashCode());
} else {
account.getRoster().clearPresences();
account.setXmppConnection(null);
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index ae3c1834..5b5664c6 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -10,6 +10,7 @@ import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.util.DisplayMetrics;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
@@ -23,6 +24,7 @@ import android.widget.Toast;
import java.util.List;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
@@ -430,6 +432,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
return view;
} else if (type == NULL) {
+ if (viewHolder.message_box != null) {
+ Log.e(Config.LOGTAG, "detected type=NULL but with wrong cached view");
+ view = activity.getLayoutInflater().inflate(R.layout.message_null, parent, false);
+ view.setTag(new ViewHolder());
+ }
if (position == getCount() - 1) {
view.getLayoutParams().height = 1;
} else {
@@ -438,6 +445,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
view.setLayoutParams(view.getLayoutParams());
return view;
+ } else if (message.wasMergedIntoPrevious()) {
+ Log.e(Config.LOGTAG,"detected wasMergedIntoPrevious with wrong type");
+ return view;
} else if (viewHolder.messageBody == null || viewHolder.image == null) {
return view; //avoiding weird platform bugs
} else if (type == RECEIVED) {
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index 714b9a51..30437575 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -95,12 +95,9 @@ public class XmppConnection implements Runnable {
private int smVersion = 3;
private final SparseArray<String> messageReceipts = new SparseArray<>();
- private boolean enabledEncryption = false;
- private boolean enabledCarbons = false;
-
private int stanzasReceived = 0;
private int stanzasSent = 0;
- private long lastPaketReceived = 0;
+ private long lastPacketReceived = 0;
private long lastPingSent = 0;
private long lastConnect = 0;
private long lastSessionStarted = 0;
@@ -147,13 +144,12 @@ public class XmppConnection implements Runnable {
protected void connect() {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting");
- enabledEncryption = false;
+ features.encryptionEnabled = false;
lastConnect = SystemClock.elapsedRealtime();
lastPingSent = SystemClock.elapsedRealtime();
this.attempt++;
try {
- shouldAuthenticate = shouldBind = !account
- .isOptionSet(Account.OPTION_REGISTER);
+ shouldAuthenticate = shouldBind = !account.isOptionSet(Account.OPTION_REGISTER);
tagReader = new XmlReader(wakeLock);
tagWriter = new TagWriter();
packetCallbacks.clear();
@@ -304,7 +300,7 @@ public class XmppConnection implements Runnable {
final RequestPacket r = new RequestPacket(smVersion);
tagWriter.writeStanzaAsync(r);
} else if (nextTag.isStart("resumed")) {
- lastPaketReceived = SystemClock.elapsedRealtime();
+ lastPacketReceived = SystemClock.elapsedRealtime();
final Element resumed = tagReader.readElement(nextTag);
final String h = resumed.getAttribute("h");
try {
@@ -337,7 +333,7 @@ public class XmppConnection implements Runnable {
tagWriter.writeStanzaAsync(ack);
} else if (nextTag.isStart("a")) {
final Element ack = tagReader.readElement(nextTag);
- lastPaketReceived = SystemClock.elapsedRealtime();
+ lastPacketReceived = SystemClock.elapsedRealtime();
final int serverSequence = Integer.parseInt(ack.getAttribute("h"));
final String msgId = this.messageReceipts.get(serverSequence);
if (msgId != null) {
@@ -426,7 +422,7 @@ public class XmppConnection implements Runnable {
}
}
++stanzasReceived;
- lastPaketReceived = SystemClock.elapsedRealtime();
+ lastPacketReceived = SystemClock.elapsedRealtime();
return element;
}
@@ -530,7 +526,7 @@ public class XmppConnection implements Runnable {
tagWriter.setOutputStream(sslSocket.getOutputStream());
sendStartStream();
Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": TLS connection established");
- enabledEncryption = true;
+ features.encryptionEnabled = true;
processStream(tagReader.readTag());
sslSocket.close();
} catch (final NoSuchAlgorithmException | KeyManagementException e1) {
@@ -543,18 +539,18 @@ public class XmppConnection implements Runnable {
private void processStreamFeatures(final Tag currentTag)
throws XmlPullParserException, IOException {
this.streamFeatures = tagReader.readElement(currentTag);
- if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) {
+ if (this.streamFeatures.hasChild("starttls") && !features.encryptionEnabled) {
sendStartTLS();
} else if (this.streamFeatures.hasChild("register")
&& account.isOptionSet(Account.OPTION_REGISTER)
- && enabledEncryption) {
+ && features.encryptionEnabled) {
sendRegistryRequest();
} else if (!this.streamFeatures.hasChild("register")
&& account.isOptionSet(Account.OPTION_REGISTER)) {
changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED);
disconnect(true);
} else if (this.streamFeatures.hasChild("mechanisms")
- && shouldAuthenticate && enabledEncryption) {
+ && shouldAuthenticate && features.encryptionEnabled) {
final List<String> mechanisms = extractMechanisms(streamFeatures
.findChild("mechanisms"));
final Element auth = new Element("auth");
@@ -679,15 +675,15 @@ public class XmppConnection implements Runnable {
tagWriter.writeStanzaAsync(enable);
stanzasSent = 0;
messageReceipts.clear();
- } else if (streamFeatures.hasChild("sm",
- "urn:xmpp:sm:2")) {
+ } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) {
smVersion = 2;
final EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
stanzasSent = 0;
messageReceipts.clear();
}
- enabledCarbons = false;
+ features.carbonsEnabled = false;
+ features.blockListRequested = false;
disco.clear();
sendServiceDiscoveryInfo(account.getServer());
sendServiceDiscoveryItems(account.getServer());
@@ -750,12 +746,10 @@ public class XmppConnection implements Runnable {
}
private void enableAdvancedStreamFeatures() {
- if (getFeatures().carbons()) {
- if (!enabledCarbons) {
- sendEnableCarbons();
- }
+ if (getFeatures().carbons() && !features.carbonsEnabled) {
+ sendEnableCarbons();
}
- if (getFeatures().blocking()) {
+ if (getFeatures().blocking() && !features.blockListRequested) {
Log.d(Config.LOGTAG, "Requesting block list");
this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser());
}
@@ -792,7 +786,7 @@ public class XmppConnection implements Runnable {
if (!packet.hasChild("error")) {
Log.d(Config.LOGTAG, account.getJid().toBareJid()
+ ": successfully enabled carbons");
- enabledCarbons = true;
+ features.carbonsEnabled = true;
} else {
Log.d(Config.LOGTAG, account.getJid().toBareJid()
+ ": error enableing carbons " + packet.toString());
@@ -1018,7 +1012,7 @@ public class XmppConnection implements Runnable {
}
public long getLastPacketReceived() {
- return this.lastPaketReceived;
+ return this.lastPacketReceived;
}
public void sendActive() {
@@ -1031,6 +1025,9 @@ public class XmppConnection implements Runnable {
public class Features {
XmppConnection connection;
+ private boolean carbonsEnabled = false;
+ private boolean encryptionEnabled = false;
+ private boolean blockListRequested = false;
public Features(final XmppConnection connection) {
this.connection = connection;
@@ -1078,9 +1075,8 @@ public class XmppConnection implements Runnable {
return connection.streamFeatures != null && connection.streamFeatures.hasChild("ver");
}
- public boolean streamhost() {
- return connection
- .findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
+ public void setBlockListRequested(boolean value) {
+ this.blockListRequested = value;
}
}