File indexing completed on 2025-03-23 13:45:10
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 }