diff --git a/plugins/telephony/telephonyplugin.cpp b/plugins/telephony/telephonyplugin.cpp index 5f12dd12..88d53483 100644 --- a/plugins/telephony/telephonyplugin.cpp +++ b/plugins/telephony/telephonyplugin.cpp @@ -1,122 +1,141 @@ /** * Copyright 2013 Albert Vaca * Copyright 2018 Simon Redman * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "telephonyplugin.h" #include "sendreplydialog.h" #include #include #include #include #include "message.h" K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_telephony.json", registerPlugin< TelephonyPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_TELEPHONY, "kdeconnect.plugin.telephony") TelephonyPlugin::TelephonyPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) , m_telepathyInterface(QStringLiteral("org.freedesktop.Telepathy.ConnectionManager.kdeconnect"), QStringLiteral("/kdeconnect")) { } bool TelephonyPlugin::receivePacket(const NetworkPacket& np) { if (np.get(QStringLiteral("isCancel"))) { //TODO: Clear the old notification return true; } const QString& event = np.get(QStringLiteral("event"), QStringLiteral("unknown")); - if (np.type() == PACKET_TYPE_TELEPHONY_MESSAGE || event == QLatin1String("sms")) + // Handle old-style packets + if (np.type() == PACKET_TYPE_TELEPHONY && event == QLatin1String("sms")) { Message message(np.body()); this->forwardToTelepathy(message); } + if (np.type() == PACKET_TYPE_TELEPHONY_MESSAGE) + { + return this->handleBatchMessages(np); + } + return true; } void TelephonyPlugin::sendMutePacket() { NetworkPacket packet(PACKET_TYPE_TELEPHONY_REQUEST, {{"action", "mute"}}); sendPacket(packet); } void TelephonyPlugin::sendSms(const QString& phoneNumber, const QString& messageBody) { NetworkPacket np(PACKET_TYPE_SMS_REQUEST, { {"sendSms", true}, {"phoneNumber", phoneNumber}, {"messageBody", messageBody} }); qDebug() << "sending sms!"; sendPacket(np); } void TelephonyPlugin::showSendSmsDialog() { QString phoneNumber = sender()->property("phoneNumber").toString(); QString contactName = sender()->property("contactName").toString(); QString originalMessage = sender()->property("originalMessage").toString(); SendReplyDialog* dialog = new SendReplyDialog(originalMessage, phoneNumber, contactName); connect(dialog, &SendReplyDialog::sendReply, this, &TelephonyPlugin::sendSms); dialog->show(); dialog->raise(); } void TelephonyPlugin::sendAllConversationsRequest() { NetworkPacket np(PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATIONS); sendPacket(np); } bool TelephonyPlugin::forwardToTelepathy(const Message& message) { // In case telepathy can handle the message, don't do anything else if (m_telepathyInterface.isValid()) { qCDebug(KDECONNECT_PLUGIN_TELEPHONY) << "Passing a text message to the telepathy interface"; connect(&m_telepathyInterface, SIGNAL(messageReceived(QString,QString)), SLOT(sendSms(QString,QString)), Qt::UniqueConnection); const QString messageBody = message.getBody(); const QString contactName = ""; const QString phoneNumber = message.getAddress(); QDBusReply reply = m_telepathyInterface.call(QStringLiteral("sendMessage"), phoneNumber, contactName, messageBody); if (reply) { return true; } else { return false; } } return false; } +bool TelephonyPlugin::handleBatchMessages(const NetworkPacket& np) +{ + auto messages = np.get("messages"); + + for (QVariant body : messages) + { + Message message(body.toMap()); + this->forwardToTelepathy(message); + } + + return true; +} + QString TelephonyPlugin::dbusPath() const { return "/modules/kdeconnect/devices/" + device()->id() + "/telephony"; } #include "telephonyplugin.moc" diff --git a/plugins/telephony/telephonyplugin.h b/plugins/telephony/telephonyplugin.h index a0600c19..3863fc81 100644 --- a/plugins/telephony/telephonyplugin.h +++ b/plugins/telephony/telephonyplugin.h @@ -1,99 +1,109 @@ /** * Copyright 2013 Albert Vaca * Copyright 2018 Simon Redman * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TELEPHONYPLUGIN_H #define TELEPHONYPLUGIN_H #include "message.h" #include #include #include /** - * Packet used to indicate a message has been pushed from the remote device + * Packet used to indicate a batch of messages has been pushed from the remote device * - * The body should contain a mapping of all fields of the message to their values + * The body should contain the key "messages" mapping to an array of messages * * For example: - * { "event" : "sms", - * "messageBody" : "Hello", - * "phoneNumber" : "2021234567", - * "messageDate" : "20150321434", - * "messageType" : "-1", - * "threadID" : "132" + * { "messages" : [ + * { "event" : "sms", + * "messageBody" : "Hello", + * "phoneNumber" : "2021234567", + * "messageDate" : "1518846484880", + * "messageType" : "2", + * "threadID" : "132" + * }, + * { ... }, + * ... + * ] * } */ #define PACKET_TYPE_TELEPHONY_MESSAGE QStringLiteral("kdeconnect.telephony.message") #define PACKET_TYPE_TELEPHONY QStringLiteral("kdeconnect.telephony") #define PACKET_TYPE_TELEPHONY_REQUEST QStringLiteral("kdeconnect.telephony.request") #define PACKET_TYPE_SMS_REQUEST QStringLiteral("kdeconnect.sms.request") /** * Packet sent to request all the most-recent messages in all conversations on the device * * The request packet shall contain no body */ #define PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATIONS QStringLiteral("kdeconnect.telephony.request_conversations") Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_TELEPHONY) class TelephonyPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.telephony") public: explicit TelephonyPlugin(QObject* parent, const QVariantList& args); bool receivePacket(const NetworkPacket& np) override; void connected() override {} QString dbusPath() const override; public Q_SLOTS: Q_SCRIPTABLE void sendSms(const QString& phoneNumber, const QString& messageBody); /** * Send a request to the remote for all of its conversations */ Q_SCRIPTABLE void sendAllConversationsRequest(); public: Q_SIGNALS: private Q_SLOTS: void sendMutePacket(); void showSendSmsDialog(); protected: /** * Send to the telepathy plugin if it is available */ bool forwardToTelepathy(const Message& message); + /** + * Handle a packet which contains many messages, such as PACKET_TYPE_TELEPHONY_MESSAGE + */ + bool handleBatchMessages(const NetworkPacket& np); + private: QDBusInterface m_telepathyInterface; }; #endif