Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • beta/202506161038
  • stable/20250613.0
  • nightly/20250613.0
  • beta/202506101658
  • stable/20250610.0
  • nightly/20250610.0
  • beta/202506091027
  • beta/202506061543
  • nightly/20250605.0
  • beta/202506051039
  • beta/202506051002
  • beta/202506041611
  • beta/202506041335
  • beta/202505231812
  • stable/20250523.0
  • nightly/20250523.0
  • nightly/20250515.0
  • nightly/20250510.0
  • nightly/20250509.1
  • nightly/20250509.0
21 results

callbackshandler.cpp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    callbackshandler.cpp 30.45 KiB
    /****************************************************************************
     *    Copyright (C) 2017-2024 Savoir-faire Linux Inc.                       *
     *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
     *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
     *                                                                          *
     *   This library is free software; you can redistribute it and/or          *
     *   modify it under the terms of the GNU Lesser General Public             *
     *   License as published by the Free Software Foundation; either           *
     *   version 2.1 of the License, or (at your option) any later version.     *
     *                                                                          *
     *   This library is distributed in the hope that it will be useful,        *
     *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
     *   Lesser General Public License for more details.                        *
     *                                                                          *
     *   You should have received a copy of the GNU General Public License      *
     *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
     ***************************************************************************/
    #include "callbackshandler.h"
    
    // Models and database
    #include "api/account.h"
    #include "api/lrc.h"
    #include "api/accountmodel.h"
    #include "api/datatransfer.h"
    #include "api/datatransfermodel.h"
    #include "api/behaviorcontroller.h"
    
    // Lrc
    #include "dbus/callmanager.h"
    #include "dbus/configurationmanager.h"
    #include "dbus/presencemanager.h"
    #include "dbus/videomanager.h"
    
    #include "typedefs.h"
    
    // libjami
    #include <datatransfer_interface.h>
    
    #include <QFileInfo>
    #include <QUrl>
    #include <QRegularExpression>
    
    #ifdef ENABLE_LIBWRAP
    // For the debugMessageReceived connection that queues const std::string refs
    // when not using dbus
    Q_DECLARE_METATYPE(std::string)
    #endif
    
    namespace lrc {
    
    using namespace api;
    
    static inline datatransfer::Status
    convertDataTransferEvent(libjami::DataTransferEventCode event)
    {
        switch (event) {
        case libjami::DataTransferEventCode::invalid:
            return datatransfer::Status::INVALID;
        case libjami::DataTransferEventCode::created:
            return datatransfer::Status::on_connection;
        case libjami::DataTransferEventCode::unsupported:
            return datatransfer::Status::unsupported;
        case libjami::DataTransferEventCode::wait_peer_acceptance:
            return datatransfer::Status::on_connection;
        case libjami::DataTransferEventCode::wait_host_acceptance:
            return datatransfer::Status::on_connection;
        case libjami::DataTransferEventCode::ongoing:
            return datatransfer::Status::on_progress;
        case libjami::DataTransferEventCode::finished:
            return datatransfer::Status::success;
        case libjami::DataTransferEventCode::closed_by_host:
            return datatransfer::Status::stop_by_host;
        case libjami::DataTransferEventCode::closed_by_peer:
            return datatransfer::Status::stop_by_peer;
        case libjami::DataTransferEventCode::invalid_pathname:
            return datatransfer::Status::invalid_pathname;
        case libjami::DataTransferEventCode::unjoinable_peer:
            return datatransfer::Status::unjoinable_peer;
        case libjami::DataTransferEventCode::timeout_expired:
            return datatransfer::Status::timeout_expired;
        }
        throw std::runtime_error("BUG: broken convertDataTransferEvent() switch");
    }
    
    CallbacksHandler::CallbacksHandler(const Lrc& parent)
        : QObject()
        , parent(parent)
    {
        // Get signals from daemon
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::incomingAccountMessage,
                this,
                &CallbacksHandler::slotNewAccountMessage,
                Qt::QueuedConnection);
    
        connect(&PresenceManager::instance(),
                &PresenceManagerInterface::newBuddyNotification,
                this,
                &CallbacksHandler::slotNewBuddySubscription,
                Qt::QueuedConnection);
    
        connect(&PresenceManager::instance(),
                &PresenceManagerInterface::nearbyPeerNotification,
                this,
                &CallbacksHandler::slotNearbyPeerSubscription,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::contactAdded,
                this,
                &CallbacksHandler::slotContactAdded,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::contactRemoved,
                this,
                &CallbacksHandler::slotContactRemoved,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::accountMessageStatusChanged,
                this,
                &CallbacksHandler::slotAccountMessageStatusChanged,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::needsHost,
                this,
                &CallbacksHandler::slotNeedsHost,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::accountDetailsChanged,
                this,
                &CallbacksHandler::slotAccountDetailsChanged,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::volatileAccountDetailsChanged,
                this,
                &CallbacksHandler::slotVolatileAccountDetailsChanged,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::accountsChanged,
                this,
                &CallbacksHandler::slotAccountsChanged);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::registrationStateChanged,
                this,
                &CallbacksHandler::slotRegistrationStateChanged,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::mediaChangeRequested,
                this,
                &CallbacksHandler::slotMediaChangeRequested,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::callStateChanged,
                this,
                &CallbacksHandler::slotCallStateChanged,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::mediaNegotiationStatus,
                this,
                &CallbacksHandler::slotMediaNegotiationStatus,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::conferenceCreated,
                this,
                &CallbacksHandler::slotConferenceCreated,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::conferenceRemoved,
                this,
                &CallbacksHandler::slotConferenceRemoved,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::conferenceChanged,
                this,
                &CallbacksHandler::slotConferenceChanged,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::recordingStateChanged,
                this,
                &CallbacksHandler::recordingStateChanged,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::incomingMessage,
                this,
                &CallbacksHandler::slotIncomingMessage,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::recordPlaybackStopped,
                this,
                &CallbacksHandler::slotRecordPlaybackStopped,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::voiceMailNotify,
                this,
                &CallbacksHandler::slotVoiceMailNotify,
                Qt::QueuedConnection);
    
        connect(&CallManager::instance(),
                &CallManagerInterface::remoteRecordingChanged,
                this,
                &CallbacksHandler::slotRemoteRecordingChanged,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::dataTransferEvent,
                this,
                &CallbacksHandler::slotDataTransferEvent,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::knownDevicesChanged,
                this,
                &CallbacksHandler::slotKnownDevicesChanged,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::deviceRevocationEnded,
                this,
                &CallbacksHandler::slotDeviceRevokationEnded,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::accountProfileReceived,
                this,
                &CallbacksHandler::slotAccountProfileReceived,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::exportOnRingEnded,
                this,
                &CallbacksHandler::slotExportOnRingEnded,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::nameRegistrationEnded,
                this,
                &CallbacksHandler::slotNameRegistrationEnded,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::registeredNameFound,
                this,
                &CallbacksHandler::slotRegisteredNameFound,
                Qt::QueuedConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::migrationEnded,
                this,
                &CallbacksHandler::slotMigrationEnded,
                Qt::QueuedConnection);
    
        connect(&VideoManager::instance(),
                &VideoManagerInterface::decodingStarted,
                this,
                &CallbacksHandler::decodingStarted,
                Qt::DirectConnection);
    
        connect(&VideoManager::instance(),
                &VideoManagerInterface::decodingStopped,
                this,
                &CallbacksHandler::decodingStopped,
                Qt::DirectConnection);
    
        connect(&VideoManager::instance(),
                &VideoManagerInterface::deviceEvent,
                this,
                &CallbacksHandler::deviceEvent,
                Qt::QueuedConnection);
        connect(&VideoManager::instance(),
                &VideoManagerInterface::fileOpened,
                this,
                &CallbacksHandler::fileOpened,
                Qt::DirectConnection);
    
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::audioDeviceEvent,
                this,
                &CallbacksHandler::slotAudioDeviceEvent,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::audioMeter,
                this,
                &CallbacksHandler::slotAudioMeterReceived,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::swarmLoaded,
                this,
                &CallbacksHandler::slotSwarmLoaded,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::messagesFound,
                this,
                &CallbacksHandler::slotMessagesFound,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::swarmMessageReceived,
                this,
                &CallbacksHandler::slotMessageReceived,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::swarmMessageUpdated,
                this,
                &CallbacksHandler::slotMessageUpdated,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::reactionAdded,
                this,
                &CallbacksHandler::slotReactionAdded,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::reactionRemoved,
                this,
                &CallbacksHandler::slotReactionRemoved,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationProfileUpdated,
                this,
                &CallbacksHandler::slotConversationProfileUpdated,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationRequestReceived,
                this,
                &CallbacksHandler::slotConversationRequestReceived,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationRequestDeclined,
                this,
                &CallbacksHandler::slotConversationRequestDeclined,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationReady,
                this,
                &CallbacksHandler::slotConversationReady,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationRemoved,
                this,
                &CallbacksHandler::slotConversationRemoved,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationMemberEvent,
                this,
                &CallbacksHandler::slotConversationMemberEvent,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::onConversationError,
                this,
                &CallbacksHandler::slotOnConversationError,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::activeCallsChanged,
                this,
                &CallbacksHandler::slotActiveCallsChanged,
                Qt::QueuedConnection);
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::conversationPreferencesUpdated,
                this,
                &CallbacksHandler::slotConversationPreferencesUpdated,
                Qt::QueuedConnection);
    }
    
    CallbacksHandler::~CallbacksHandler() {}
    
    void
    CallbacksHandler::subscribeToDebugReceived()
    {
        connect(&ConfigurationManager::instance(),
                &ConfigurationManagerInterface::messageSend,
                this,
                &CallbacksHandler::slotDebugMessageReceived,
                Qt::QueuedConnection);
    }
    
    void
    CallbacksHandler::slotNewAccountMessage(const QString& accountId,
                                            const QString& peerId,
                                            const QString& msgId,
                                            const MapStringString& payloads)
    {
        auto peerId2 = QString(peerId).replace("@ring.dht", "");
        for (const auto& payload : payloads.keys()) {
            if (payload.contains(APPLICATION_GEO)) {
                Q_EMIT newPosition(accountId, peerId, payloads.value(payload), 0, msgId);
                return;
            }
        }
        Q_EMIT newAccountMessage(accountId, peerId2, msgId, payloads);
    }
    
    void
    CallbacksHandler::slotNewBuddySubscription(const QString& accountId,
                                               const QString& uri,
                                               bool status,
                                               const QString& message)
    {
        Q_UNUSED(status)
        Q_UNUSED(message)
        Q_EMIT newBuddySubscription(accountId, uri, status);
    }
    
    void
    CallbacksHandler::slotNearbyPeerSubscription(const QString& accountId,
                                                 const QString& contactUri,
                                                 int state,
                                                 const QString& displayname)
    {
        Q_EMIT newPeerSubscription(accountId, contactUri, state, displayname);
    }
    
    void
    CallbacksHandler::slotVoiceMailNotify(const QString& accountId,
                                          int newCount,
                                          int oldCount,
                                          int urgentCount)
    {
        Q_EMIT voiceMailNotify(accountId, newCount, oldCount, urgentCount);
    }
    
    void
    CallbacksHandler::slotRecordPlaybackStopped(const QString& filePath)
    {
        Q_EMIT recordPlaybackStopped(filePath);
    }
    
    void
    CallbacksHandler::slotContactAdded(const QString& accountId,
                                       const QString& contactUri,
                                       bool confirmed)
    {
        Q_EMIT contactAdded(accountId, contactUri, confirmed);
    }
    
    void
    CallbacksHandler::slotContactRemoved(const QString& accountId,
                                         const QString& contactUri,
                                         bool banned)
    {
        Q_EMIT contactRemoved(accountId, contactUri, banned);
    }
    
    void
    CallbacksHandler::slotMediaChangeRequested(const QString& accountId,
                                               const QString& callId,
                                               const VectorMapStringString& mediaList)
    {
        Q_EMIT mediaChangeRequested(accountId, callId, mediaList);
    }
    
    void
    CallbacksHandler::slotCallStateChanged(const QString& accountId,
                                           const QString& callId,
                                           const QString& state,
                                           int code)
    {
        Q_EMIT callStateChanged(accountId, callId, state, code);
    }
    
    void
    CallbacksHandler::slotMediaNegotiationStatus(const QString& callId,
                                                 const QString& event,
                                                 const VectorMapStringString& mediaList)
    {
        Q_EMIT mediaNegotiationStatus(callId, event, mediaList);
    }
    
    void
    CallbacksHandler::slotAccountDetailsChanged(const QString& accountId, const MapStringString& details)
    {
        Q_EMIT accountDetailsChanged(accountId, details);
    }
    
    void
    CallbacksHandler::slotVolatileAccountDetailsChanged(const QString& accountId,
                                                        const MapStringString& details)
    {
        Q_EMIT volatileAccountDetailsChanged(accountId, details);
    }
    
    void
    CallbacksHandler::slotAccountsChanged()
    {
        Q_EMIT accountsChanged();
    }
    
    void
    CallbacksHandler::slotRegistrationStateChanged(const QString& accountId,
                                                   const QString& registration_state,
                                                   unsigned detail_code,
                                                   const QString& detail_str)
    {
        (void) detail_code;
        (void) detail_str;
        Q_EMIT accountStatusChanged(accountId, lrc::api::account::to_status(registration_state));
    }
    
    void
    CallbacksHandler::slotIncomingMessage(const QString& accountId,
                                          const QString& callId,
                                          const QString& from,
                                          const MapStringString& interaction)
    {
        QString from2;
        if (from.contains("@ring.dht")) {
            from2 = QString(from).replace("@ring.dht", "");
        } else {
            auto left = from.indexOf(":") + 1;
            auto right = from.indexOf("@");
            from2 = from.mid(left, right - left);
        }
    
        for (auto& e : interaction.toStdMap()) {
            if (e.first.contains("x-ring/ring.profile.vcard")) {
                auto decodedHead = QUrl::fromPercentEncoding(e.first.toLatin1());
                QRegularExpression re(
                    "x-ring/ring.profile.vcard;id=([A-z0-9]+),part=([0-9]+),of=([0-9]+)");
                auto match = re.match(decodedHead);
    
                if (!match.hasMatch())
                    continue;
    
                Q_EMIT incomingVCardChunk(accountId,
                                          callId,
                                          from2,
                                          match.captured(2).toInt(),
                                          match.captured(3).toInt(),
                                          e.second);
            } else if (e.first.contains(TEXT_PLAIN)) { // we consider it as an usual message interaction
                Q_EMIT incomingCallMessage(accountId, callId, from2, e.second);
            }
        }
    }
    
    void
    CallbacksHandler::slotConferenceCreated(const QString& accountId, const QString& callId)
    {
        Q_EMIT conferenceCreated(accountId, callId);
    }
    
    void
    CallbacksHandler::slotConferenceRemoved(const QString& accountId, const QString& callId)
    {
        Q_EMIT conferenceRemoved(accountId, callId);
    }
    
    void
    CallbacksHandler::slotConferenceChanged(const QString& accountId,
                                            const QString& callId,
                                            const QString& state)
    {
        Q_EMIT conferenceChanged(accountId, callId, state);
        slotCallStateChanged(accountId, callId, state, 0);
    }
    
    void
    CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
                                                      const QString& conversationId,
                                                      const QString& peer,
                                                      const QString& messageId,
                                                      int status)
    {
        Q_EMIT accountMessageStatusChanged(accountId, conversationId, peer, messageId, status);
    }
    
    void
    CallbacksHandler::slotNeedsHost(const QString& accountId, const QString& conversationId)
    {
        Q_EMIT needsHost(accountId, conversationId);
    }
    
    void
    CallbacksHandler::slotDataTransferEvent(const QString& accountId,
                                            const QString& conversationId,
                                            const QString&,
                                            const QString& fileId,
                                            uint codeStatus)
    {
        auto event = libjami::DataTransferEventCode(codeStatus);
    
        api::datatransfer::Info info;
        if (conversationId.isEmpty()) {
            return;
        } else {
            info.uid = fileId;
            info.status = convertDataTransferEvent(event);
            info.conversationId = conversationId;
            info.accountId = accountId;
            qlonglong totalSize, progress;
            QString path;
            try {
                parent.getAccountModel().getAccountInfo(accountId).dataTransferModel->fileTransferInfo(
                    accountId, conversationId, fileId, path, totalSize, progress);
            } catch (...) {
                return;
            }
            auto fi = QFileInfo(path);
            if (fi.isSymLink()) {
                path = fi.symLinkTarget();
            }
            info.path = path;
            info.totalSize = totalSize;
            info.progress = progress;
        }
    
        // WARNING: info.status could be INVALID in case of async signaling
        // So listeners must only take account of fileId in such case.
        // Is useful for "termination" status like unjoinable_peer.
    
        switch (event) {
        case libjami::DataTransferEventCode::created:
            Q_EMIT transferStatusCreated(fileId, info);
            break;
        case libjami::DataTransferEventCode::closed_by_host:
        case libjami::DataTransferEventCode::closed_by_peer:
            Q_EMIT transferStatusCanceled(fileId, info);
            break;
        case libjami::DataTransferEventCode::wait_peer_acceptance:
            Q_EMIT transferStatusAwaitingPeer(fileId, info);
            break;
        case libjami::DataTransferEventCode::wait_host_acceptance:
            Q_EMIT transferStatusAwaitingHost(fileId, info);
            break;
        case libjami::DataTransferEventCode::ongoing:
            Q_EMIT transferStatusOngoing(fileId, info);
            break;
        case libjami::DataTransferEventCode::finished:
            Q_EMIT transferStatusFinished(fileId, info);
            break;
        case libjami::DataTransferEventCode::invalid_pathname:
        case libjami::DataTransferEventCode::unsupported:
            Q_EMIT transferStatusError(fileId, info);
            break;
        case libjami::DataTransferEventCode::timeout_expired:
            Q_EMIT transferStatusTimeoutExpired(fileId, info);
            break;
        case libjami::DataTransferEventCode::unjoinable_peer:
            Q_EMIT transferStatusUnjoinable(fileId, info);
            break;
        case libjami::DataTransferEventCode::invalid:
            break;
        }
    }
    
    void
    CallbacksHandler::slotKnownDevicesChanged(const QString& accountId, const MapStringString& devices)
    {
        Q_EMIT knownDevicesChanged(accountId, devices);
    }
    
    void
    CallbacksHandler::slotDeviceRevokationEnded(const QString& accountId,
                                                const QString& deviceId,
                                                const int status)
    {
        Q_EMIT deviceRevocationEnded(accountId, deviceId, status);
    }
    
    void
    CallbacksHandler::slotAccountProfileReceived(const QString& accountId,
                                                 const QString& displayName,
                                                 const QString& userPhoto)
    {
        Q_EMIT accountProfileReceived(accountId, displayName, userPhoto);
    }
    
    void
    CallbacksHandler::slotExportOnRingEnded(const QString& accountId, int status, const QString& pin)
    {
        Q_EMIT exportOnRingEnded(accountId, status, pin);
    }
    
    void
    CallbacksHandler::slotNameRegistrationEnded(const QString& accountId,
                                                int status,
                                                const QString& name)
    {
        Q_EMIT nameRegistrationEnded(accountId, status, name);
    }
    
    void
    CallbacksHandler::slotRegisteredNameFound(const QString& accountId,
                                              int status,
                                              const QString& address,
                                              const QString& name)
    {
        Q_EMIT registeredNameFound(accountId, status, address, name);
    }
    
    void
    CallbacksHandler::slotMigrationEnded(const QString& accountId, const QString& status)
    {
        Q_EMIT migrationEnded(accountId, status == "SUCCESS");
    }
    
    void
    CallbacksHandler::slotDebugMessageReceived(const QString& message)
    {
        Q_EMIT parent.getBehaviorController().debugMessageReceived(message);
    }
    
    void
    CallbacksHandler::slotAudioDeviceEvent()
    {
        Q_EMIT audioDeviceEvent();
    }
    
    void
    CallbacksHandler::slotAudioMeterReceived(const QString& id, float level)
    {
        Q_EMIT audioMeter(id, level);
    }
    
    void
    CallbacksHandler::slotRemoteRecordingChanged(const QString& callId,
                                                 const QString& peerNumber,
                                                 bool state)
    {
        Q_EMIT remoteRecordingChanged(callId, peerNumber, state);
    }
    
    void
    CallbacksHandler::slotSwarmLoaded(uint32_t requestId,
                                      const QString& accountId,
                                      const QString& conversationId,
                                      const VectorSwarmMessage& messages)
    {
        Q_EMIT swarmLoaded(requestId, accountId, conversationId, messages);
    }
    
    void
    CallbacksHandler::slotMessagesFound(uint32_t requestId,
                                        const QString& accountId,
                                        const QString& conversationId,
                                        const VectorMapStringString& messages)
    {
        Q_EMIT messagesFound(requestId, accountId, conversationId, messages);
    }
    
    void
    CallbacksHandler::slotMessageReceived(const QString& accountId,
                                          const QString& conversationId,
                                          const SwarmMessage& message)
    {
        Q_EMIT messageReceived(accountId, conversationId, message);
    }
    
    void
    CallbacksHandler::slotMessageUpdated(const QString& accountId,
                                         const QString& conversationId,
                                         const SwarmMessage& message)
    {
        Q_EMIT messageUpdated(accountId, conversationId, message);
    }
    
    void
    CallbacksHandler::slotReactionAdded(const QString& accountId,
                                        const QString& conversationId,
                                        const QString& messageId,
                                        const MapStringString& reaction)
    {
        Q_EMIT reactionAdded(accountId, conversationId, messageId, reaction);
    }
    
    void
    CallbacksHandler::slotReactionRemoved(const QString& accountId,
                                          const QString& conversationId,
                                          const QString& messageId,
                                          const QString& reactionId)
    {
        Q_EMIT reactionRemoved(accountId, conversationId, messageId, reactionId);
    }
    
    void
    CallbacksHandler::slotConversationProfileUpdated(const QString& accountId,
                                                     const QString& conversationId,
                                                     const MapStringString& profile)
    {
        Q_EMIT conversationProfileUpdated(accountId, conversationId, profile);
    }
    
    void
    CallbacksHandler::slotConversationRequestReceived(const QString& accountId,
                                                      const QString& conversationId,
                                                      const MapStringString& metadatas)
    {
        Q_EMIT conversationRequestReceived(accountId, conversationId, metadatas);
    }
    
    void
    CallbacksHandler::slotConversationRequestDeclined(const QString& accountId,
                                                      const QString& conversationId)
    {
        Q_EMIT conversationRequestDeclined(accountId, conversationId);
    }
    
    void
    CallbacksHandler::slotConversationReady(const QString& accountId, const QString& conversationId)
    {
        Q_EMIT conversationReady(accountId, conversationId);
    }
    
    void
    CallbacksHandler::slotConversationRemoved(const QString& accountId, const QString& conversationId)
    {
        Q_EMIT conversationRemoved(accountId, conversationId);
    }
    
    void
    CallbacksHandler::slotConversationMemberEvent(const QString& accountId,
                                                  const QString& conversationId,
                                                  const QString& memberId,
                                                  int event)
    {
        Q_EMIT conversationMemberEvent(accountId, conversationId, memberId, event);
    }
    
    void
    CallbacksHandler::slotOnConversationError(const QString& accountId,
                                              const QString& conversationId,
                                              int code,
                                              const QString& what)
    {
        Q_EMIT conversationError(accountId, conversationId, code, what);
    }
    
    void
    CallbacksHandler::slotActiveCallsChanged(const QString& accountId,
                                             const QString& conversationId,
                                             const VectorMapStringString& activeCalls)
    {
        Q_EMIT activeCallsChanged(accountId, conversationId, activeCalls);
    }
    
    void
    CallbacksHandler::slotConversationPreferencesUpdated(const QString& accountId,
                                                         const QString& conversationId,
                                                         const MapStringString& preferences)
    {
        Q_EMIT conversationPreferencesUpdated(accountId, conversationId, preferences);
    }
    
    } // namespace lrc