// SPDX-FileCopyrightText: 2012 George Kiagiadakis // SPDX-FileCopyrightText: 2021 Alexey Andreyev // SPDX-FileCopyrightText: 2022 Bhushan Shah // SPDX-License-Identifier: LGPL-2.1-or-later #include "dialer-manager.h" #include #ifndef LOWER_LIBCALLAUDIO_VERSION #include #endif // LOWER_LIBCALLAUDIO_VERSION #include #include #include #include #include #include "mprisplayerinterface.h" static void enable_call_mode() { #ifdef LOWER_LIBCALLAUDIO_VERSION qWarning() << "callaudio version is not supported"; return; #endif // LOWER_LIBCALLAUDIO_VERSION call_audio_select_mode_async(CALL_AUDIO_MODE_CALL, nullptr, nullptr); } static void enable_default_mode() { #ifdef LOWER_LIBCALLAUDIO_VERSION qWarning() << "callaudio version is not supported"; return; #endif // LOWER_LIBCALLAUDIO_VERSION call_audio_select_mode_async(CALL_AUDIO_MODE_DEFAULT, nullptr, nullptr); } static void mute_mic(bool want_mute) { #ifdef LOWER_LIBCALLAUDIO_VERSION qWarning() << "callaudio version is not supported"; return; #endif // LOWER_LIBCALLAUDIO_VERSION call_audio_mute_mic_async(want_mute, nullptr, nullptr); } static void enable_speaker(bool want_speaker) { #ifdef LOWER_LIBCALLAUDIO_VERSION qWarning() << "callaudio version is not supported"; return; #endif // LOWER_LIBCALLAUDIO_VERSION call_audio_enable_speaker_async(want_speaker, nullptr, nullptr); } DialerManager::DialerManager(QObject *parent) : QObject(parent) , m_needsDefaultAudioMode(false) { GError *err = nullptr; if (!call_audio_init(&err)) { qWarning() << "Failed to init callaudio" << err->message; } } DialerManager::~DialerManager() { enable_default_mode(); call_audio_deinit(); qDebug() << "Deleting DialerManager"; } void DialerManager::setCallUtils(org::kde::telephony::CallUtils *callUtils) { m_callUtils = callUtils; connect(m_callUtils, &org::kde::telephony::CallUtils::callAdded, this, &DialerManager::onUtilsCallAdded); connect(m_callUtils, &org::kde::telephony::CallUtils::callsChanged, this, &DialerManager::onUtilsCallsChanged); connect(m_callUtils, &org::kde::telephony::CallUtils::callStateChanged, this, &DialerManager::onUtilsCallStateChanged); } void DialerManager::setDialerUtils(DialerUtils *dialerUtils) { qDebug() << Q_FUNC_INFO; m_dialerUtils = dialerUtils; connect(m_dialerUtils, &DialerUtils::muteChanged, this, &DialerManager::onUtilsMuteChanged); connect(m_dialerUtils, &DialerUtils::speakerModeChanged, this, &DialerManager::onUtilsSpeakerModeChanged); connect(m_dialerUtils, &DialerUtils::muteRequested, this, &DialerManager::onUtilsMuteRequested); connect(m_dialerUtils, &DialerUtils::speakerModeRequested, this, &DialerManager::onUtilsSpeakerModeRequested); m_dialerUtils->fetchMute(); m_dialerUtils->fetchSpeakerMode(); } void DialerManager::onUtilsCallAdded(const QString &deviceUni, const QString &callUni, const DialerTypes::CallDirection &callDirection, const DialerTypes::CallState &callState, const DialerTypes::CallStateReason &callStateReason, const QString communicationWith) { Q_UNUSED(communicationWith); if (!m_callUtils) { qCritical() << Q_FUNC_INFO; } qDebug() << Q_FUNC_INFO << "call added" << deviceUni << callUni << callDirection << callState << callStateReason; if (callDirection == DialerTypes::CallDirection::Incoming) { if (callState == DialerTypes::CallState::RingingIn) { pauseMedia(); } } } void DialerManager::onUtilsCallsChanged(const DialerTypes::CallDataVector &calls) { if (calls.isEmpty()) { unpauseMedia(); } } void DialerManager::onUtilsCallStateChanged(const DialerTypes::CallData &callData) { if (!m_callUtils) { qCritical() << Q_FUNC_INFO; } qDebug() << Q_FUNC_INFO << "new call state:" << callData.state; switch (callData.state) { case DialerTypes::CallState::Active: enable_call_mode(); m_needsDefaultAudioMode = true; break; case DialerTypes::CallState::Terminated: if (m_needsDefaultAudioMode) { enable_default_mode(); m_needsDefaultAudioMode = false; } break; default: break; } } void DialerManager::onUtilsSpeakerModeRequested() { #ifdef LOWER_LIBCALLAUDIO_VERSION qWarning() << "callaudio version is not supported"; return; #else // LOWER_LIBCALLAUDIO_VERSION bool speakerMode = call_audio_get_speaker_state() == CALL_AUDIO_SPEAKER_ON; m_dialerUtils->setSpeakerMode(speakerMode); #endif // LOWER_LIBCALLAUDIO_VERSION } void DialerManager::onUtilsMuteRequested() { #ifdef LOWER_LIBCALLAUDIO_VERSION qWarning() << "callaudio version is not supported"; return; #else // LOWER_LIBCALLAUDIO_VERSION auto micMute = call_audio_get_mic_state() == CALL_AUDIO_MIC_OFF; m_dialerUtils->setMute(micMute); #endif // LOWER_LIBCALLAUDIO_VERSION } void DialerManager::onUtilsSpeakerModeChanged(bool enabled) { enable_speaker(enabled); } void DialerManager::onUtilsMuteChanged(bool muted) { mute_mic(muted); } void DialerManager::pauseMedia() { auto sessionBus = QDBusConnection::sessionBus(); const QStringList interfaces = sessionBus.interface()->registeredServiceNames().value(); for (const QString &iface : interfaces) { if (iface.startsWith(QLatin1String("org.mpris.MediaPlayer2"))) { if (iface.contains(QLatin1String("kdeconnect"))) { qDebug() << Q_FUNC_INFO << "Skip players connected over KDE Connect. KDE Connect pauses them itself"; continue; } qDebug() << Q_FUNC_INFO << "Found player:" << iface; org::mpris::MediaPlayer2::Player mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), sessionBus); QString status = mprisInterface.playbackStatus(); qDebug() << Q_FUNC_INFO << "Found player status:" << iface << status; if (status == QLatin1String("Playing")) { if (!m_pausedSources.contains(iface)) { m_pausedSources.insert(iface); if (mprisInterface.canPause()) { mprisInterface.Pause(); } else { mprisInterface.Stop(); } } } } } } void DialerManager::unpauseMedia() { auto sessionBus = QDBusConnection::sessionBus(); for (const QString &iface : std::as_const(m_pausedSources)) { org::mpris::MediaPlayer2::Player mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), sessionBus); mprisInterface.Play(); } m_pausedSources.clear(); }