summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorn Potter <lorn.potter@jollamobile.com>2013-06-23 10:24:34 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-24 20:43:11 +0200
commitbfa844cd2c5e00d824c86167de1829442527d646 (patch)
treee607f2b8c8befd1d629cc50e45d1199630ba2a92
parenta1bf12d59043356647671442688a382d74126e59 (diff)
add UPower backend for QBattery
ported from qtmobility Change-Id: If121f23c52eb81ed605a6cbe3435b0b260b2662f Reviewed-by: Lorn Potter <lorn.potter@jollamobile.com>
-rw-r--r--doc/src/systeminfo/systeminfo.qdoc6
-rw-r--r--src/systeminfo/linux/qbatteryinfo_upower.cpp420
-rw-r--r--src/systeminfo/linux/qbatteryinfo_upower_p.h120
-rw-r--r--src/systeminfo/linux/qdevicekitservice_linux.cpp332
-rw-r--r--src/systeminfo/linux/qdevicekitservice_linux_p.h135
-rw-r--r--src/systeminfo/qbatteryinfo.cpp6
-rw-r--r--src/systeminfo/systeminfo.pro19
7 files changed, 1034 insertions, 4 deletions
diff --git a/doc/src/systeminfo/systeminfo.qdoc b/doc/src/systeminfo/systeminfo.qdoc
index ecfcdb5a..dfee8d11 100644
--- a/doc/src/systeminfo/systeminfo.qdoc
+++ b/doc/src/systeminfo/systeminfo.qdoc
@@ -40,6 +40,12 @@
activated locks, different hardware features, network, screen saver, and
storage, etc.
+ \section1 Buildtime configuration
+
+ Qt SystemInfo for Linux can use a number of technololgies based on dbus.
+ These can be configured at build time through the CONFIG of qmake.
+ * CONFIG+=upower will build the UPower dbus backend.
+
\section1 C++ Classes
\annotatedlist systeminfo
diff --git a/src/systeminfo/linux/qbatteryinfo_upower.cpp b/src/systeminfo/linux/qbatteryinfo_upower.cpp
new file mode 100644
index 00000000..ea30aa69
--- /dev/null
+++ b/src/systeminfo/linux/qbatteryinfo_upower.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtSystems module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbatteryinfo_upower_p.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+#include <QFile>
+#include "qdevicekitservice_linux_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+QBatteryInfoPrivate::QBatteryInfoPrivate(QBatteryInfo *parent)
+ : QObject(parent)
+ , q_ptr(parent),
+ cType(QBatteryInfo::UnknownCharger),
+ cState(QBatteryInfo::UnknownChargingState)
+{
+
+ watcher = new QDBusServiceWatcher("org.freedesktop.UPower",QDBusConnection::systemBus(),
+ QDBusServiceWatcher::WatchForRegistration |
+ QDBusServiceWatcher::WatchForUnregistration, this);
+ connect(watcher, SIGNAL(serviceRegistered(QString)),
+ this, SLOT(connectToUpower()));
+ connect(watcher, SIGNAL(serviceUnregistered(QString)),
+ this, SLOT(disconnectFromUpower()));
+
+ bool uPowerAvailable = QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.UPower");
+
+ if (uPowerAvailable)
+ connectToUpower();
+}
+
+QBatteryInfoPrivate::~QBatteryInfoPrivate()
+{
+}
+
+void QBatteryInfoPrivate::connectToUpower()
+{
+ getBatteryStats();
+}
+
+void QBatteryInfoPrivate::disconnectFromUpower()
+{
+}
+
+int QBatteryInfoPrivate::batteryCount()
+{
+ return batteryMap.count();
+}
+
+int QBatteryInfoPrivate::currentFlow(int battery)
+{
+ if (batteryMap.count() >= battery)
+ return (batteryMap.value(battery).value(QStringLiteral("EnergyRate")).toDouble()
+ / (batteryMap.value(battery).value(QStringLiteral("Voltage")).toInt()) * 1000);
+ else
+ return 0;
+}
+
+int QBatteryInfoPrivate::maximumCapacity(int battery)
+{
+ if (batteryMap.count() >= battery)
+ return batteryMap.value(battery).value(QStringLiteral("EnergyFull")).toInt() * 1000;
+ else
+ return 0;
+}
+
+int QBatteryInfoPrivate::remainingCapacity(int battery)
+{
+ if (batteryMap.count() >= battery)
+ return batteryMap.value(battery).value(QStringLiteral("Energy")).toInt() * 1000;
+ else
+ return 0;
+}
+
+int QBatteryInfoPrivate::remainingChargingTime(int battery)
+{
+ if (batteryMap.count() >= battery)
+ return batteryMap.value(battery).value(QStringLiteral("TimeToFull")).toInt();
+ else
+ return 0;
+}
+
+int QBatteryInfoPrivate::voltage(int battery)
+{
+ if (batteryMap.count() >= battery)
+ return (batteryMap.value(battery).value(QStringLiteral("Voltage")).toInt() * 1000);
+ else
+ return 0;
+}
+
+QBatteryInfo::ChargerType QBatteryInfoPrivate::chargerType()
+{
+ return cType;
+}
+
+QBatteryInfo::ChargingState QBatteryInfoPrivate::chargingState(int battery)
+{
+
+ return cState;
+}
+
+QBatteryInfo::EnergyUnit QBatteryInfoPrivate::energyUnit()
+{
+ return QBatteryInfo::UnitmAh;
+}
+
+QBatteryInfo::BatteryStatus QBatteryInfoPrivate::batteryStatus(int battery)
+{
+ QBatteryInfo::BatteryStatus stat = QBatteryInfo::BatteryStatusUnknown;
+ if (batteryMap.count() >= battery) {
+ int level = batteryMap.value(battery).value(QStringLiteral("Percentage")).toInt();
+ if (level < 2)
+ stat = QBatteryInfo::BatteryEmpty;
+ else if (level > 1 && level < 11)
+ stat = QBatteryInfo::BatteryLow;
+ else if (level > 10 && level < 99)
+ stat = QBatteryInfo::BatteryOk;
+ else if (level == 100)
+ stat = QBatteryInfo::BatteryFull;
+ }
+ return stat;
+}
+
+void QBatteryInfoPrivate::upowerChanged()
+{
+// QUPowerInterface *uPower = qobject_cast<QUPowerInterface*>(sender());
+// if (uPower->onBattery()) {
+// chargerTypeChanged();
+// }
+//// if (uPowerAvailable()) {
+// QBatteryInfo::ChargingState pState = QBatteryInfo::UnknownChargingState;
+
+// QUPowerInterface power(this);
+// foreach (const QDBusObjectPath &objpath, power.enumerateDevices()) {
+// QUPowerDeviceInterface powerDevice(objpath.path(),this);
+// if (powerDevice.getType() == 2) {
+// switch (powerDevice.getState()) {
+// case 0:
+// break;
+// case 1:
+// case 5:
+// pState = QBatteryInfo::Charging;
+// break;
+// case 2:
+// case 6:
+// pState = QBatteryInfo::Discharging;
+// break;
+// case 4:
+// pState = QBatteryInfo::Full;
+// break;
+// default:
+// pState = QBatteryInfo::UnknownChargingState;
+// };
+// }
+// }
+// if (!power.onBattery() && pState == QBatteryInfo::UnknownChargingState)
+// pState = QBatteryInfo::NotCharging;
+// if (curPowerState != pState) {
+// curPowerState = pState;
+// Q_EMIT powerStateChanged(pState);
+// }
+// return pState;
+ // }
+}
+
+void QBatteryInfoPrivate::upowerDeviceChanged()
+{
+ QUPowerDeviceInterface *uPowerDevice = qobject_cast<QUPowerDeviceInterface*>(sender());
+
+ if (uPowerDevice->type() == 1) {
+//line power
+ if (uPowerDevice->nativePath().contains(QStringLiteral("usb")))
+ Q_EMIT chargerTypeChanged(QBatteryInfo::USBCharger);
+ else
+ Q_EMIT chargerTypeChanged(QBatteryInfo::WallCharger);
+ }
+ if (uPowerDevice->type() == 2) {
+//battery
+ }
+}
+void QBatteryInfoPrivate::uPowerBatteryPropertyChanged(const QString &prop, const QVariant &v)
+{
+ QUPowerDeviceInterface *uPowerDevice = qobject_cast<QUPowerDeviceInterface*>(sender());
+
+ int foundBattery = 0;
+ QMapIterator<int, QVariantMap> i(batteryMap);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value().value(QStringLiteral("NativePath")).toString() == uPowerDevice->nativePath()) {
+ foundBattery = i.key();
+ break;
+ }
+ }
+
+ QVariantMap foundMap = batteryMap.value(foundBattery);
+ foundMap.insert(prop,v);
+ batteryMap.insert(foundBattery,foundMap);
+
+ if (prop == QLatin1String("Energy")) {
+ Q_EMIT remainingCapacityChanged(foundBattery, v.toDouble() * 1000);
+
+ } else if (prop == QLatin1String("EnergyRate")) {
+ Q_EMIT currentFlowChanged(foundBattery, v.toDouble() / (uPowerDevice->voltage() * 1000));
+
+ } else if (prop == QLatin1String("Percentage")) {
+ int level = v.toInt();
+ // Q_EMIT remainingCapacityChanged(foundBattery, level);
+
+ QBatteryInfo::BatteryStatus stat = QBatteryInfo::BatteryStatusUnknown;
+
+ if (level < 2)
+ stat = QBatteryInfo::BatteryEmpty;
+ else if (level > 1 && level < 11)
+ stat = QBatteryInfo::BatteryLow;
+ else if (level > 10 && level < 99)
+ stat = QBatteryInfo::BatteryOk;
+ else if (level == 100)
+ stat = QBatteryInfo::BatteryFull;
+
+ // if (batteryMap.value(foundBattery).value(QStringLiteral("Percentage")).toInt() != stat) {
+ Q_EMIT batteryStatusChanged(foundBattery, stat);
+ // }
+
+ } else if (prop == QLatin1String("Voltage")) {
+ Q_EMIT voltageChanged(foundBattery,v.toDouble() * 1000 );
+
+ } else if (prop == QLatin1String("State")) {
+
+ QBatteryInfo::ChargingState curChargeState = getCurrentChargingState(v.toInt());
+
+ if (curChargeState != cState) {
+ cState = curChargeState;
+ Q_EMIT chargingStateChanged(foundBattery,curChargeState);
+ }
+
+ } else if (prop == QLatin1String("Capacity")) {
+ qDebug() << "Your battery just got less capacity";
+ } else if (prop == QLatin1String("TimeToFull")) {
+
+ Q_EMIT remainingChargingTimeChanged(foundBattery,v.toInt());
+
+ } else if (prop == QLatin1String("Type")) {
+ if (uPowerDevice->isOnline()) {
+ QBatteryInfo::ChargerType curCharger = curCharger = getChargerType(uPowerDevice->nativePath());
+ if (curCharger != cType) {
+ cType = curCharger;
+ Q_EMIT chargerTypeChanged(cType);
+ }
+ }
+ }
+}
+
+QBatteryInfo::ChargerType QBatteryInfoPrivate::getChargerType(const QString &path)
+{
+ QFile charger;
+ QBatteryInfo::ChargerType chargerType = QBatteryInfo::UnknownCharger;
+ charger.setFileName(path + "/type");
+ if (charger.open(QIODevice::ReadOnly)) {
+ QString line = charger.readAll().simplified();
+ if (line == QStringLiteral("USB")) {
+ chargerType = QBatteryInfo::USBCharger;
+
+ } else if (line == QStringLiteral("Mains")) {
+ chargerType = QBatteryInfo::WallCharger;
+ }
+ }
+ charger.close();
+ return chargerType;
+}
+
+QBatteryInfo::ChargingState QBatteryInfoPrivate::getCurrentChargingState(int state)
+{
+ QBatteryInfo::ChargingState curChargeState = QBatteryInfo::UnknownChargingState;
+ switch (state) {
+ case 1: // charging
+ {
+ curChargeState = QBatteryInfo::Charging;
+ }
+ break;
+ case 2: //discharging
+ case 3: //empty
+ curChargeState = QBatteryInfo::Discharging;
+ break;
+ case 4: //fully charged
+ curChargeState = QBatteryInfo::NotCharging;
+ break;
+ case 5: //pending charge
+ case 6: //pending discharge
+ break;
+ default:
+ curChargeState = QBatteryInfo::UnknownChargingState;
+ break;
+ };
+ qDebug() << Q_FUNC_INFO << state << curChargeState;
+
+ return curChargeState;
+}
+
+void QBatteryInfoPrivate::getBatteryStats()
+{
+ qDebug() << Q_FUNC_INFO;
+
+ int batteryNumber = 0;
+ batteryMap.clear();
+ QUPowerInterface *power;
+ power = new QUPowerInterface(this);
+
+ connect(power,SIGNAL(changed()),
+ this,SLOT(upowerChanged()));
+ connect(power,SIGNAL(deviceAdded(QString)),
+ this,SLOT(deviceAdded(QString)));
+ connect(power,SIGNAL(deviceRemoved(QString)),
+ this,SLOT(deviceRemoved(QString)));
+
+ foreach (const QDBusObjectPath &objpath, power->enumerateDevices()) {
+ QUPowerDeviceInterface *battery;
+ battery = new QUPowerDeviceInterface(objpath.path(),this);
+
+ if (!battery->isPowerSupply())
+ continue;
+ if (battery->type() == 1) { //line power
+ cType = getChargerType(battery->nativePath());
+ }
+ if (battery->type() == 2) { //battery power
+
+ batteryMap.insert(++batteryNumber,battery->getProperties());
+
+ connect(battery,SIGNAL(changed()),this,SLOT(upowerDeviceChanged()));
+ connect(battery,SIGNAL(propertyChanged(QString,QVariant)),
+ this,SLOT(uPowerBatteryPropertyChanged(QString,QVariant)));
+
+ cState = getCurrentChargingState(battery->state());
+
+ } //end enumerateDevices
+ }
+}
+
+void QBatteryInfoPrivate::deviceAdded(const QString &path)
+{
+ QUPowerDeviceInterface *battery;
+ battery = new QUPowerDeviceInterface(path,this);
+ int batteryNumber = batteryCount();
+
+ if (battery->type() == 2) {
+ batteryMap.insert(++batteryNumber,battery->getProperties());
+ connect(battery,SIGNAL(changed()),this,SLOT(upowerDeviceChanged()));
+ connect(battery,SIGNAL(propertyChanged(QString,QVariant)),
+ this,SLOT(uPowerBatteryPropertyChanged(QString,QVariant)));
+
+ }
+}
+
+void QBatteryInfoPrivate::deviceRemoved(const QString &path)
+{
+ QUPowerDeviceInterface *battery;
+ battery = new QUPowerDeviceInterface(path,this);
+
+ int foundBattery = 0;
+ QMapIterator<int, QVariantMap> i(batteryMap);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value().value(QStringLiteral("NativePath")).toString()
+ == battery->nativePath()) {
+ foundBattery = i.key();
+ break;
+ }
+ }
+
+ if (battery->type() == 2) {
+ batteryMap.remove(foundBattery);
+ disconnect(battery,SIGNAL(changed()),this,SLOT(upowerDeviceChanged()));
+ disconnect(battery,SIGNAL(propertyChanged(QString,QVariant)),
+ this,SLOT(uPowerBatteryPropertyChanged(QString,QVariant)));
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/systeminfo/linux/qbatteryinfo_upower_p.h b/src/systeminfo/linux/qbatteryinfo_upower_p.h
new file mode 100644
index 00000000..b06fa6bd
--- /dev/null
+++ b/src/systeminfo/linux/qbatteryinfo_upower_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtSystems module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QBATTERYINFO_UPOWER_P_H
+#define QBATTERYINFO_UPOWER_P_H
+
+#include <qbatteryinfo.h>
+
+#include <QtCore/qmap.h>
+#include <QtCore/QVariantMap>
+#include <QtCore/QMap>
+#include <QtDBus/QDBusServiceWatcher>
+
+QT_BEGIN_NAMESPACE
+
+class QBatteryInfoPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QBatteryInfoPrivate(QBatteryInfo *parent);
+ ~QBatteryInfoPrivate();
+
+ int batteryCount();
+ int currentFlow(int battery);
+ int maximumCapacity(int battery);
+ int remainingCapacity(int battery);
+ int remainingChargingTime(int battery);
+ int voltage(int battery);
+ QBatteryInfo::ChargerType chargerType();
+ QBatteryInfo::ChargingState chargingState(int battery);
+ QBatteryInfo::EnergyUnit energyUnit();
+ QBatteryInfo::BatteryStatus batteryStatus(int battery);
+
+Q_SIGNALS:
+ void batteryCountChanged(int count);
+ void chargerTypeChanged(QBatteryInfo::ChargerType type);
+ void chargingStateChanged(int battery, QBatteryInfo::ChargingState state);
+ void currentFlowChanged(int battery, int flow);
+ void remainingCapacityChanged(int battery, int capacity);
+ void remainingChargingTimeChanged(int battery, int seconds);
+ void voltageChanged(int battery, int voltage);
+ void batteryStatusChanged(int battery, QBatteryInfo::BatteryStatus);
+
+protected:
+ QMap <int,QVariantMap> batteryMap;
+ QBatteryInfo::ChargerType cType;
+ QBatteryInfo::ChargingState cState;
+private Q_SLOTS:
+ void upowerDeviceChanged();
+ void upowerChanged();
+ void uPowerBatteryPropertyChanged(const QString & prop, const QVariant &v);
+ void getBatteryStats();
+ void deviceAdded(const QString &path);
+ void deviceRemoved(const QString &path);
+ void connectToUpower();
+ void disconnectFromUpower();
+
+private:
+ QBatteryInfo * const q_ptr;
+ Q_DECLARE_PUBLIC(QBatteryInfo)
+ QDBusServiceWatcher *watcher;
+
+ QBatteryInfo::ChargingState getCurrentChargingState(int);
+ QBatteryInfo::ChargerType getChargerType(const QString &path);
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QBATTERYINFO_UPOWER_P_H
diff --git a/src/systeminfo/linux/qdevicekitservice_linux.cpp b/src/systeminfo/linux/qdevicekitservice_linux.cpp
new file mode 100644
index 00000000..15faae13
--- /dev/null
+++ b/src/systeminfo/linux/qdevicekitservice_linux.cpp
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtSystems module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdevicekitservice_linux_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#define UPOWER_SERVICE "org.freedesktop.UPower"
+#define UPOWER_PATH "/org/freedesktop/UPower"
+#define UPOWER_DEVICE_SERVICE "org.freedesktop.UPower.Device"
+#define UPOWER_DEVICE_PATH "/org/freedesktop/UPower/Device"
+
+QUPowerInterface::QUPowerInterface(QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(UPOWER_SERVICE)
+ , QLatin1String(UPOWER_PATH)
+ , UPOWER_SERVICE
+ , QDBusConnection::systemBus()
+ , parent)
+{
+}
+
+QUPowerInterface::~QUPowerInterface()
+{
+}
+
+QList<QDBusObjectPath> QUPowerInterface::enumerateDevices()
+{
+ QDBusPendingReply<QList<QDBusObjectPath> > reply = call(QLatin1String("EnumerateDevices"));
+ reply.waitForFinished();
+ if (reply.isError())
+ qDebug() << reply.error().message();
+ return reply.value();
+}
+
+QVariant QUPowerInterface::getProperty(const QString &property)
+{
+ QVariant var;
+ QDBusInterface *interface = new QDBusInterface(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus());
+ if (interface && interface->isValid()) {
+ QDBusReply<QVariant> r = interface->call(QStringLiteral("Get"), QStringLiteral(UPOWER_PATH), property);
+ var = r.value();
+ }
+ return var;
+}
+
+void QUPowerInterface::connectNotify(const QMetaMethod &signal)
+{
+ static const QMetaMethod changedSignal = QMetaMethod::fromSignal(&QUPowerInterface::changed);
+ static const QMetaMethod addedSignal = QMetaMethod::fromSignal(&QUPowerInterface::deviceAdded);
+ static const QMetaMethod removedSignal = QMetaMethod::fromSignal(&QUPowerInterface::deviceRemoved);
+ if (signal == changedSignal) {
+ if (!connection().connect(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral("Changed"),
+ this, SIGNAL(changed()))) {
+ qDebug() << "Error"<<connection().lastError().message();
+ }
+ }
+ if (signal == addedSignal) {
+ if (!connection().connect(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral("DeviceAdded"),
+ this, SIGNAL(onDeviceAdded(QDBusObjectPath)))) {
+ qDebug() << "Error"<<connection().lastError().message();
+ }
+
+ }
+ if (signal == removedSignal) {
+ if (!connection().connect(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral("DeviceRemoved"),
+ this, SIGNAL(onDeviceRemoved(QDBusObjectPath)))) {
+ qDebug() << "Error"<<connection().lastError().message();
+ }
+ }
+}
+
+void QUPowerInterface::disconnectNotify(const QMetaMethod &signal)
+{
+ static const QMetaMethod changedSignal = QMetaMethod::fromSignal(&QUPowerInterface::changed);
+ static const QMetaMethod addedSignal = QMetaMethod::fromSignal(&QUPowerInterface::deviceAdded);
+ static const QMetaMethod removedSignal = QMetaMethod::fromSignal(&QUPowerInterface::deviceRemoved);
+ if (signal == changedSignal) {
+ if (!connection().disconnect(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral("Changed"),
+ this, SIGNAL(changed()))) {
+ qDebug() << "Error"<<connection().lastError().message();
+ }
+ }
+ if (signal == addedSignal) {
+ if (!connection().disconnect(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral("DeviceAdded"),
+ this, SLOT(onDeviceAdded(QDBusObjectPath)))) {
+ qDebug() << "Error"<<connection().lastError().message();
+ }
+
+ }
+ if (signal == removedSignal) {
+ if (!connection().disconnect(QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral(UPOWER_PATH),
+ QStringLiteral(UPOWER_SERVICE),
+ QStringLiteral("DeviceRemoved"),
+ this, SLOT(onDeviceRemoved(QDBusObjectPath)))) {
+ qDebug() << "Error"<<connection().lastError().message();
+ }
+ }
+
+}
+
+bool QUPowerInterface::onBattery()
+{
+ return getProperty(QStringLiteral("OnBattery")).toBool();
+}
+
+void QUPowerInterface::onDeviceAdded(const QDBusObjectPath &path)
+{
+ Q_EMIT deviceAdded(path.path());
+}
+
+void QUPowerInterface::onDeviceRemoved(const QDBusObjectPath &path)
+{
+ Q_EMIT deviceRemoved(path.path());
+}
+
+QUPowerDeviceInterface::QUPowerDeviceInterface(const QString &dbusPathName, QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(UPOWER_SERVICE)
+ , dbusPathName
+ , UPOWER_DEVICE_SERVICE
+ , QDBusConnection::systemBus()
+ , parent)
+{
+ propertiesInterface = new QDBusInterface(QStringLiteral(UPOWER_SERVICE), path(),
+ QStringLiteral("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus());
+ pMap = getProperties();
+}
+
+QUPowerDeviceInterface::~QUPowerDeviceInterface()
+{
+}
+
+QVariantMap QUPowerDeviceInterface::getProperties()
+{
+ QDBusPendingReply<QVariantMap> reply = propertiesInterface->call(QLatin1String("GetAll"),
+ QLatin1String("org.freedesktop.UPower.Device"));
+ reply.waitForFinished();
+ if (!reply.isValid())
+ qDebug() << reply.error();
+
+ pMap = reply.value();
+ return pMap;
+ // QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ // connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ // SLOT(propertiesFinished(QDBusPendingCallWatcher*)));
+}
+
+//void QUPowerDeviceInterface::propertiesFinished(QDBusPendingCallWatcher *watch)
+//{
+// QDBusPendingReply<QVariantMap> reply = *watch;
+// if (reply.isError()) {
+// qDebug() << Q_FUNC_INFO << reply.error();
+// }
+// Q_EMIT getPropertiesFinished(reply.value());
+//}
+
+QVariant QUPowerDeviceInterface::getProperty(const QString &property)
+{
+ return pMap.value(property);
+}
+
+quint16 QUPowerDeviceInterface::type()
+{
+ return getProperty(QStringLiteral("Type")).toUInt();
+}
+
+bool QUPowerDeviceInterface::isPowerSupply()
+{
+ return getProperty(QStringLiteral("PowerSupply")).toBool();
+}
+
+bool QUPowerDeviceInterface::isOnline()
+{
+ return getProperty(QStringLiteral("Online")).toBool();
+}
+
+double QUPowerDeviceInterface::currentEnergy()
+{
+ return getProperty(QStringLiteral("Energy")).toDouble();
+}
+
+double QUPowerDeviceInterface::energyWhenFull()
+{
+ return getProperty(QStringLiteral("EnergyFull")).toDouble();
+}
+
+double QUPowerDeviceInterface::energyDischargeRate()
+{
+ return getProperty(QStringLiteral("EnergyRate")).toDouble();
+}
+
+double QUPowerDeviceInterface::voltage()
+{
+ return getProperty(QStringLiteral("Voltage")).toDouble();
+}
+
+qint64 QUPowerDeviceInterface::timeToFull()
+{
+ return getProperty(QStringLiteral("TimeToFull")).toUInt();
+}
+
+double QUPowerDeviceInterface::percentLeft()
+{
+ return getProperty(QStringLiteral("Percentage")).toDouble();
+}
+
+quint16 QUPowerDeviceInterface::state()
+{
+ return getProperty(QStringLiteral("State")).toUInt();
+}
+
+void QUPowerDeviceInterface::connectNotify(const QMetaMethod &signal)
+{
+ static const QMetaMethod changedSignal = QMetaMethod::fromSignal(&QUPowerDeviceInterface::changed);
+ static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QUPowerDeviceInterface::propertyChanged);
+
+ if (signal == changedSignal) {
+ if (!connection().connect(QLatin1String(UPOWER_SERVICE),
+ path(),
+ QLatin1String(UPOWER_DEVICE_SERVICE),
+ QLatin1String("Changed"),
+ this, SIGNAL(changed()))) {
+ qDebug() << "Error" << connection().lastError().message();
+ }
+ }
+ if (signal == propertyChangedSignal) {
+ if (!connection().connect(QLatin1String(UPOWER_SERVICE),
+ path(),
+ QLatin1String(UPOWER_DEVICE_SERVICE),
+ QLatin1String("Changed"),
+ this, SIGNAL(propChanged()))) {
+ qDebug() << "Error" << connection().lastError().message();
+ }
+ }
+}
+
+void QUPowerDeviceInterface::disconnectNotify(const QMetaMethod &signal)
+{
+ static const QMetaMethod changedSignal = QMetaMethod::fromSignal(&QUPowerDeviceInterface::changed);
+ static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QUPowerDeviceInterface::propertyChanged);
+ if (signal == changedSignal) {
+ connection().disconnect(QLatin1String(UPOWER_SERVICE),
+ path(),
+ QLatin1String(UPOWER_DEVICE_SERVICE),
+ QLatin1String("Changed"),
+ this, SIGNAL(changed()));
+ }
+ if (signal == propertyChangedSignal) {
+ connection().disconnect(QLatin1String(UPOWER_SERVICE),
+ path(),
+ QLatin1String(UPOWER_DEVICE_SERVICE),
+ QLatin1String("Changed"),
+ this, SIGNAL(propChanged()));
+ }
+}
+
+void QUPowerDeviceInterface::propChanged()
+{
+ QVariantMap map = pMap;
+ QMapIterator<QString, QVariant> i(getProperties());
+
+ while (i.hasNext()) {
+ i.next();
+ if (pMap.value(i.key()) != map.value(i.key())) {
+ Q_EMIT propertyChanged(i.key(), QVariant::fromValue(i.value()));
+ }
+ }
+}
+
+QString QUPowerDeviceInterface::nativePath()
+{
+ return getProperty(QStringLiteral("NativePath")).toString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/systeminfo/linux/qdevicekitservice_linux_p.h b/src/systeminfo/linux/qdevicekitservice_linux_p.h
new file mode 100644
index 00000000..a5407203
--- /dev/null
+++ b/src/systeminfo/linux/qdevicekitservice_linux_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtSystems module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDEVICEKITSERVICE_H
+#define QDEVICEKITSERVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtDBus/QtDBus>
+
+QT_BEGIN_NAMESPACE
+
+
+class QUPowerInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+ QUPowerInterface(QObject *parent = 0);
+ ~QUPowerInterface();
+
+ bool onBattery();
+
+ QList<QDBusObjectPath> enumerateDevices();
+
+Q_SIGNALS:
+ void changed();
+ void deviceAdded(const QString &path);
+ void deviceRemoved(const QString &path);
+
+protected:
+ void connectNotify(const QMetaMethod &signal);
+ void disconnectNotify(const QMetaMethod &signal);
+
+private:
+ QVariant getProperty(const QString &property);
+
+private Q_SLOTS:
+ void onDeviceAdded(const QDBusObjectPath &path);
+ void onDeviceRemoved(const QDBusObjectPath &path);
+};
+
+class QUPowerDeviceInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ QUPowerDeviceInterface(const QString &dbusPathName,QObject *parent = 0);
+ ~QUPowerDeviceInterface();
+
+
+ bool isPowerSupply();
+ bool isOnline();
+ double currentEnergy();
+ double energyWhenFull();
+ double energyDischargeRate();
+ double percentLeft();
+ double voltage();
+ quint16 state();
+ quint16 type();
+ qint64 timeToFull();
+ QString nativePath();
+
+ QVariantMap getProperties();
+
+Q_SIGNALS:
+ void changed();
+ void propertyChanged(QString,QVariant);
+// void getPropertiesFinished(const QVariantMap &properties);
+
+protected:
+ void connectNotify(const QMetaMethod &signal);
+ void disconnectNotify(const QMetaMethod &signal);
+
+private:
+ QVariant getProperty(const QString &);
+ QDBusInterface *propertiesInterface;
+ QVariantMap pMap;
+
+private Q_SLOTS:
+ void propChanged();
+ //void propertiesFinished(QDBusPendingCallWatcher *watch);
+
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QDEVICEKITSERVICE_H
diff --git a/src/systeminfo/qbatteryinfo.cpp b/src/systeminfo/qbatteryinfo.cpp
index f6abcc7e..d3442f80 100644
--- a/src/systeminfo/qbatteryinfo.cpp
+++ b/src/systeminfo/qbatteryinfo.cpp
@@ -44,7 +44,11 @@
#if defined(QT_SIMULATOR)
# include "simulator/qsysteminfo_simulator_p.h"
#elif defined(Q_OS_LINUX)
-# include "linux/qbatteryinfo_linux_p.h"
+#if defined(QT_NO_UPOWER)
+#include "linux/qbatteryinfo_linux_p.h"
+#else
+#include "linux/qbatteryinfo_upower_p.h"
+#endif
#elif defined(Q_OS_WIN)
# include "windows/qbatteryinfo_win_p.h"
#elif defined(Q_OS_MAC)
diff --git a/src/systeminfo/systeminfo.pro b/src/systeminfo/systeminfo.pro
index 29da3049..fc8d44be 100644
--- a/src/systeminfo/systeminfo.pro
+++ b/src/systeminfo/systeminfo.pro
@@ -63,13 +63,11 @@ win32: !simulator: {
linux-*: !simulator: {
PRIVATE_HEADERS += linux/qdeviceinfo_linux_p.h \
linux/qstorageinfo_linux_p.h \
- linux/qbatteryinfo_linux_p.h \
linux/qnetworkinfo_linux_p.h \
linux/qscreensaver_linux_p.h
SOURCES += linux/qdeviceinfo_linux.cpp \
linux/qstorageinfo_linux.cpp \
- linux/qbatteryinfo_linux.cpp \
linux/qnetworkinfo_linux.cpp \
linux/qscreensaver_linux.cpp
@@ -101,8 +99,23 @@ linux-*: !simulator: {
} else: {
DEFINES += QT_NO_UDISKS
}
+ contains(CONFIG,upower): {
+ QT += dbus
+ SOURCES += linux/qdevicekitservice_linux.cpp \
+ linux/qbatteryinfo_upower.cpp
+ HEADERS += linux/qdevicekitservice_linux_p.h \
+ linux/qbatteryinfo_upower_p.h
+ } else {
+ HEADERS += linux/qbatteryinfo_linux_p.h
+ SOURCES += linux/qbatteryinfo_linux.cpp
+
+ DEFINES += QT_NO_UPOWER
+ }
+
} else {
- DEFINES += QT_NO_OFONO QT_NO_UDISKS
+ DEFINES += QT_NO_OFONO QT_NO_UDISKS QT_NO_UPOWER
+ HEADERS += linux/qbatteryinfo_linux_p.h
+ SOURCES += linux/qbatteryinfo_linux.cpp
}
config_udev {