// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>
#include <cctype>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <QAudioOutput>
#include <QGuiApplication>
#include <QUrl>
#include "Cache.h"
#include "CallDevices.h"
#include "CallManager.h"
#include "ChatPage.h"
#include "Logging.h"
#include "MatrixClient.h"
#include "UserSettingsPage.h"
#include "Utils.h"
#include "mtx/responses/turn_server.hpp"
#include "voip/ScreenCastPortal.h"
#include "voip/WebRTCSession.h"
/*
* Select Answer when one instance of the client supports v0
*/
#ifdef XCB_AVAILABLE
#include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h>
#endif
#ifdef Q_OS_WINDOWS
#include <Windows.h>
#endif
#ifdef GSTREAMER_AVAILABLE
extern "C"
{
#include "gst/gst.h"
}
#endif
using namespace mtx::events;
using namespace mtx::events::voip;
using webrtc::CallType;
using webrtc::ScreenShareType;
//! Session Description Object
typedef RTCSessionDescriptionInit SDO;
namespace {
std::vector<std::string>
getTurnURIs(const mtx::responses::TurnServer &turnServer);
}
CallManager *
CallManager::create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
auto instance = ChatPage::instance()->callManager();
Q_ASSERT(instance);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance, QJSEngine::CppOwnership);
return instance;
}
CallManager::CallManager(QObject *parent)
: QObject(parent)
, session_(WebRTCSession::instance())
, turnServerTimer_(this)
{
#ifdef GSTREAMER_AVAILABLE
std::string errorMessage;
if (QGuiApplication::platformName() == QStringLiteral("windows") &&
session_.havePlugins(true, true, ScreenShareType::D3D11, &errorMessage)) {
screenShareType_ = ScreenShareType::D3D11;
screenShareTypes_.push_back(ScreenShareType::D3D11);
} else if (