diff --git a/src/batterystatus.cpp b/src/batterystatus.cpp new file mode 100644 index 0000000..755a35d --- /dev/null +++ b/src/batterystatus.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2017 Jolla Ltd. + * Contact: Raine Makelainen + * + * You may use this file under the terms of the BSD license as follows: + * + * "Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Nemo Mobile nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + */ + +#include "batterystatus.h" +#include "batterystatus_p.h" + +#include +#include +#include +#include +#include + +#include +#include + +QDBusPendingCallWatcher *getMceRequestCallWatcher(const QString &method) +{ + QDBusInterface mceInterface(MCE_SERVICE, + MCE_REQUEST_PATH, + MCE_REQUEST_IF, + QDBusConnection::systemBus()); + QDBusPendingCall pendingModemsRequest = mceInterface.asyncCall(method); + return new QDBusPendingCallWatcher(pendingModemsRequest); +} + +BatteryStatusPrivate::BatteryStatusPrivate(BatteryStatus *batteryInfo) + : QObject(batteryInfo) + , q(batteryInfo) + , status(BatteryStatus::BatteryStatusUnknown) + , chargerStatus(BatteryStatus::ChargerStatusUnknown) + , chargePercentage(-1) +{ + QDBusServiceWatcher *mceWatcher = new QDBusServiceWatcher(MCE_SERVICE, QDBusConnection::systemBus(), + QDBusServiceWatcher::WatchForOwnerChange, this); + + connect(mceWatcher, &QDBusServiceWatcher::serviceRegistered, + this, &BatteryStatusPrivate::mceRegistered); + connect(mceWatcher, &QDBusServiceWatcher::serviceUnregistered, + this, &BatteryStatusPrivate::mceUnregistered); + + registerSignals(); + + QDBusPendingCallWatcher *chargerState = getMceRequestCallWatcher(MCE_CHARGER_STATE_GET); + QObject::connect(chargerState, &QDBusPendingCallWatcher::finished, + this, &BatteryStatusPrivate::initialChargerState); + + QDBusPendingCallWatcher *batteryStatus = getMceRequestCallWatcher(MCE_BATTERY_STATUS_GET); + QObject::connect(batteryStatus, &QDBusPendingCallWatcher::finished, + this, &BatteryStatusPrivate::initialBatteryStatus); + + QDBusPendingCallWatcher *batteryLevel = getMceRequestCallWatcher(MCE_BATTERY_LEVEL_GET); + QObject::connect(batteryLevel, &QDBusPendingCallWatcher::finished, + this, &BatteryStatusPrivate::initialChargePercentage); +} + +BatteryStatusPrivate::~BatteryStatusPrivate() +{ +} + +void BatteryStatusPrivate::registerSignals() +{ + QDBusConnection systemBus = QDBusConnection::systemBus(); + systemBus.connect(MCE_SERVICE, MCE_SIGNAL_PATH, + MCE_SIGNAL_IF, MCE_CHARGER_STATE_SIG, + this, SLOT(chargerStatusChanged(QString))); + systemBus.connect(MCE_SERVICE, MCE_SIGNAL_PATH, + MCE_SIGNAL_IF, MCE_BATTERY_STATUS_SIG, + this, SLOT(statusChanged(QString))); + systemBus.connect(MCE_SERVICE, MCE_SIGNAL_PATH, + MCE_SIGNAL_IF, MCE_BATTERY_LEVEL_SIG, + this, SLOT(chargePercentageChanged(int))); +} + +BatteryStatus::ChargerStatus BatteryStatusPrivate::parseChargerStatus(const QString &state) +{ + if (state == QLatin1String(MCE_CHARGER_STATE_ON)) { + return BatteryStatus::Connected; + } else if (state == QLatin1String(MCE_CHARGER_STATE_OFF)){ + return BatteryStatus::Disconnected; + } + + return BatteryStatus::ChargerStatusUnknown; +} + +BatteryStatus::Status BatteryStatusPrivate::parseBatteryStatus(const QString &status) +{ + if (status == QLatin1String(MCE_BATTERY_STATUS_LOW)) { + return BatteryStatus::Low; + } else if (status == QLatin1String(MCE_BATTERY_STATUS_OK)) { + return BatteryStatus::Normal; + } else if (status == QLatin1String(MCE_BATTERY_STATUS_EMPTY)) { + return BatteryStatus::Empty; + } else if (status == QLatin1String(MCE_BATTERY_STATUS_FULL)) { + return BatteryStatus::Full; + } + + return BatteryStatus::BatteryStatusUnknown; +} + +void BatteryStatusPrivate::mceRegistered() +{ + registerSignals(); +} + +void BatteryStatusPrivate::mceUnregistered() +{ + chargerStatusChanged(QLatin1String(MCE_CHARGER_STATE_UNKNOWN)); + statusChanged(QLatin1String(MCE_BATTERY_STATUS_UNKNOWN)); + chargePercentageChanged(-1); +} + +void BatteryStatusPrivate::chargerStatusChanged(const QString &status) +{ + BatteryStatus::ChargerStatus newStatus = parseChargerStatus(status); + if (newStatus != chargerStatus) { + chargerStatus = newStatus; + emit q->chargerStatusChanged(chargerStatus); + } +} + +void BatteryStatusPrivate::statusChanged(const QString &s) +{ + BatteryStatus::Status newStatus = parseBatteryStatus(s); + if (newStatus != status) { + status = newStatus; + emit q->statusChanged(status); + } +} + +void BatteryStatusPrivate::chargePercentageChanged(int percentage) +{ + if (percentage != chargePercentage) { + chargePercentage = percentage; + emit q->chargePercentageChanged(chargePercentage); + } +} + +void BatteryStatusPrivate::initialChargerState(QDBusPendingCallWatcher *watcher) +{ + if (watcher->isError() && (watcher->error().type() == QDBusError::ServiceUnknown)) { + // Service unknow => mce not registered. Signal initial state. + emit q->chargerStatusChanged(BatteryStatus::ChargerStatusUnknown); + } else if (watcher->isValid() && watcher->isFinished()) { + QDBusPendingReply reply = *watcher; + chargerStatusChanged(reply.value()); + } + + watcher->deleteLater(); +} + +void BatteryStatusPrivate::initialBatteryStatus(QDBusPendingCallWatcher *watcher) +{ + if (watcher->isError() && (watcher->error().type() == QDBusError::ServiceUnknown)) { + // Service unknown => mce not registered. Signal initial state. + emit q->statusChanged(BatteryStatus::BatteryStatusUnknown); + } else if (watcher->isValid() && watcher->isFinished()) { + QDBusPendingReply reply = *watcher; + statusChanged(reply.value()); + } + + watcher->deleteLater(); +} + +void BatteryStatusPrivate::initialChargePercentage(QDBusPendingCallWatcher *watcher) +{ + if (watcher->isError() && (watcher->error().type() == QDBusError::ServiceUnknown)) { + // Service unknown => mce not registered. Signal initial state. + emit q->chargePercentageChanged(-1); + } else if (watcher->isValid() && watcher->isFinished()) { + QDBusPendingReply reply = *watcher; + chargePercentageChanged(reply.value()); + } + + watcher->deleteLater(); +} + +BatteryStatus::BatteryStatus(QObject *parent) + : QObject(parent) + , d_ptr(new BatteryStatusPrivate(this)) +{ +} + +BatteryStatus::~BatteryStatus() +{ +} + +/** + * @brief BatteryStatus::chargerStatus + * @return Returns charger connected status. Returns Connected when power cord is connected (charging) and + * Disconnected when charger is disconnected (discharging). In case information cannot be read ChargerStatusUnknown + * is returned. + */ +BatteryStatus::ChargerStatus BatteryStatus::chargerStatus() const +{ + Q_D(const BatteryStatus); + return d->chargerStatus; +} + +/** + * @brief BatteryStatus::batteryChargeLevel + * @return Returns battery charge level, in case information cannot be read -1 is returned. + */ +int BatteryStatus::chargePercentage() const +{ + Q_D(const BatteryStatus); + return d->chargePercentage; +} + + +/** + * @brief BatteryStatus::status + * @return Returns battery charge status + */ +BatteryStatus::Status BatteryStatus::status() const +{ + Q_D(const BatteryStatus); + return d->status; +} diff --git a/src/batterystatus.h b/src/batterystatus.h new file mode 100644 index 0000000..ff1e37e --- /dev/null +++ b/src/batterystatus.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2017 Jolla Ltd. + * Contact: Raine Makelainen + * + * You may use this file under the terms of the BSD license as follows: + * + * "Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Nemo Mobile nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + */ + +#ifndef BATTERYSTATUS_H +#define BATTERYSTATUS_H + +#include + +#include + +class BatteryStatusPrivate; +class SYSTEMSETTINGS_EXPORT BatteryStatus : public QObject +{ + Q_OBJECT + Q_ENUMS(ChargerStatus) + Q_ENUMS(Status) + + Q_PROPERTY(ChargerStatus chargerStatus READ chargerStatus NOTIFY chargerStatusChanged) + Q_PROPERTY(int chargePercentage READ chargePercentage NOTIFY chargePercentageChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + +public: + BatteryStatus(QObject *parent = 0); + ~BatteryStatus(); + + enum ChargerStatus { + ChargerStatusUnknown = -1, + Disconnected = 0, + Connected = 1 + }; + Q_ENUM(ChargerStatus) + + enum Status { + BatteryStatusUnknown = -1, + Full = 0, + Normal = 1, + Low = 2, + Empty = 3 + }; + Q_ENUM(Status) + + ChargerStatus chargerStatus() const; + int chargePercentage() const; + Status status() const; + +signals: + void chargerStatusChanged(ChargerStatus status); + void chargePercentageChanged(int percentage); + void statusChanged(Status status); + +private: + BatteryStatusPrivate *d_ptr; + Q_DISABLE_COPY(BatteryStatus) + Q_DECLARE_PRIVATE(BatteryStatus) +}; + +#endif // BATTERYSTATUS_H diff --git a/src/batterystatus_p.h b/src/batterystatus_p.h new file mode 100644 index 0000000..da54cd7 --- /dev/null +++ b/src/batterystatus_p.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 Jolla Ltd. + * Contact: Raine Makelainen + * + * You may use this file under the terms of the BSD license as follows: + * + * "Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Nemo Mobile nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + */ + +#ifndef BATTERYSTATUS_P_H +#define BATTERYSTATUS_P_H + +#include "batterystatus.h" + +class QDBusPendingCallWatcher; + +class BatteryStatusPrivate : public QObject +{ + Q_OBJECT + +public: + BatteryStatusPrivate(BatteryStatus *batteryInfo); + ~BatteryStatusPrivate(); + + void registerSignals(); + + BatteryStatus::ChargerStatus parseChargerStatus(const QString &state); + BatteryStatus::Status parseBatteryStatus(const QString &status); + + BatteryStatus *q; + BatteryStatus::Status status; + BatteryStatus::ChargerStatus chargerStatus; + int chargePercentage; + +public slots: + void mceRegistered(); + void mceUnregistered(); + + void chargerStatusChanged(const QString &status); + void statusChanged(const QString &s); + void chargePercentageChanged(int percentage); + + void initialChargerState(QDBusPendingCallWatcher *watcher); + void initialBatteryStatus(QDBusPendingCallWatcher *watcher); + void initialChargePercentage(QDBusPendingCallWatcher *watcher); +}; + +#endif // BATTERYSTATUS_P_H diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp index 03b41a6..ca33114 100644 --- a/src/plugin/plugin.cpp +++ b/src/plugin/plugin.cpp @@ -43,6 +43,7 @@ #include "displaysettings.h" #include "aboutsettings.h" #include "developermodesettings.h" +#include "batterystatus.h" #include "diskusage.h" #include "partitionmodel.h" #include "certificatemodel.h" @@ -80,6 +81,7 @@ class SystemSettingsPlugin : public QQmlExtensionPlugin qmlRegisterType(uri, 1, 0, "CertificateModel"); qmlRegisterSingletonType(uri, 1, 0, "VpnModel", vpnmodel_api_factory); qRegisterMetaType("DeveloperModeSettings::Status"); + qmlRegisterType(uri, 1, 0, "BatteryStatus"); qmlRegisterType(uri, 1, 0, "DiskUsage"); } }; diff --git a/src/src.pro b/src/src.pro index 40d7672..172b895 100644 --- a/src/src.pro +++ b/src/src.pro @@ -6,7 +6,7 @@ QT += qml dbus systeminfo QT -= gui CONFIG += c++11 hide_symbols link_pkgconfig -PKGCONFIG += profile mlite5 timed-qt5 libshadowutils blkid libcrypto nemomodels-qt5 +PKGCONFIG += profile mlite5 mce timed-qt5 libshadowutils blkid libcrypto nemomodels-qt5 system(qdbusxml2cpp -p mceiface.h:mceiface.cpp mce.xml) system(qdbusxml2cpp -c ConnmanVpnProxy -p connmanvpnproxy ../dbus/net.connman.vpn.xml -i qdbusxml2cpp_dbus_types.h) @@ -25,6 +25,7 @@ SOURCES += \ connmanvpnproxy.cpp \ connmanvpnconnectionproxy.cpp \ developermodesettings.cpp \ + batterystatus.cpp \ diskusage.cpp \ diskusage_impl.cpp \ partition.cpp \ @@ -44,6 +45,7 @@ PUBLIC_HEADERS = \ connmanvpnproxy.h \ connmanvpnconnectionproxy.h \ developermodesettings.h \ + batterystatus.h \ diskusage.h \ partition.h \ partitionmanager.h \ @@ -53,6 +55,7 @@ PUBLIC_HEADERS = \ HEADERS += \ $$PUBLIC_HEADERS \ qdbusxml2cpp_dbus_types.h \ + batterystatus_p.h \ diskusage_p.h \ partition_p.h \ partitionmanager_p.h diff --git a/systemsettings.pro b/systemsettings.pro index 40e2e1e..9fbcd10 100644 --- a/systemsettings.pro +++ b/systemsettings.pro @@ -4,4 +4,6 @@ src_plugins.subdir = src/plugin src_plugins.target = sub-plugins src_plugins.depends = src +OTHER_FILES += rpm/nemo-qml-plugin-systemsettings.spec + SUBDIRS = src src_plugins tests