create missed call notification when device is busy

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/services/NotificationService.java        | 24 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java | 32 
2 files changed, 51 insertions(+), 5 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/services/NotificationService.java 🔗

@@ -773,6 +773,25 @@ public class NotificationService {
         }
     }
 
+    public void clearMissedCall(final Message message) {
+        synchronized (mMissedCalls) {
+            final Iterator<Map.Entry<Conversational,MissedCallsInfo>> iterator = mMissedCalls.entrySet().iterator();
+            while (iterator.hasNext()) {
+                final Map.Entry<Conversational, MissedCallsInfo> entry = iterator.next();
+                final Conversational conversational = entry.getKey();
+                final MissedCallsInfo missedCallsInfo = entry.getValue();
+                if (conversational.getUuid().equals(message.getConversation().getUuid())) {
+                    if (missedCallsInfo.removeMissedCall()) {
+                        cancel(conversational.getUuid(), MISSED_CALL_NOTIFICATION_ID);
+                        Log.d(Config.LOGTAG,conversational.getAccount().getJid().asBareJid()+": dismissed missed call because call was picked up on other device");
+                        iterator.remove();
+                    }
+                }
+            }
+            updateMissedCallNotifications(null);
+        }
+    }
+
     public void clearMissedCalls() {
         synchronized (mMissedCalls) {
             for (final Conversational conversation : mMissedCalls.keySet()) {
@@ -1943,6 +1962,11 @@ public class NotificationService {
             lastTime = time;
         }
 
+        public boolean removeMissedCall() {
+            --numberOfCalls;
+            return numberOfCalls <= 0;
+        }
+
         public int getNumberOfCalls() {
             return numberOfCalls;
         }

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java 🔗

@@ -100,7 +100,8 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                         this.terminatedSessions.asMap().containsKey(PersistableSessionId.of(id));
                 final boolean stranger =
                         isWithStrangerAndStrangerNotificationsAreOff(account, id.with);
-                if (isBusy() || sessionEnded || stranger) {
+                final boolean busy = isBusy();
+                if (busy || sessionEnded || stranger) {
                     Log.d(
                             Config.LOGTAG,
                             id.account.getJid().asBareJid()
@@ -117,6 +118,15 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                     sessionTermination.setTo(id.with);
                     sessionTermination.setReason(Reason.BUSY, null);
                     mXmppConnectionService.sendIqPacket(account, sessionTermination, null);
+                    if (busy || stranger) {
+                        writeLogMissedIncoming(
+                                account,
+                                id.with,
+                                id.sessionId,
+                                null,
+                                System.currentTimeMillis(),
+                                stranger);
+                    }
                     return;
                 }
                 connection = new JingleRtpConnection(this, id, from);
@@ -329,6 +339,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                             Config.LOGTAG,
                             id.account.getJid().asBareJid()
                                     + ": updated previous busy because call got picked up by another device");
+                    mXmppConnectionService.getNotificationService().clearMissedCall(previousBusy);
                     return;
                 }
             }
@@ -400,7 +411,12 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                         isWithStrangerAndStrangerNotificationsAreOff(account, id.with);
                 if (isBusy() || stranger) {
                     writeLogMissedIncoming(
-                            account, id.with.asBareJid(), id.sessionId, serverMsgId, timestamp);
+                            account,
+                            id.with.asBareJid(),
+                            id.sessionId,
+                            serverMsgId,
+                            timestamp,
+                            stranger);
                     if (stranger) {
                         Log.d(
                                 Config.LOGTAG,
@@ -544,10 +560,11 @@ public class JingleConnectionManager extends AbstractConnectionManager {
 
     private void writeLogMissedIncoming(
             final Account account,
-            Jid with,
+            final Jid with,
             final String sessionId,
-            String serverMsgId,
-            long timestamp) {
+            final String serverMsgId,
+            final long timestamp,
+            final boolean stranger) {
         final Conversation conversation =
                 mXmppConnectionService.findOrCreateConversation(
                         account, with.asBareJid(), false, false);
@@ -557,7 +574,12 @@ public class JingleConnectionManager extends AbstractConnectionManager {
         message.setBody(new RtpSessionStatus(false, 0).toString());
         message.setServerMsgId(serverMsgId);
         message.setTime(timestamp);
+        message.setCounterpart(with);
         writeMessage(message);
+        if (stranger) {
+            return;
+        }
+        mXmppConnectionService.getNotificationService().pushMissedCallNow(message);
     }
 
     private void writeMessage(final Message message) {