From 43932a4300761b8b7554972d4c13f4012daa9403 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Fri, 26 Jul 2013 16:21:19 +0200 Subject: [PATCH] Added battery reporting via dbus interface --- daemon/CMakeLists.txt | 30 ++++++---- daemon/daemon.cpp | 3 +- daemon/daemon.h | 2 +- daemon/device.cpp | 11 +++- daemon/device.h | 11 ++-- daemon/devicelinks/tcpdevicelink.cpp | 14 +++-- daemon/linkproviders/linkprovider.cpp | 3 +- daemon/networkpackage.cpp | 4 +- daemon/networkpackagetypes.h | 1 + .../batterypackageinterface.cpp | 57 +++++++++++++++++++ .../batterypackageinterface.h | 43 ++++++++++++++ .../clipboardpackageinterface.cpp | 3 +- .../devicebatteryinformation_p.cpp | 27 +++++++++ .../devicebatteryinformation_p.h | 52 +++++++++++++++++ .../notificationpackageinterface.cpp | 6 +- daemon/packageinterfaces/packageinterface.cpp | 3 +- .../pingpackageinterface.cpp | 3 +- kcm/CMakeLists.txt | 1 + kcm/dbusinterfaces.cpp | 4 +- kcm/dbusinterfaces.h | 10 +++- 20 files changed, 250 insertions(+), 38 deletions(-) create mode 100644 daemon/packageinterfaces/batterypackageinterface.cpp create mode 100644 daemon/packageinterfaces/batterypackageinterface.h create mode 100644 daemon/packageinterfaces/devicebatteryinformation_p.cpp create mode 100644 daemon/packageinterfaces/devicebatteryinformation_p.h diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 007dea513..ce393c1fa 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -13,6 +13,8 @@ set(kded_kdeconnect_SRCS packageinterfaces/notificationpackageinterface.cpp packageinterfaces/pausemusicpackageinterface.cpp packageinterfaces/clipboardpackageinterface.cpp + packageinterfaces/batterypackageinterface.cpp + packageinterfaces/devicebatteryinformation_p.cpp networkpackage.cpp daemon.cpp @@ -31,30 +33,34 @@ target_link_libraries(kded_kdeconnect ${QJSON_LIBRARY} ) -qt4_generate_dbus_interface( +macro (generate_and_install_dbus_interface project_main_target header_file output_xml_file) #OPTIONS qdbus_options + QT4_EXTRACT_OPTIONS(extra_files_ignore qdbus_options ${ARGN}) + qt4_generate_dbus_interface(${header_file} ${output_xml_file} OPTIONS ${qdbus_options}) + add_dependencies(${project_main_target} ${output_xml_file}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${output_xml_file} DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) +endmacro (generate_and_install_dbus_interface) + +generate_and_install_dbus_interface( + kded_kdeconnect daemon.h org.kde.kdeconnect.xml OPTIONS -a ) -qt4_generate_dbus_interface( +generate_and_install_dbus_interface( + kded_kdeconnect device.h org.kde.kdeconnect.device.xml OPTIONS -a ) -add_custom_target( - org.kde.kdeconnect.xml - SOURCES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kdeconnect.xml +generate_and_install_dbus_interface( + kded_kdeconnect + packageinterfaces/devicebatteryinformation_p.h + org.kde.kdeconnect.device.battery.xml + OPTIONS -a ) -add_custom_target( - org.kde.kdeconnect.device.xml - SOURCES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kdeconnect.device.xml -) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kdeconnect.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kdeconnect.device.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) install(TARGETS kded_kdeconnect DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES kdeconnect.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded) install(FILES kdeconnect.notifyrc DESTINATION ${DATA_INSTALL_DIR}/kdeconnect) diff --git a/daemon/daemon.cpp b/daemon/daemon.cpp index fcb7c474e..01171c874 100644 --- a/daemon/daemon.cpp +++ b/daemon/daemon.cpp @@ -26,6 +26,7 @@ #include "packageinterfaces/notificationpackageinterface.h" #include "packageinterfaces/pausemusicpackageinterface.h" #include "packageinterfaces/clipboardpackageinterface.h" +#include "packageinterfaces/batterypackageinterface.h" #include "linkproviders/avahitcplinkprovider.h" #include "linkproviders/loopbacklinkprovider.h" @@ -56,7 +57,6 @@ Daemon::Daemon(QObject *parent, const QList&) //Debugging qDebug() << "Starting KdeConnect daemon"; - config->group("devices").group("paired").group("fake_unreachable").writeEntry("name","Fake device"); //TODO: Do not hardcode the load of the package interfaces //use: https://techbase.kde.org/Development/Tutorials/Services/Plugins @@ -64,6 +64,7 @@ Daemon::Daemon(QObject *parent, const QList&) mPackageInterfaces.push_back(new NotificationPackageInterface()); mPackageInterfaces.push_back(new PauseMusicPackageInterface()); mPackageInterfaces.push_back(new ClipboardPackageInterface()); + mPackageInterfaces.push_back(new BatteryPackageInterface()); //TODO: Do not hardcode the load of the device locators //use: https://techbase.kde.org/Development/Tutorials/Services/Plugins diff --git a/daemon/daemon.h b/daemon/daemon.h index ab1d4e99c..9228e2e51 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -49,7 +49,7 @@ class Daemon : public KDEDModule { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "kdeconnect.daemon") + Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon") public: Daemon(QObject *parent, const QList&); diff --git a/daemon/device.cpp b/daemon/device.cpp index 08241e47a..e158dbf99 100644 --- a/daemon/device.cpp +++ b/daemon/device.cpp @@ -3,7 +3,7 @@ #include #include "devicelinks/devicelink.h" #include "linkproviders/linkprovider.h" - +#include "packageinterfaces/devicebatteryinformation_p.h" #include #include @@ -13,7 +13,10 @@ Device::Device(const QString& id, const QString& name) m_deviceName = name; m_paired = true; m_knownIdentiy = true; - QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/Devices/"+id, this, QDBusConnection::ExportScriptableContents); + + //Register in bus + QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/devices/"+id, this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); + } Device::Device(const QString& id, const QString& name, DeviceLink* link) @@ -22,7 +25,9 @@ Device::Device(const QString& id, const QString& name, DeviceLink* link) m_deviceName = name; m_paired = false; m_knownIdentiy = true; - QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/Devices/"+id, this, QDBusConnection::ExportScriptableContents); + + //Register in bus + QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/devices/"+id, this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); addLink(link); } diff --git a/daemon/device.h b/daemon/device.h index 7bc0441a5..a0f279ce6 100644 --- a/daemon/device.h +++ b/daemon/device.h @@ -32,7 +32,9 @@ class DeviceLink; class Device : public QObject { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "kdeconnect.device") + Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device") + Q_PROPERTY(QString id READ id) + Q_PROPERTY(QString name READ name) public: @@ -46,6 +48,9 @@ public: //(not supported yet, do we need it or we can rely on the device presenging itself?) //Device(const QString& id, DeviceLink* dl); + QString id() const{ return m_deviceId; } + QString name() const { return m_deviceName; } + //Add and remove links void addLink(DeviceLink*); void removeLink(DeviceLink*); @@ -56,10 +61,8 @@ Q_SIGNALS: public Q_SLOTS: bool sendPackage(const NetworkPackage& np); - //Public dbus interface + //Public dbus operations public Q_SLOTS: - Q_SCRIPTABLE QString id() const{ return m_deviceId; } - Q_SCRIPTABLE QString name() const { return m_deviceName; } Q_SCRIPTABLE QStringList availableLinks() const; Q_SCRIPTABLE bool paired() const { return m_paired; } Q_SCRIPTABLE bool reachable() const { return !m_deviceLinks.empty(); } diff --git a/daemon/devicelinks/tcpdevicelink.cpp b/daemon/devicelinks/tcpdevicelink.cpp index 7bfaf3895..bc357d019 100644 --- a/daemon/devicelinks/tcpdevicelink.cpp +++ b/daemon/devicelinks/tcpdevicelink.cpp @@ -39,12 +39,16 @@ void TcpDeviceLink::dataReceived() { qDebug() << "TcpDeviceLink dataReceived"; - QByteArray a = mSocket->readAll(); + QByteArray data = mSocket->readAll(); + QList packages = data.split('\n'); + Q_FOREACH(const QByteArray& package, packages) { - qDebug() << a; + if (package.length() < 3) continue; - NetworkPackage np; - NetworkPackage::unserialize(a,&np); + NetworkPackage np; + NetworkPackage::unserialize(package,&np); - emit receivedPackage(np); + emit receivedPackage(np); + + } } diff --git a/daemon/linkproviders/linkprovider.cpp b/daemon/linkproviders/linkprovider.cpp index 7fce173da..2ca4dbabc 100644 --- a/daemon/linkproviders/linkprovider.cpp +++ b/daemon/linkproviders/linkprovider.cpp @@ -20,6 +20,7 @@ #include "linkprovider.h" -LinkProvider::LinkProvider() { +LinkProvider::LinkProvider() +{ //gcc complains if we don't add something to compile on a class with virtual functions } \ No newline at end of file diff --git a/daemon/networkpackage.cpp b/daemon/networkpackage.cpp index 255ef363e..4fea23074 100644 --- a/daemon/networkpackage.cpp +++ b/daemon/networkpackage.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -66,7 +65,8 @@ QByteArray NetworkPackage::serialize() const void NetworkPackage::unserialize(QByteArray a, NetworkPackage* np) { - kDebug() << a; + qDebug() << "Unserialize:" << a; + //Json -> QVariant QJson::Parser parser; bool ok; diff --git a/daemon/networkpackagetypes.h b/daemon/networkpackagetypes.h index b5d6338bb..981139f1c 100644 --- a/daemon/networkpackagetypes.h +++ b/daemon/networkpackagetypes.h @@ -24,6 +24,7 @@ #define PACKAGE_TYPE_IDENTITY QString("kdeconnect.identity") #define PACKAGE_TYPE_PING QString("kdeconnect.ping") #define PACKAGE_TYPE_NOTIFICATION QString("kdeconnect.notification") +#define PACKAGE_TYPE_BATTERY QString("kdeconnect.battery") #define PACKAGE_TYPE_CALL QString("kdeconnect.call") #define PACKAGE_TYPE_CLIPBOARD QString("kdeconnect.clipboard") diff --git a/daemon/packageinterfaces/batterypackageinterface.cpp b/daemon/packageinterfaces/batterypackageinterface.cpp new file mode 100644 index 000000000..ec4a1a57e --- /dev/null +++ b/daemon/packageinterfaces/batterypackageinterface.cpp @@ -0,0 +1,57 @@ +/** + * Copyright 2013 Albert Vaca + * + * 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 "batterypackageinterface.h" + +#include +#include + + +BatteryPackageInterface::BatteryPackageInterface() +{ + //TODO: Get initial state of all devices +} + +bool BatteryPackageInterface::receivePackage(const Device& device, const NetworkPackage& np) +{ + if (np.type() != PACKAGE_TYPE_BATTERY) return false; + + QString id = device.id(); + + if (!devices.contains(id)) { + + //TODO: Avoid ugly const_cast + DeviceBatteryInformation* deviceInfo = new DeviceBatteryInformation(const_cast(&device)); + + devices[id] = deviceInfo; + + qDebug() << "Added battery info to device" << id; + + } + + bool isCharging = np.get("isCharging"); + devices[id]->setCharging(isCharging); + + int currentCharge = np.get("currentCharge"); + devices[id]->setCharge(currentCharge); + + return true; + +} diff --git a/daemon/packageinterfaces/batterypackageinterface.h b/daemon/packageinterfaces/batterypackageinterface.h new file mode 100644 index 000000000..f2d5afe16 --- /dev/null +++ b/daemon/packageinterfaces/batterypackageinterface.h @@ -0,0 +1,43 @@ +/** + * Copyright 2013 Albert Vaca + * + * 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 BATTERYPACKAGEINTERFACE_H +#define BATTERYPACKAGEINTERFACE_H + +#include + +#include "packageinterface.h" + +#include "devicebatteryinformation_p.h" + +class BatteryPackageInterface + : public PackageInterface +{ + +public: + BatteryPackageInterface(); + virtual bool receivePackage(const Device&, const NetworkPackage& np); + +private: + QHash devices; + +}; + +#endif diff --git a/daemon/packageinterfaces/clipboardpackageinterface.cpp b/daemon/packageinterfaces/clipboardpackageinterface.cpp index 201fa9ef6..1454bf8d0 100644 --- a/daemon/packageinterfaces/clipboardpackageinterface.cpp +++ b/daemon/packageinterfaces/clipboardpackageinterface.cpp @@ -24,7 +24,8 @@ #include #include -ClipboardPackageInterface::ClipboardPackageInterface() { +ClipboardPackageInterface::ClipboardPackageInterface() +{ clipboard = QApplication::clipboard(); ignore_next_clipboard_change = false; connect(clipboard,SIGNAL(changed(QClipboard::Mode)),this,SLOT(clipboardChanged(QClipboard::Mode))); diff --git a/daemon/packageinterfaces/devicebatteryinformation_p.cpp b/daemon/packageinterfaces/devicebatteryinformation_p.cpp new file mode 100644 index 000000000..647746f29 --- /dev/null +++ b/daemon/packageinterfaces/devicebatteryinformation_p.cpp @@ -0,0 +1,27 @@ +/** + * Copyright 2013 Albert Vaca + * + * 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 "devicebatteryinformation_p.h" + +DeviceBatteryInformation::DeviceBatteryInformation(QObject* parent) + : QDBusAbstractAdaptor(parent) +{ + +} diff --git a/daemon/packageinterfaces/devicebatteryinformation_p.h b/daemon/packageinterfaces/devicebatteryinformation_p.h new file mode 100644 index 000000000..1b2bda146 --- /dev/null +++ b/daemon/packageinterfaces/devicebatteryinformation_p.h @@ -0,0 +1,52 @@ +/** + * Copyright 2013 Albert Vaca + * + * 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 DEVICEBATTERYINFORMATION_H +#define DEVICEBATTERYINFORMATION_H + +#include +#include + +class DeviceBatteryInformation + : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.battery") + Q_PROPERTY( int charge READ charge ) + Q_PROPERTY( bool isCharging READ isCharging NOTIFY chargingChange ) + +public: + DeviceBatteryInformation(QObject* parent = 0); + + int charge() { return mCharge; } + void setCharge(int charge) { mCharge = charge; } + bool isCharging() { return mIsCharging; } + void setCharging(bool isCharging) { mIsCharging = isCharging; } + +private: + bool mIsCharging; + int mCharge; + +Q_SIGNALS: + Q_SCRIPTABLE void chargingChange(bool charging); + +}; + +#endif //DEVICEBATTERYINFORMATION_H \ No newline at end of file diff --git a/daemon/packageinterfaces/notificationpackageinterface.cpp b/daemon/packageinterfaces/notificationpackageinterface.cpp index c3130fa91..e0a001b54 100644 --- a/daemon/packageinterfaces/notificationpackageinterface.cpp +++ b/daemon/packageinterfaces/notificationpackageinterface.cpp @@ -23,7 +23,8 @@ #include #include -KNotification* NotificationPackageInterface::createNotification(const QString& deviceName, const NetworkPackage& np) { +KNotification* NotificationPackageInterface::createNotification(const QString& deviceName, const NetworkPackage& np) +{ QString npType = np.get("notificationType"); @@ -71,7 +72,8 @@ KNotification* NotificationPackageInterface::createNotification(const QString& d } -bool NotificationPackageInterface::receivePackage(const Device& device, const NetworkPackage& np) { +bool NotificationPackageInterface::receivePackage(const Device& device, const NetworkPackage& np) +{ if (np.type() != PACKAGE_TYPE_NOTIFICATION) return false; diff --git a/daemon/packageinterfaces/packageinterface.cpp b/daemon/packageinterfaces/packageinterface.cpp index 18a3431ef..d1f75cbea 100644 --- a/daemon/packageinterfaces/packageinterface.cpp +++ b/daemon/packageinterfaces/packageinterface.cpp @@ -20,6 +20,7 @@ #include "packageinterface.h" -PackageInterface::PackageInterface() { +PackageInterface::PackageInterface() +{ //gcc complains if we don't add something to compile on a class with virtual functions } diff --git a/daemon/packageinterfaces/pingpackageinterface.cpp b/daemon/packageinterfaces/pingpackageinterface.cpp index b81ebd08d..b984fdd5b 100644 --- a/daemon/packageinterfaces/pingpackageinterface.cpp +++ b/daemon/packageinterfaces/pingpackageinterface.cpp @@ -23,7 +23,8 @@ #include #include -bool PingPackageInterface::receivePackage(const Device& device, const NetworkPackage& np) { +bool PingPackageInterface::receivePackage(const Device& device, const NetworkPackage& np) +{ if (np.type() != PACKAGE_TYPE_PING) return false; diff --git a/kcm/CMakeLists.txt b/kcm/CMakeLists.txt index f279a5d75..2c15af2fd 100644 --- a/kcm/CMakeLists.txt +++ b/kcm/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries(kcm_kdeconnect add_dependencies(kcm_kdeconnect org.kde.kdeconnect.xml org.kde.kdeconnect.device.xml + org.kde.kdeconnect.device.battery.xml ) install(TARGETS kcm_kdeconnect DESTINATION ${PLUGIN_INSTALL_DIR}) diff --git a/kcm/dbusinterfaces.cpp b/kcm/dbusinterfaces.cpp index c695064e4..70b6df40e 100644 --- a/kcm/dbusinterfaces.cpp +++ b/kcm/dbusinterfaces.cpp @@ -21,13 +21,13 @@ #include "dbusinterfaces.h" DaemonDbusInterface::DaemonDbusInterface(QObject* parent) - : KdeconnectDaemonInterface("org.kde.kdeconnect", "/modules/kdeconnect", QDBusConnection::sessionBus(), parent) + : OrgKdeKdeconnectDaemonInterface("org.kde.kdeconnect", "/modules/kdeconnect", QDBusConnection::sessionBus(), parent) { } DeviceDbusInterface::DeviceDbusInterface(const QString& id, QObject* parent) - : KdeconnectDeviceInterface("org.kde.kdeconnect", "/modules/kdeconnect/Devices/"+id, QDBusConnection::sessionBus(), parent) + : OrgKdeKdeconnectDeviceInterface("org.kde.kdeconnect", "/modules/kdeconnect/devices/"+id, QDBusConnection::sessionBus(), parent) { } \ No newline at end of file diff --git a/kcm/dbusinterfaces.h b/kcm/dbusinterfaces.h index ccf7b333b..1a9fd3319 100644 --- a/kcm/dbusinterfaces.h +++ b/kcm/dbusinterfaces.h @@ -24,8 +24,12 @@ #ifndef DbusInterfaces_H_ #define DbusInterfaces_H_ +/** + * Using these "proxy" classes just in case we need to rename the + * interface, so we can change the class name in a single place. + */ class DaemonDbusInterface - : public KdeconnectDaemonInterface + : public OrgKdeKdeconnectDaemonInterface { Q_OBJECT public: @@ -33,7 +37,9 @@ public: }; -class DeviceDbusInterface : public KdeconnectDeviceInterface{ +class DeviceDbusInterface + : public OrgKdeKdeconnectDeviceInterface +{ Q_OBJECT public: DeviceDbusInterface(const QString& id, QObject* parent);