File indexing completed on 2024-04-28 16:42:51

0001 // SPDX-FileCopyrightText: 2012 George Kiagiadakis <kiagiadakis.george@gmail.com>
0002 // SPDX-FileCopyrightText: 2021 Alexey Andreyev <aa13q@ya.ru>
0003 // SPDX-FileCopyrightText: 2022 Bhushan Shah <bshah@kde.org>
0004 // SPDX-License-Identifier: LGPL-2.1-or-later
0005 
0006 #include "dialer-manager.h"
0007 
0008 #include <glib.h>
0009 
0010 #ifndef LOWER_LIBCALLAUDIO_VERSION
0011 #include <libcallaudio-enums.h>
0012 #endif // LOWER_LIBCALLAUDIO_VERSION
0013 #include <libcallaudio.h>
0014 
0015 #include <KLocalizedString>
0016 #include <QDBusConnection>
0017 #include <QDBusMessage>
0018 
0019 #include <QDebug>
0020 
0021 #include "mprisplayerinterface.h"
0022 
0023 static void enable_call_mode()
0024 {
0025 #ifdef LOWER_LIBCALLAUDIO_VERSION
0026     qWarning() << "callaudio version is not supported";
0027     return;
0028 #endif // LOWER_LIBCALLAUDIO_VERSION
0029     call_audio_select_mode_async(CALL_AUDIO_MODE_CALL, nullptr, nullptr);
0030 }
0031 
0032 static void enable_default_mode()
0033 {
0034 #ifdef LOWER_LIBCALLAUDIO_VERSION
0035     qWarning() << "callaudio version is not supported";
0036     return;
0037 #endif // LOWER_LIBCALLAUDIO_VERSION
0038     call_audio_select_mode_async(CALL_AUDIO_MODE_DEFAULT, nullptr, nullptr);
0039 }
0040 
0041 static void mute_mic(bool want_mute)
0042 {
0043 #ifdef LOWER_LIBCALLAUDIO_VERSION
0044     qWarning() << "callaudio version is not supported";
0045     return;
0046 #endif // LOWER_LIBCALLAUDIO_VERSION
0047     call_audio_mute_mic_async(want_mute, nullptr, nullptr);
0048 }
0049 
0050 static void enable_speaker(bool want_speaker)
0051 {
0052 #ifdef LOWER_LIBCALLAUDIO_VERSION
0053     qWarning() << "callaudio version is not supported";
0054     return;
0055 #endif // LOWER_LIBCALLAUDIO_VERSION
0056     call_audio_enable_speaker_async(want_speaker, nullptr, nullptr);
0057 }
0058 
0059 DialerManager::DialerManager(QObject *parent)
0060     : QObject(parent)
0061     , _needsDefaultAudioMode(false)
0062 {
0063     GError *err = nullptr;
0064     if (!call_audio_init(&err)) {
0065         qWarning() << "Failed to init callaudio" << err->message;
0066     }
0067 }
0068 
0069 DialerManager::~DialerManager()
0070 {
0071     enable_default_mode();
0072     call_audio_deinit();
0073     qDebug() << "Deleting DialerManager";
0074 }
0075 
0076 void DialerManager::setCallUtils(org::kde::telephony::CallUtils *callUtils)
0077 {
0078     _callUtils = callUtils;
0079 
0080     connect(_callUtils, &org::kde::telephony::CallUtils::callAdded, this, &DialerManager::onUtilsCallAdded);
0081     connect(_callUtils, &org::kde::telephony::CallUtils::callsChanged, this, &DialerManager::onUtilsCallsChanged);
0082     connect(_callUtils, &org::kde::telephony::CallUtils::callStateChanged, this, &DialerManager::onUtilsCallStateChanged);
0083 }
0084 
0085 void DialerManager::setDialerUtils(DialerUtils *dialerUtils)
0086 {
0087     qDebug() << Q_FUNC_INFO;
0088     _dialerUtils = dialerUtils;
0089 
0090     connect(_dialerUtils, &DialerUtils::muteChanged, this, &DialerManager::onUtilsMuteChanged);
0091     connect(_dialerUtils, &DialerUtils::speakerModeChanged, this, &DialerManager::onUtilsSpeakerModeChanged);
0092 
0093     connect(_dialerUtils, &DialerUtils::muteRequested, this, &DialerManager::onUtilsMuteRequested);
0094     connect(_dialerUtils, &DialerUtils::speakerModeRequested, this, &DialerManager::onUtilsSpeakerModeRequested);
0095 
0096     _dialerUtils->fetchMute();
0097     _dialerUtils->fetchSpeakerMode();
0098 }
0099 
0100 void DialerManager::onUtilsCallAdded(const QString &deviceUni,
0101                                      const QString &callUni,
0102                                      const DialerTypes::CallDirection &callDirection,
0103                                      const DialerTypes::CallState &callState,
0104                                      const DialerTypes::CallStateReason &callStateReason,
0105                                      const QString communicationWith)
0106 {
0107     if (!_callUtils) {
0108         qCritical() << Q_FUNC_INFO;
0109     }
0110     qDebug() << Q_FUNC_INFO << "call added" << deviceUni << callUni << callDirection << callState << callStateReason;
0111 
0112     if (callDirection == DialerTypes::CallDirection::Incoming) {
0113         if (callState == DialerTypes::CallState::RingingIn) {
0114             pauseMedia();
0115         }
0116     }
0117 }
0118 
0119 void DialerManager::onUtilsCallsChanged(const DialerTypes::CallDataVector &calls)
0120 {
0121     if (calls.isEmpty()) {
0122         unpauseMedia();
0123     }
0124 }
0125 
0126 void DialerManager::onUtilsCallStateChanged(const DialerTypes::CallData &callData)
0127 {
0128     if (!_callUtils) {
0129         qCritical() << Q_FUNC_INFO;
0130     }
0131     qDebug() << Q_FUNC_INFO << "new call state:" << callData.state;
0132     switch (callData.state) {
0133     case DialerTypes::CallState::Active:
0134         enable_call_mode();
0135         _needsDefaultAudioMode = true;
0136         break;
0137     case DialerTypes::CallState::Terminated:
0138         if (_needsDefaultAudioMode) {
0139             enable_default_mode();
0140             _needsDefaultAudioMode = false;
0141         }
0142 
0143         break;
0144     default:
0145         break;
0146     }
0147 }
0148 
0149 void DialerManager::onUtilsSpeakerModeRequested()
0150 {
0151 #ifdef LOWER_LIBCALLAUDIO_VERSION
0152     qWarning() << "callaudio version is not supported";
0153     return;
0154 #else // LOWER_LIBCALLAUDIO_VERSION
0155     bool speakerMode = call_audio_get_speaker_state() == CALL_AUDIO_SPEAKER_ON;
0156     _dialerUtils->setSpeakerMode(speakerMode);
0157 #endif // LOWER_LIBCALLAUDIO_VERSION
0158 }
0159 
0160 void DialerManager::onUtilsMuteRequested()
0161 {
0162 #ifdef LOWER_LIBCALLAUDIO_VERSION
0163     qWarning() << "callaudio version is not supported";
0164     return;
0165 #else // LOWER_LIBCALLAUDIO_VERSION
0166     auto micMute = call_audio_get_mic_state() == CALL_AUDIO_MIC_OFF;
0167     _dialerUtils->setMute(micMute);
0168 #endif // LOWER_LIBCALLAUDIO_VERSION
0169 }
0170 
0171 void DialerManager::onUtilsSpeakerModeChanged(bool enabled)
0172 {
0173     enable_speaker(enabled);
0174 }
0175 
0176 void DialerManager::onUtilsMuteChanged(bool muted)
0177 {
0178     mute_mic(muted);
0179 }
0180 
0181 void DialerManager::pauseMedia()
0182 {
0183     auto sessionBus = QDBusConnection::sessionBus();
0184     const QStringList interfaces = sessionBus.interface()->registeredServiceNames().value();
0185     for (const QString &iface : interfaces) {
0186         if (iface.startsWith(QLatin1String("org.mpris.MediaPlayer2"))) {
0187             if (iface.contains(QLatin1String("kdeconnect"))) {
0188                 qDebug() << Q_FUNC_INFO << "Skip players connected over KDE Connect. KDE Connect pauses them itself";
0189                 continue;
0190             }
0191             qDebug() << Q_FUNC_INFO << "Found player:" << iface;
0192 
0193             org::mpris::MediaPlayer2::Player mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), sessionBus);
0194             QString status = mprisInterface.playbackStatus();
0195             qDebug() << Q_FUNC_INFO << "Found player status:" << iface << status;
0196             if (status == QLatin1String("Playing")) {
0197                 if (!_pausedSources.contains(iface)) {
0198                     _pausedSources.insert(iface);
0199                     if (mprisInterface.canPause()) {
0200                         mprisInterface.Pause();
0201                     } else {
0202                         mprisInterface.Stop();
0203                     }
0204                 }
0205             }
0206         }
0207     }
0208 }
0209 
0210 void DialerManager::unpauseMedia()
0211 {
0212     auto sessionBus = QDBusConnection::sessionBus();
0213     for (const QString &iface : qAsConst(_pausedSources)) {
0214         org::mpris::MediaPlayer2::Player mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), sessionBus);
0215         mprisInterface.Play();
0216     }
0217     _pausedSources.clear();
0218 }