diff options
author | Lorn Potter <lorn.potter@jollamobile.com> | 2013-06-23 10:24:34 +1000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-06-24 20:43:11 +0200 |
commit | bfa844cd2c5e00d824c86167de1829442527d646 (patch) | |
tree | e607f2b8c8befd1d629cc50e45d1199630ba2a92 | |
parent | a1bf12d59043356647671442688a382d74126e59 (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.qdoc | 6 | ||||
-rw-r--r-- | src/systeminfo/linux/qbatteryinfo_upower.cpp | 420 | ||||
-rw-r--r-- | src/systeminfo/linux/qbatteryinfo_upower_p.h | 120 | ||||
-rw-r--r-- | src/systeminfo/linux/qdevicekitservice_linux.cpp | 332 | ||||
-rw-r--r-- | src/systeminfo/linux/qdevicekitservice_linux_p.h | 135 | ||||
-rw-r--r-- | src/systeminfo/qbatteryinfo.cpp | 6 | ||||
-rw-r--r-- | src/systeminfo/systeminfo.pro | 19 |
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 { |