File indexing completed on 2024-04-28 16:42:53
0001 // SPDX-FileCopyrightText: 2012 George Kiagiadakis <kiagiadakis.george@gmail.com> 0002 // SPDX-FileCopyrightText: 2021 Alexey Andreyev <aa13q@ya.ru> 0003 // 0004 // SPDX-License-Identifier: LGPL-2.1-or-later 0005 0006 #include "call-manager.h" 0007 0008 #include <QCoreApplication> 0009 #include <QDBusConnection> 0010 #include <QDBusInterface> 0011 #include <QDBusReply> 0012 #include <QDebug> 0013 #include <QStringLiteral> 0014 0015 #include "call-utils.h" 0016 #include "modem-controller.h" 0017 0018 CallManager::CallManager(ModemController *modemController, CallUtils *callUtils, QObject *parent) 0019 : QObject(parent) 0020 { 0021 _modemController = modemController; 0022 _callUtils = callUtils; 0023 0024 connect(_modemController, &ModemController::callStateChanged, this, &CallManager::onCallStateChanged); 0025 connect(_modemController, &ModemController::callAdded, this, &CallManager::onCallAdded); 0026 connect(_modemController, &ModemController::callDeleted, this, &CallManager::onCallDeleted); 0027 0028 connect(_callUtils, &CallUtils::dialed, this, &CallManager::onUtilsCreatedCall); 0029 connect(_callUtils, &CallUtils::accepted, this, &CallManager::onUtilsAccepted); 0030 connect(_callUtils, &CallUtils::hungUp, this, &CallManager::onUtilsHungUp); 0031 connect(_callUtils, &CallUtils::sentDtmf, this, &CallManager::onUtilsSentDtmf); 0032 0033 connect(_callUtils, &CallUtils::callsRequested, this, &CallManager::onUtilsCallsRequested); 0034 0035 callUtils->fetchCalls(); 0036 } 0037 0038 void CallManager::onCallAdded(const QString &deviceUni, 0039 const QString &callUni, 0040 const DialerTypes::CallDirection &callDirection, 0041 const DialerTypes::CallState &callState, 0042 const DialerTypes::CallStateReason &callStateReason, 0043 const QString communicationWith) 0044 { 0045 qDebug() << "call added:" << deviceUni << callUni; 0046 _callUtils->addCall(deviceUni, callUni, callDirection, callState, callStateReason, communicationWith); 0047 } 0048 0049 void CallManager::onCallDeleted(const QString &deviceUni, const QString &callUni) 0050 { 0051 qDebug() << "call deleted:" << deviceUni << callUni; 0052 _callUtils->deleteCall(deviceUni, callUni); 0053 } 0054 0055 void CallManager::onCallStateChanged(const DialerTypes::CallData &callData) 0056 { 0057 qDebug() << "new call state:" << callData.state << callData.stateReason; 0058 _callUtils->setCallState(callData); 0059 0060 // Add inhibition in logind when call is active. 0061 // Otherwise if powerdevil is configured to suspend device afer few minutes, 0062 // it will happily put it to suspend, freezing calls. 0063 // 0064 // For XDG spec, see also: 0065 // https://gitlab.freedesktop.org/xdg/xdg-specs/-/issues/99 0066 // 0067 // For Solid support state, see also: 0068 // https://invent.kde.org/frameworks/solid/-/blob/79bdd41abcd479f486976596fcca40b388caa9b2/CMakeLists.txt#L97-L104 0069 switch (callData.state) { 0070 case DialerTypes::CallState::Active: { 0071 qDebug() << "logind sleep inhibitor: starting"; 0072 0073 if (_inhibitSleepFd) { 0074 qDebug() << "logind sleep inhibitor: already inhibited"; 0075 break; 0076 } 0077 0078 auto bus = QDBusConnection::systemBus(); 0079 0080 if (!bus.isConnected()) { 0081 qDebug() << "logind sleep inhibitor: error: D-Bus system bus is not connected"; 0082 break; 0083 } 0084 0085 QDBusMessage sleepInhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.login1"), 0086 QStringLiteral("/org/freedesktop/login1"), 0087 QStringLiteral("org.freedesktop.login1.Manager"), 0088 QStringLiteral("Inhibit")); 0089 sleepInhibitCall.setArguments( 0090 {QStringLiteral("sleep"), QCoreApplication::instance()->applicationName(), tr("Active call inhibits system suspend"), QStringLiteral("block")}); 0091 QDBusReply<QDBusUnixFileDescriptor> reply = bus.call(sleepInhibitCall); 0092 0093 if (!reply.isValid()) { 0094 qDebug() << "logind sleep inhibitor: error: call failed"; 0095 break; 0096 } 0097 0098 auto const fd = reply.value(); 0099 if (!fd.isValid()) { 0100 qDebug() << "logind sleep inhibitor: error: call returned an invalid file descriptor"; 0101 break; 0102 } 0103 _inhibitSleepFd = fd; 0104 qDebug() << "logind sleep inhibitor: success"; 0105 break; 0106 } 0107 case DialerTypes::CallState::Terminated: { 0108 QString deviceUni; // TODO: improve deviceUni getter 0109 _modemController->deleteCall(deviceUni, callData.id); 0110 _inhibitSleepFd.reset(); 0111 qDebug() << "logind sleep inhibitor: turned off"; 0112 break; 0113 } 0114 default: 0115 break; 0116 } 0117 } 0118 0119 void CallManager::onUtilsCreatedCall(const QString &deviceUni, const QString &callUni) 0120 { 0121 _modemController->createCall(deviceUni, callUni); 0122 } 0123 0124 void CallManager::onUtilsAccepted(const QString &deviceUni, const QString &callUni) 0125 { 0126 _modemController->acceptCall(deviceUni, callUni); 0127 } 0128 0129 void CallManager::onUtilsHungUp(const QString &deviceUni, const QString &callUni) 0130 { 0131 _modemController->hangUp(deviceUni, callUni); 0132 } 0133 0134 void CallManager::onUtilsSentDtmf(const QString &deviceUni, const QString &callUni, const QString &tones) 0135 { 0136 _modemController->sendDtmf(deviceUni, callUni, tones); 0137 } 0138 0139 void CallManager::onUtilsCallsRequested() 0140 { 0141 _callUtils->setCalls(_modemController->fetchCalls()); 0142 }