From 1665e6ee33936c40dab31ffa4aa6b47b3c6702e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Sat, 9 Oct 2021 22:21:14 -0400
Subject: [PATCH] call: allow state listeners to cancel themselves

Change-Id: If306734d2c29c017115e829b3fb4811333cea1f4
---
 src/call.cpp                | 11 +++++++++--
 src/call.h                  |  2 +-
 src/jamidht/jamiaccount.cpp |  4 ++++
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/call.cpp b/src/call.cpp
index 01b2ed5df0..27a88efbd9 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -134,6 +134,8 @@ Call::Call(const std::shared_ptr<Account>& account,
         // kill pending subcalls at disconnect
         if (call_state == CallState::OVER)
             hangupCalls(safePopSubcalls(), 0);
+
+        return true;
     });
 
     time(&timestamp_start_);
@@ -265,8 +267,12 @@ Call::setState(CallState call_state, ConnectionState cnx_state, signed code)
     connectionState_ = cnx_state;
     auto new_client_state = getStateStr();
 
-    for (auto& l : stateChangedListeners_)
-        l(callState_, connectionState_, code);
+    for (auto it = stateChangedListeners_.begin(); it != stateChangedListeners_.end(); ) {
+        if ((*it)(callState_, connectionState_, code))
+            ++it;
+        else
+            it = stateChangedListeners_.erase(it);
+    }
 
     if (old_client_state != new_client_state) {
         if (not parent_) {
@@ -481,6 +487,7 @@ Call::addSubCall(Call& subcall)
                     }
                 }
             });
+            return true;
         });
 }
 
diff --git a/src/call.h b/src/call.h
index 972860cd69..8e4e930c30 100644
--- a/src/call.h
+++ b/src/call.h
@@ -109,7 +109,7 @@ public:
 
     using SubcallSet = std::set<std::shared_ptr<Call>, std::owner_less<std::shared_ptr<Call>>>;
     using OnReadyCb = std::function<void(bool)>;
-    using StateListenerCb = std::function<void(CallState, ConnectionState, int)>;
+    using StateListenerCb = std::function<bool(CallState, ConnectionState, int)>;
 
     /**
      * This determines if the call originated from the local user (OUTGOING)
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 5fbf2411b8..542cf42f24 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -604,7 +604,9 @@ JamiAccount::startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std::
                         and state != Call::ConnectionState::TRYING) {
                         if (auto shared = w.lock())
                             shared->callConnectionClosed(deviceId, true);
+                        return false;
                     }
+                    return true;
                 });
             call->addSubCall(*dev_call);
             dev_call->setIceMedia(call->getIceMedia());
@@ -665,7 +667,9 @@ JamiAccount::startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std::
                     and state != Call::ConnectionState::TRYING) {
                     if (auto shared = w.lock())
                         shared->callConnectionClosed(deviceId, true);
+                    return false;
                 }
+                return true;
             });
 
         auto remote_address = ice->getRemoteAddress(ICE_COMP_ID_SIP_TRANSPORT);
-- 
GitLab