callbackshandler.cpp 18.7 KB
Newer Older
Nicolas Jager's avatar
Nicolas Jager committed
1
/****************************************************************************
2
 *    Copyright (C) 2017-2020 Savoir-faire Linux Inc.                       *
3 4
 *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
 *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
Nicolas Jager's avatar
Nicolas Jager committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *                                                                          *
 *   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"

21
// Models and database
22
#include "api/account.h"
23 24
#include "api/lrc.h"
#include "api/newaccountmodel.h"
Anthony Léonard's avatar
Anthony Léonard committed
25
#include "api/datatransfermodel.h"
26
#include "api/behaviorcontroller.h"
27

28 29
// Lrc
#include "dbus/callmanager.h"
30 31
#include "dbus/configurationmanager.h"
#include "dbus/presencemanager.h"
Sébastien Blin's avatar
Sébastien Blin committed
32
#include "dbus/videomanager.h"
33

Nicolas Jager's avatar
Nicolas Jager committed
34 35 36
// DRing
#include <datatransfer_interface.h>

37 38 39 40 41 42
#ifdef ENABLE_LIBWRAP
// For the debugMessageReceived connection that queues const std::string refs
// when not using dbus
Q_DECLARE_METATYPE(std::string);
#endif

Nicolas Jager's avatar
Nicolas Jager committed
43 44 45
namespace lrc
{

46 47 48
using namespace api;

CallbacksHandler::CallbacksHandler(const Lrc& parent)
Nicolas Jager's avatar
Nicolas Jager committed
49
: QObject()
50
, parent(parent)
Nicolas Jager's avatar
Nicolas Jager committed
51
{
52 53 54 55
    // Get signals from daemon
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::incomingAccountMessage,
            this,
56 57
            &CallbacksHandler::slotNewAccountMessage,
            Qt::QueuedConnection);
58 59 60 61

    connect(&PresenceManager::instance(),
            &PresenceManagerInterface::newBuddyNotification,
            this,
62 63
            &CallbacksHandler::slotNewBuddySubscription,
            Qt::QueuedConnection);
Nicolas Jager's avatar
Nicolas Jager committed
64

65 66 67 68 69 70
    connect(&PresenceManager::instance(),
            &PresenceManagerInterface::nearbyPeerNotification,
            this,
            &CallbacksHandler::slotNearbyPeerSubscription,
            Qt::QueuedConnection);

71 72 73
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::contactAdded,
            this,
74 75
            &CallbacksHandler::slotContactAdded,
            Qt::QueuedConnection);
76 77 78 79

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::contactRemoved,
            this,
80 81
            &CallbacksHandler::slotContactRemoved,
            Qt::QueuedConnection);
82 83 84 85

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::incomingTrustRequest,
            this,
86 87
            &CallbacksHandler::slotIncomingContactRequest,
            Qt::QueuedConnection);
88 89 90 91

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountMessageStatusChanged,
            this,
92 93
            &CallbacksHandler::slotAccountMessageStatusChanged,
            Qt::QueuedConnection);
94

95 96 97
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountDetailsChanged,
            this,
98 99
            &CallbacksHandler::slotAccountDetailsChanged,
            Qt::QueuedConnection);
100

101 102 103 104 105 106
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::volatileAccountDetailsChanged,
            this,
            &CallbacksHandler::slotVolatileAccountDetailsChanged,
            Qt::QueuedConnection);

107 108 109 110 111
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountsChanged,
            this,
            &CallbacksHandler::slotAccountsChanged);

112 113 114
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::registrationStateChanged,
            this,
115 116
            &CallbacksHandler::slotRegistrationStateChanged,
            Qt::QueuedConnection);
117 118 119 120

    connect(&CallManager::instance(),
            &CallManagerInterface::incomingCall,
            this,
121 122
            &CallbacksHandler::slotIncomingCall,
            Qt::QueuedConnection);
123 124 125 126

    connect(&CallManager::instance(),
            &CallManagerInterface::callStateChanged,
            this,
127 128
            &CallbacksHandler::slotCallStateChanged,
            Qt::QueuedConnection);
129

130 131 132
    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceCreated,
            this,
133 134
            &CallbacksHandler::slotConferenceCreated,
            Qt::QueuedConnection);
135 136 137 138

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceRemoved,
            this,
139 140
            &CallbacksHandler::slotConferenceRemoved,
            Qt::QueuedConnection);
141 142 143 144

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceChanged,
            this,
145 146
            &CallbacksHandler::slotConferenceChanged,
            Qt::QueuedConnection);
147

148 149 150
    connect(&CallManager::instance(),
            &CallManagerInterface::incomingMessage,
            this,
151 152
            &CallbacksHandler::slotIncomingMessage,
            Qt::QueuedConnection);
Nicolas Jager's avatar
Nicolas Jager committed
153

154 155 156 157 158 159
    connect(&CallManager::instance(),
            &CallManagerInterface::recordPlaybackStopped,
            this,
            &CallbacksHandler::slotRecordPlaybackStopped,
            Qt::QueuedConnection);

160 161 162 163 164 165
    connect(&CallManager::instance(),
            &CallManagerInterface::voiceMailNotify,
            this,
            &CallbacksHandler::slotVoiceMailNotify,
            Qt::QueuedConnection);

Nicolas Jager's avatar
Nicolas Jager committed
166 167 168
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::dataTransferEvent,
            this,
169 170
            &CallbacksHandler::slotDataTransferEvent,
            Qt::QueuedConnection);
171 172 173 174

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::knownDevicesChanged,
            this,
175 176
            &CallbacksHandler::slotKnownDevicesChanged,
            Qt::QueuedConnection);
177 178 179 180

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::deviceRevocationEnded,
            this,
181 182
            &CallbacksHandler::slotDeviceRevokationEnded,
            Qt::QueuedConnection);
183

184
    connect(&ConfigurationManager::instance(),
185
            &ConfigurationManagerInterface::accountProfileReceived,
186
            this,
187
            &CallbacksHandler::slotAccountProfileReceived,
188 189
            Qt::QueuedConnection);

190 191 192
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::exportOnRingEnded,
            this,
193 194
            &CallbacksHandler::slotExportOnRingEnded,
            Qt::QueuedConnection);
195 196 197 198

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::nameRegistrationEnded,
            this,
199 200
            &CallbacksHandler::slotNameRegistrationEnded,
            Qt::QueuedConnection);
201 202 203 204

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::registeredNameFound,
            this,
205 206
            &CallbacksHandler::slotRegisteredNameFound,
            Qt::QueuedConnection);
207 208 209 210

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::migrationEnded,
            this,
211 212
            &CallbacksHandler::slotMigrationEnded,
            Qt::QueuedConnection);
213

Sébastien Blin's avatar
Sébastien Blin committed
214 215 216 217 218 219 220 221 222 223 224
    connect(&VideoManager::instance(),
            &VideoManagerInterface::startedDecoding,
            this,
            &CallbacksHandler::slotStartedDecoding,
            Qt::QueuedConnection);

    connect(&VideoManager::instance(),
            &VideoManagerInterface::stoppedDecoding,
            this,
            &CallbacksHandler::slotStoppedDecoding,
            Qt::QueuedConnection);
225 226 227 228 229 230

    connect(&VideoManager::instance(),
            &VideoManagerInterface::deviceEvent,
            this,
            &CallbacksHandler::slotDeviceEvent,
            Qt::QueuedConnection);
231 232 233 234 235 236

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::audioMeter,
            this,
            &CallbacksHandler::slotAudioMeterReceived,
            Qt::QueuedConnection);
Nicolas Jager's avatar
Nicolas Jager committed
237 238 239 240
}

CallbacksHandler::~CallbacksHandler()
{
241
}
Nicolas Jager's avatar
Nicolas Jager committed
242

243 244 245 246 247 248 249 250
void
CallbacksHandler::subscribeToDebugReceived()
{
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::debugMessageReceived,
            this,
            &CallbacksHandler::slotDebugMessageReceived,
            Qt::QueuedConnection);
Nicolas Jager's avatar
Nicolas Jager committed
251 252 253 254
}

void
CallbacksHandler::slotNewAccountMessage(const QString& accountId,
255
                                        const QString& msgId,
Nicolas Jager's avatar
Nicolas Jager committed
256
                                        const QString& from,
257
                                        const MapStringString& payloads)
Nicolas Jager's avatar
Nicolas Jager committed
258
{
259 260
    auto from2 = QString(from).replace("@ring.dht", "");
    emit newAccountMessage(accountId, msgId, from2, payloads);
Nicolas Jager's avatar
Nicolas Jager committed
261 262 263 264 265 266 267 268
}

void
CallbacksHandler::slotNewBuddySubscription(const QString& accountId,
                                           const QString& uri,
                                           bool status,
                                           const QString& message)
{
269 270 271
    Q_UNUSED(accountId)
    Q_UNUSED(status)
    Q_UNUSED(message)
272
    emit newBuddySubscription(uri, status);
273
}
Nicolas Jager's avatar
Nicolas Jager committed
274

275 276 277 278 279 280
void
CallbacksHandler::slotNearbyPeerSubscription(const QString& accountId,
                                             const QString& contactUri,
                                             int state,
                                             const QString& displayname)
{
281
    emit newPeerSubscription(accountId, contactUri, state, displayname);
282 283
}

284 285 286
void
CallbacksHandler::slotVoiceMailNotify(const QString& accountId, int newCount, int oldCount, int urgentCount)
{
287
    emit voiceMailNotify(accountId, newCount, oldCount, urgentCount);
288 289
}

290 291 292
void
CallbacksHandler::slotRecordPlaybackStopped(const QString& filePath)
{
293
    emit recordPlaybackStopped(filePath);
294 295
}

296 297 298 299 300
void
CallbacksHandler::slotContactAdded(const QString& accountId,
                                   const QString& contactUri,
                                   bool confirmed)
{
301
    emit contactAdded(accountId, contactUri, confirmed);
302 303 304 305 306 307 308
}

void
CallbacksHandler::slotContactRemoved(const QString& accountId,
                                     const QString& contactUri,
                                     bool banned)
{
309
    emit contactRemoved(accountId, contactUri, banned);
Nicolas Jager's avatar
Nicolas Jager committed
310 311
}

312 313 314 315 316 317 318
void
CallbacksHandler::slotIncomingContactRequest(const QString& accountId,
                                             const QString& ringId,
                                             const QByteArray& payload,
                                             time_t time)
{
    Q_UNUSED(time)
319
    emit incomingContactRequest(accountId, ringId, payload);
320 321 322 323 324
}

void
CallbacksHandler::slotIncomingCall(const QString &accountId, const QString &callId, const QString &fromUri)
{
325 326
    QString displayname;
    QString fromQString;
327
    if (fromUri.contains("ring.dht")) {
328 329
        auto qDisplayname = fromUri.left(fromUri.indexOf("<") + 1);
        if (qDisplayname.size() > 2) {
330
            displayname = qDisplayname.left(qDisplayname.indexOf("<") - 1);
331
        }
332
        fromQString = fromUri.right(50);
333 334
        fromQString = fromQString.left(40);
    } else {
335
        auto left = fromUri.indexOf("<") + 1;
336
        auto right = fromUri.indexOf("@");
337 338
        fromQString = fromUri.mid(left, right-left);
        displayname = fromUri.left(fromUri.indexOf("<") - 1);
339
    }
340
    emit incomingCall(accountId, callId, fromQString, displayname);
341 342 343 344 345
}

void
CallbacksHandler::slotCallStateChanged(const QString& callId, const QString& state, int code)
{
346
    emit callStateChanged(callId, state, code);
347 348
}

349 350 351 352
void
CallbacksHandler::slotAccountDetailsChanged(const QString& accountId,
                                            const MapStringString& details)
{
353
    emit accountDetailsChanged(accountId, details);
354 355
}

356 357 358 359
void
CallbacksHandler::slotVolatileAccountDetailsChanged(const QString& accountId,
                                                    const MapStringString& details)
{
360
    emit volatileAccountDetailsChanged(accountId, details);
361 362
}

363 364 365 366 367 368
void
CallbacksHandler::slotAccountsChanged()
{
    emit accountsChanged();
}

369 370 371 372 373 374
void
CallbacksHandler::slotRegistrationStateChanged(const QString& accountId,
                                               const QString& registration_state,
                                               unsigned detail_code,
                                               const QString& detail_str)
{
Anthony Léonard's avatar
Anthony Léonard committed
375 376
    (void) detail_code;
    (void) detail_str;
377
    emit accountStatusChanged(accountId, lrc::api::account::to_status(registration_state));
378 379 380 381 382
}

void
CallbacksHandler::slotIncomingMessage(const QString& callId,
                                      const QString& from,
383
                                      const MapStringString& interaction)
384
{
385
    QString from2;
386
    if (from.contains("@ring.dht")) {
387
        from2 = QString(from).replace("@ring.dht", "");
388
    } else {
389 390
        auto left = from.indexOf(":")+1;
        auto right = from.indexOf("@");
391
        from2 = from.mid(left, right-left);
392 393 394 395 396 397 398 399
    }

    for (auto& e : interaction.toStdMap()) {
        if (e.first.contains("x-ring/ring.profile.vcard")) {
            auto pieces0 = e.first.split( ";" );
            auto pieces1 = pieces0[1].split( "," );
            auto pieces2 = pieces1[1].split( "=" );
            auto pieces3 = pieces1[2].split( "=" );
400
            emit incomingVCardChunk(callId,
401 402 403
                                    from2,
                                    pieces2[1].toInt(),
                                    pieces3[1].toInt(),
404
                                    e.second);
405
        } else if (e.first.contains("text/plain")) { // we consider it as an usual message interaction
406
            emit incomingCallMessage(callId, from2, e.second);
407 408 409 410
        }
    }
}

411 412 413
void
CallbacksHandler::slotConferenceCreated(const QString& callId)
{
414
    emit conferenceCreated(callId);
415 416 417 418 419 420 421 422 423 424 425
}

void
CallbacksHandler::slotConferenceChanged(const QString& callId, const QString& state)
{
    slotCallStateChanged(callId, state, 0);
}

void
CallbacksHandler::slotConferenceRemoved(const QString& callId)
{
426
    emit conferenceRemoved(callId);
427 428
}

429 430 431 432 433
void
CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
                                                  const uint64_t id,
                                                  const QString& to, int status)
{
434 435
    emit accountMessageStatusChanged(accountId, id,
                                     to, status);
436 437
}

Nicolas Jager's avatar
Nicolas Jager committed
438
void
Nicolas Jager's avatar
Nicolas Jager committed
439
CallbacksHandler::slotDataTransferEvent(qulonglong dringId, uint codeStatus)
Nicolas Jager's avatar
Nicolas Jager committed
440
{
Nicolas Jager's avatar
Nicolas Jager committed
441 442
    auto event = DRing::DataTransferEventCode(codeStatus);

Anthony Léonard's avatar
Anthony Léonard committed
443 444 445 446 447 448 449
    api::datatransfer::Info info;
    parent.getDataTransferModel().transferInfo(dringId, info);

    // WARNING: info.status could be INVALID in case of async signaling
    // So listeners must only take account of dringId in such case.
    // Is useful for "termination" status like unjoinable_peer.

Nicolas Jager's avatar
Nicolas Jager committed
450 451
    switch (event) {
    case DRing::DataTransferEventCode::created:
Anthony Léonard's avatar
Anthony Léonard committed
452
        emit transferStatusCreated(static_cast<long long>(dringId), info);
Nicolas Jager's avatar
Nicolas Jager committed
453 454 455
        break;
    case DRing::DataTransferEventCode::closed_by_host:
    case DRing::DataTransferEventCode::closed_by_peer:
Anthony Léonard's avatar
Anthony Léonard committed
456
        emit transferStatusCanceled(static_cast<long long>(dringId), info);
Nicolas Jager's avatar
Nicolas Jager committed
457 458
        break;
    case DRing::DataTransferEventCode::wait_peer_acceptance:
459 460
        emit transferStatusAwaitingPeer(static_cast<long long>(dringId), info);
        break;
Nicolas Jager's avatar
Nicolas Jager committed
461
    case DRing::DataTransferEventCode::wait_host_acceptance:
462
        emit transferStatusAwaitingHost(static_cast<long long>(dringId), info);
Nicolas Jager's avatar
Nicolas Jager committed
463 464
        break;
    case DRing::DataTransferEventCode::ongoing:
Anthony Léonard's avatar
Anthony Léonard committed
465
        emit transferStatusOngoing(static_cast<long long>(dringId), info);
Nicolas Jager's avatar
Nicolas Jager committed
466 467
        break;
    case DRing::DataTransferEventCode::finished:
Anthony Léonard's avatar
Anthony Léonard committed
468
        emit transferStatusFinished(static_cast<long long>(dringId), info);
Nicolas Jager's avatar
Nicolas Jager committed
469 470 471
        break;
    case DRing::DataTransferEventCode::invalid_pathname:
    case DRing::DataTransferEventCode::unsupported:
Anthony Léonard's avatar
Anthony Léonard committed
472
        emit transferStatusError(static_cast<long long>(dringId), info);
Nicolas Jager's avatar
Nicolas Jager committed
473
        break;
474 475 476
    case DRing::DataTransferEventCode::timeout_expired:
        emit transferStatusTimeoutExpired(static_cast<long long>(dringId), info);
        break;
477 478 479
    case DRing::DataTransferEventCode::unjoinable_peer:
        emit transferStatusUnjoinable(static_cast<long long>(dringId), info);
        break;
Sébastien Blin's avatar
Sébastien Blin committed
480 481
    case DRing::DataTransferEventCode::invalid:
        break;
Nicolas Jager's avatar
Nicolas Jager committed
482
    }
Nicolas Jager's avatar
Nicolas Jager committed
483 484
}

485 486
void
CallbacksHandler::slotKnownDevicesChanged(const QString& accountId,
487
                                          const MapStringString& devices)
488
{
489
    emit knownDevicesChanged(accountId, devices);
490 491 492 493 494 495 496
}

void
CallbacksHandler::slotDeviceRevokationEnded(const QString& accountId,
                                            const QString& deviceId,
                                            const int status)
{
497
    emit deviceRevocationEnded(accountId, deviceId, status);
498 499
}

500
void
501 502 503
CallbacksHandler::slotAccountProfileReceived(const QString& accountId,
                                             const QString& displayName,
                                             const QString& userPhoto)
504
{
505
    emit accountProfileReceived(accountId, displayName, userPhoto);
506 507
}

508 509 510
void
CallbacksHandler::slotExportOnRingEnded(const QString& accountId, int status, const QString& pin)
{
511
    emit exportOnRingEnded(accountId, status, pin);
512 513
}

514 515 516
void
CallbacksHandler::slotNameRegistrationEnded(const QString& accountId, int status, const QString& name)
{
517
    emit nameRegistrationEnded(accountId, status, name);
518 519 520 521 522
}

void
CallbacksHandler::slotRegisteredNameFound(const QString& accountId, int status, const QString& address, const QString& name)
{
523
    emit registeredNameFound(accountId, status, address, name);
524 525
}

526 527 528
void
CallbacksHandler::slotMigrationEnded(const QString& accountId, const QString& status)
{
529
    emit migrationEnded(accountId, status == "SUCCESS");
530
}
531

532 533 534
void
CallbacksHandler::slotDebugMessageReceived(const QString& message)
{
535
    emit parent.getBehaviorController().debugMessageReceived(message);
536 537
}

Sébastien Blin's avatar
Sébastien Blin committed
538 539 540
void
CallbacksHandler::slotStartedDecoding(const QString& id, const QString& shmPath, int width, int height)
{
541
    emit startedDecoding(id, shmPath, width, height);
Sébastien Blin's avatar
Sébastien Blin committed
542 543 544 545 546
}

void
CallbacksHandler::slotStoppedDecoding(const QString& id, const QString& shmPath)
{
547
    emit stoppedDecoding(id, shmPath);
Sébastien Blin's avatar
Sébastien Blin committed
548 549
}

550 551 552 553 554 555
void
CallbacksHandler::slotDeviceEvent()
{
    emit deviceEvent();
}

556 557 558
void
CallbacksHandler::slotAudioMeterReceived(const QString& id, float level)
{
559
    emit audioMeter(id, level);
560
}
Sébastien Blin's avatar
Sébastien Blin committed
561

Nicolas Jager's avatar
Nicolas Jager committed
562
} // namespace lrc