postpone notification actions (mark as read, reply) until after messages are loaded
This commit is contained in:
parent
4600b3982e
commit
2b39acf352
|
@ -62,6 +62,7 @@ import java.util.ListIterator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@ -159,6 +160,7 @@ public class XmppConnectionService extends Service {
|
||||||
private final SerialSingleThreadExecutor mVideoCompressionExecutor = new SerialSingleThreadExecutor("VideoCompression");
|
private final SerialSingleThreadExecutor mVideoCompressionExecutor = new SerialSingleThreadExecutor("VideoCompression");
|
||||||
private final SerialSingleThreadExecutor mDatabaseWriterExecutor = new SerialSingleThreadExecutor("DatabaseWriter");
|
private final SerialSingleThreadExecutor mDatabaseWriterExecutor = new SerialSingleThreadExecutor("DatabaseWriter");
|
||||||
private final SerialSingleThreadExecutor mDatabaseReaderExecutor = new SerialSingleThreadExecutor("DatabaseReader");
|
private final SerialSingleThreadExecutor mDatabaseReaderExecutor = new SerialSingleThreadExecutor("DatabaseReader");
|
||||||
|
private final SerialSingleThreadExecutor mNotificationExecutor = new SerialSingleThreadExecutor("NotificationExecutor");
|
||||||
private ReplacingSerialSingleThreadExecutor mContactMergerExecutor = new ReplacingSerialSingleThreadExecutor(true);
|
private ReplacingSerialSingleThreadExecutor mContactMergerExecutor = new ReplacingSerialSingleThreadExecutor(true);
|
||||||
private final IBinder mBinder = new XmppConnectionBinder();
|
private final IBinder mBinder = new XmppConnectionBinder();
|
||||||
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
||||||
|
@ -420,14 +422,14 @@ public class XmppConnectionService extends Service {
|
||||||
private LruCache<String, Bitmap> mBitmapCache;
|
private LruCache<String, Bitmap> mBitmapCache;
|
||||||
private EventReceiver mEventReceiver = new EventReceiver();
|
private EventReceiver mEventReceiver = new EventReceiver();
|
||||||
|
|
||||||
private boolean mRestoredFromDatabase = false;
|
public final CountDownLatch restoredFromDatabaseLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
private static String generateFetchKey(Account account, final Avatar avatar) {
|
private static String generateFetchKey(Account account, final Avatar avatar) {
|
||||||
return account.getJid().toBareJid() + "_" + avatar.owner + "_" + avatar.sha1sum;
|
return account.getJid().toBareJid() + "_" + avatar.owner + "_" + avatar.sha1sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean areMessagesInitialized() {
|
public boolean areMessagesInitialized() {
|
||||||
return this.mRestoredFromDatabase;
|
return this.restoredFromDatabaseLatch.getCount() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PgpEngine getPgpEngine() {
|
public PgpEngine getPgpEngine() {
|
||||||
|
@ -569,7 +571,6 @@ public class XmppConnectionService extends Service {
|
||||||
boolean interactive = false;
|
boolean interactive = false;
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
final String uuid = intent.getStringExtra("uuid");
|
final String uuid = intent.getStringExtra("uuid");
|
||||||
final Conversation c = findConversationByUuid(uuid);
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ConnectivityManager.CONNECTIVITY_ACTION:
|
case ConnectivityManager.CONNECTIVITY_ACTION:
|
||||||
if (hasInternetConnection() && Config.RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE) {
|
if (hasInternetConnection() && Config.RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE) {
|
||||||
|
@ -577,7 +578,7 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_MERGE_PHONE_CONTACTS:
|
case ACTION_MERGE_PHONE_CONTACTS:
|
||||||
if (mRestoredFromDatabase) {
|
if (restoredFromDatabaseLatch.getCount() == 0) {
|
||||||
loadPhoneContacts();
|
loadPhoneContacts();
|
||||||
}
|
}
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
|
@ -585,11 +586,20 @@ public class XmppConnectionService extends Service {
|
||||||
logoutAndSave(true);
|
logoutAndSave(true);
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
case ACTION_CLEAR_NOTIFICATION:
|
case ACTION_CLEAR_NOTIFICATION:
|
||||||
if (c != null) {
|
mNotificationExecutor.execute(() -> {
|
||||||
mNotificationService.clear(c);
|
try {
|
||||||
} else {
|
final Conversation c = findConversationByUuid(uuid);
|
||||||
mNotificationService.clear();
|
if (c != null) {
|
||||||
}
|
mNotificationService.clear(c);
|
||||||
|
} else {
|
||||||
|
mNotificationService.clear();
|
||||||
|
}
|
||||||
|
restoredFromDatabaseLatch.await();
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(Config.LOGTAG,"unable to process clear notification");
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case ACTION_DISMISS_ERROR_NOTIFICATIONS:
|
case ACTION_DISMISS_ERROR_NOTIFICATIONS:
|
||||||
dismissErrorNotifications();
|
dismissErrorNotifications();
|
||||||
|
@ -600,19 +610,41 @@ public class XmppConnectionService extends Service {
|
||||||
break;
|
break;
|
||||||
case ACTION_REPLY_TO_CONVERSATION:
|
case ACTION_REPLY_TO_CONVERSATION:
|
||||||
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
|
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
|
||||||
if (remoteInput != null && c != null) {
|
if (remoteInput == null) {
|
||||||
final CharSequence body = remoteInput.getCharSequence("text_reply");
|
break;
|
||||||
if (body != null && body.length() > 0) {
|
|
||||||
directReply(c, body.toString(), intent.getBooleanExtra("dismiss_notification", false));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
final CharSequence body = remoteInput.getCharSequence("text_reply");
|
||||||
|
final boolean dismissNotification = intent.getBooleanExtra("dismiss_notification", false);
|
||||||
|
if (body == null || body.length() <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mNotificationExecutor.execute(()-> {
|
||||||
|
try {
|
||||||
|
restoredFromDatabaseLatch.await();
|
||||||
|
final Conversation c = findConversationByUuid(uuid);
|
||||||
|
if (c != null) {
|
||||||
|
directReply(c, body.toString(), dismissNotification);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(Config.LOGTAG,"unable to process direct reply");
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case ACTION_MARK_AS_READ:
|
case ACTION_MARK_AS_READ:
|
||||||
if (c != null) {
|
mNotificationExecutor.execute(() -> {
|
||||||
sendReadMarker(c);
|
final Conversation c = findConversationByUuid(uuid);
|
||||||
} else {
|
if (c == null) {
|
||||||
Log.d(Config.LOGTAG, "received mark read intent for unknown conversation (" + uuid + ")");
|
Log.d(Config.LOGTAG, "received mark read intent for unknown conversation (" + uuid + ")");
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
restoredFromDatabaseLatch.await();
|
||||||
|
sendReadMarker(c);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(Config.LOGTAG,"unable to process notification read marker for conversation "+c.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case AudioManager.RINGER_MODE_CHANGED_ACTION:
|
case AudioManager.RINGER_MODE_CHANGED_ACTION:
|
||||||
if (dndOnSilentMode()) {
|
if (dndOnSilentMode()) {
|
||||||
|
@ -1459,7 +1491,7 @@ public class XmppConnectionService extends Service {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
mNotificationService.finishBacklog(false);
|
mNotificationService.finishBacklog(false);
|
||||||
mRestoredFromDatabase = true;
|
restoredFromDatabaseLatch.countDown();
|
||||||
final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
|
final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
|
||||||
Log.d(Config.LOGTAG, "finished restoring messages in " + diffMessageRestore + "ms");
|
Log.d(Config.LOGTAG, "finished restoring messages in " + diffMessageRestore + "ms");
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
|
|
|
@ -17,4 +17,5 @@ public final class Namespace {
|
||||||
public static final String PUBSUB_ERROR = "http://jabber.org/protocol/pubsub#errors";
|
public static final String PUBSUB_ERROR = "http://jabber.org/protocol/pubsub#errors";
|
||||||
public static final String NICK = "http://jabber.org/protocol/nick";
|
public static final String NICK = "http://jabber.org/protocol/nick";
|
||||||
public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL = "http://jabber.org/protocol/offline";
|
public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL = "http://jabber.org/protocol/offline";
|
||||||
|
public static final String BIND = "urn:ietf:params:xml:ns:xmpp-bind";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1043,14 +1043,16 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendBindRequest() {
|
private void sendBindRequest() {
|
||||||
while (!mXmppConnectionService.areMessagesInitialized() && socket != null && !socket.isClosed()) {
|
try {
|
||||||
uninterruptedSleep(500);
|
mXmppConnectionService.restoredFromDatabaseLatch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": interrupted while waiting for DB restore during bind");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
needsBinding = false;
|
needsBinding = false;
|
||||||
clearIqCallbacks();
|
clearIqCallbacks();
|
||||||
final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
|
final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
|
||||||
iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind")
|
iq.addChild("bind", Namespace.BIND).addChild("resource").setContent(account.getResource());
|
||||||
.addChild("resource").setContent(account.getResource());
|
|
||||||
this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() {
|
this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() {
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
|
|
Loading…
Reference in a new issue