From ebc496d4e8038834e68ef2069bc53a0524da2008 Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 31 Mar 2015 17:33:29 +0200 Subject: implement the voicecallmanager (dialer, etc.) --- saltoqd/voicecallmanager.cpp | 198 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 186 insertions(+), 12 deletions(-) (limited to 'saltoqd/voicecallmanager.cpp') diff --git a/saltoqd/voicecallmanager.cpp b/saltoqd/voicecallmanager.cpp index d2c5c52..79cfcf6 100644 --- a/saltoqd/voicecallmanager.cpp +++ b/saltoqd/voicecallmanager.cpp @@ -1,13 +1,27 @@ #include +#include "contactsmanager.h" #include "voicecallmanager.h" #include "voicecallmanager_interface.h" +#include "voicecall_interface.h" #include "profiled_interface.h" static ComNokiaProfiledInterface *profiled = NULL; static OrgNemomobileVoicecallVoiceCallManagerInterface *vcm = NULL; -VoiceCallManager::VoiceCallManager(ToqManager *toq) : - QObject(toq), _toq(toq) +enum VoiceCallStatus { + STATUS_NULL, + STATUS_ACTIVE, + STATUS_HELD, + STATUS_DIALING, + STATUS_ALERTING, + STATUS_INCOMING, + STATUS_WAITING, + STATUS_DISCONNECTED +}; + +VoiceCallManager::VoiceCallManager(ContactsManager *contacts, ToqManager *toq) : + QObject(toq), _toq(toq), _contacts(contacts), + _activeCall(0) { if (!profiled) { qDBusRegisterMetaType(); @@ -25,6 +39,8 @@ VoiceCallManager::VoiceCallManager(ToqManager *toq) : connect(profiled, &ComNokiaProfiledInterface::profile_changed, this, &VoiceCallManager::handleProfileChanged); + connect(vcm, &OrgNemomobileVoicecallVoiceCallManagerInterface::activeVoiceCallChanged, + this, &VoiceCallManager::handleActiveVoiceCallChanged); _toq->setEndpointListener(ToqConnection::VoiceCallEndpoint, this); } @@ -33,8 +49,69 @@ void VoiceCallManager::handleMessage(const ToqConnection::Message &msg) { Q_ASSERT(msg.destination == ToqConnection::VoiceCallEndpoint); switch (msg.type) { - case 15: - handleGetPhoneStatusMessage(msg); + case 0: // Call number? + if (vcm) { + QStringList providers = vcm->providers(); + if (providers.isEmpty()) { + sendReply(msg, 3, "No service"); + return; + } + QString provider = providers.first().split(":").at(0); + QString number = msg.toJson().object().value("dial_number").toString(); + if (vcm->dial(provider, number)) { + sendReply(msg, 0, "Succesfully dialed"); + } else { + sendReply(msg, 1, "Wrong number"); + } + } + break; + case 1: // Redial? + // TODO + sendReply(msg, 1, "Could not redial"); + break; + case 4: // Cancel call + if (_activeCall && _activeCall->hangup()) { + sendReply(msg, 0, "Succesfully ended"); + } else { + sendReply(msg, 1, "Could not cancel call"); + } + break; + case 5: // Answer call + if (_activeCall && _activeCall->answer()) { + sendReply(msg, 0, "Succesfully answered"); + } else { + sendReply(msg, 1, "Could not answer call"); + } + break; + case 6: // Reject call + if (_activeCall && _activeCall->hangup()) { + sendReply(msg, 0, "Succesfully rejected"); + } else { + sendReply(msg, 1, "Could not reject call"); + } + break; + case 7: // End call + if (_activeCall && _activeCall->hangup()) { + sendReply(msg, 0, "Succesfully ended"); + } else { + sendReply(msg, 1, "Could not end call"); + } + break; + case 9: // Speaker volume up + case 10: // Speaker volume down + // TODO + sendReply(msg, 1, "TODO"); + break; + case 11: // Mic mute + vcm->setIsMicrophoneMuted(true); + sendReply(msg, 0, "Succesfully muted"); + break; + case 12: // Mic unmute + vcm->setIsMicrophoneMuted(false); + sendReply(msg, 0, "Succesfully unmuted"); + break; + case 15: // Phone status + _toq->sendReply(msg, 0x400F, buildPhoneStatus()); break; default: qWarning() << "Unknown message" << msg.type; @@ -47,9 +124,12 @@ void VoiceCallManager::setSilentMode(bool silent) setProfile(silent ? "silent" : "ambience"); } -void VoiceCallManager::handleGetPhoneStatusMessage(const ToqConnection::Message &msg) +void VoiceCallManager::sendReply(const ToqConnection::Message &msg, int status, const QString &message) { - _toq->sendReply(msg, 0x400F, buildPhoneStatus()); + QJsonObject obj; + obj.insert("result", status); + obj.insert("description", message); + _toq->sendReply(msg, 0x4000 | msg.type, obj); } QString VoiceCallManager::getCurrentProfile() @@ -73,20 +153,85 @@ void VoiceCallManager::setProfile(const QString &name) } } +QJsonObject VoiceCallManager::buildPhoneStatus() +{ + QJsonObject obj; + obj.insert("service", int(1)); // TODO + int call_status = 0; + int call_setup_status = 0; + int call_held = 0; + if (_activeCall) { + switch (_activeCall->status()) { + case STATUS_ACTIVE: + call_status = 1; + break; + case STATUS_HELD: + call_status = 1; + call_held = 1; + break; + case STATUS_DIALING: + case STATUS_ALERTING: + call_status = 1; + break; + case STATUS_INCOMING: + call_status = 0; + call_setup_status = 1; + break; + case STATUS_WAITING: + call_status = 1; + call_setup_status = 0; + break; + case STATUS_NULL: + case STATUS_DISCONNECTED: + default: + call_status = 0; + call_setup_status = 0; + break; + } + + QString phoneNumber = _activeCall->lineId(); + auto callerId = _contacts->findNameTypeForPhoneNumber(phoneNumber); + obj.insert("caller_id", phoneNumber); + obj.insert("caller_name", callerId.name); + obj.insert("caller_phone_type", callerId.type); + obj.insert("privileged", callerId.favorite); + QDateTime callTime = _activeCall->startedAt(); + if (callTime.isValid()) { + obj.insert("call_time", qint64(_activeCall->startedAt().toTime_t())); + } + } + + obj.insert("call_status", call_status); + obj.insert("call_setup_status", call_setup_status); + obj.insert("call_held", call_held); + obj.insert("silence_mode", getCurrentProfile() == "silent" ? 1 : 0); + obj.insert("mic_mute", vcm->isMicrophoneMuted() ? 1 : 0); + + return obj; +} + void VoiceCallManager::sendPhoneStatusMessage() { _toq->sendMessage(ToqConnection::VoiceCallEndpoint, ToqConnection::VoiceCallEndpoint + 1, 0x8000, buildPhoneStatus()); } -QJsonObject VoiceCallManager::buildPhoneStatus() +void VoiceCallManager::sendPhoneRingMessage() { QJsonObject obj; - obj.insert("service", int(1)); - obj.insert("call_status", int(0)); - obj.insert("call_setup_status", int(0)); - obj.insert("silence_mode", getCurrentProfile() == "silent" ? 1 : 0); - return obj; + + if (_activeCall) { + QString phoneNumber = _activeCall->lineId(); + auto callerId = _contacts->findNameTypeForPhoneNumber(phoneNumber); + obj.insert("caller_id_present", phoneNumber.isEmpty() ? 0 : 1); + obj.insert("caller_id", phoneNumber); + obj.insert("caller_name", callerId.name); + obj.insert("caller_phone_type", callerId.type); + obj.insert("privileged", callerId.favorite); + } + + _toq->sendMessage(ToqConnection::VoiceCallEndpoint, ToqConnection::VoiceCallEndpoint + 1, + 0x8001, obj); } void VoiceCallManager::handleProfileChanged(bool changed, bool active, const QString &profile) @@ -97,6 +242,35 @@ void VoiceCallManager::handleProfileChanged(bool changed, bool active, const QSt sendPhoneStatusMessage(); } +void VoiceCallManager::handleActiveVoiceCallChanged() +{ + if (_activeCall) { + delete _activeCall; + } + QString id = vcm->activeVoiceCall(); + if (!id.isEmpty()) { + _activeCall = new OrgNemomobileVoicecallVoiceCallInterface("org.nemomobile.voicecall", + QString("/calls/%1").arg(id), + vcm->connection(), + this); + connect(_activeCall, &OrgNemomobileVoicecallVoiceCallInterface::statusChanged, + this, &VoiceCallManager::handleActiveVoiceCallStatusChanged); + } else { + _activeCall = 0; + } + sendPhoneStatusMessage(); +} + +void VoiceCallManager::handleActiveVoiceCallStatusChanged() +{ + int status = _activeCall->status(); + qDebug() << "Status changed" << status << _activeCall->statusText(); + if (status == STATUS_INCOMING) { + sendPhoneRingMessage(); + } + sendPhoneStatusMessage(); +} + QDBusArgument &operator<<(QDBusArgument &argument, const ProfileValue &value) { argument.beginStructure(); -- cgit v1.2.3