122 lines
3.4 KiB
C++
122 lines
3.4 KiB
C++
#include "SystemInfo.h"
|
|
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QFileInfo>
|
|
#include <QTextStream>
|
|
|
|
SystemInfo::SystemInfo(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
m_capacityPath = findBatteryCapacityPath();
|
|
|
|
updateBattery();
|
|
|
|
connect(&m_batteryTimer,
|
|
&QTimer::timeout,
|
|
this,
|
|
&SystemInfo::updateBattery);
|
|
|
|
// Battery percentage and charging state don't need
|
|
// millisecond precision.
|
|
m_batteryTimer.start(10000);
|
|
}
|
|
|
|
int SystemInfo::batteryPercent() const
|
|
{
|
|
return m_batteryPercent;
|
|
}
|
|
|
|
bool SystemInfo::charging() const
|
|
{
|
|
return m_charging;
|
|
}
|
|
|
|
QString SystemInfo::findBatteryCapacityPath() const
|
|
{
|
|
QDir powerSupply("/sys/class/power_supply");
|
|
|
|
const QStringList devices =
|
|
powerSupply.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
|
|
for (const QString &device : devices) {
|
|
const QString base =
|
|
powerSupply.absoluteFilePath(device);
|
|
|
|
QFile typeFile(base + "/type");
|
|
|
|
if (!typeFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
continue;
|
|
|
|
const QString type =
|
|
QString::fromUtf8(typeFile.readAll()).trimmed();
|
|
|
|
if (type != "Battery")
|
|
continue;
|
|
|
|
const QString capacityPath = base + "/capacity";
|
|
|
|
if (QFile::exists(capacityPath))
|
|
return capacityPath;
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
void SystemInfo::updateBattery()
|
|
{
|
|
if (m_capacityPath.isEmpty())
|
|
m_capacityPath = findBatteryCapacityPath();
|
|
|
|
if (m_capacityPath.isEmpty())
|
|
return;
|
|
|
|
// ─────────────────────────────────────────────────────────────
|
|
// Battery percentage
|
|
// ─────────────────────────────────────────────────────────────
|
|
|
|
QFile capacityFile(m_capacityPath);
|
|
|
|
if (capacityFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
bool ok = false;
|
|
|
|
int percent =
|
|
QString::fromUtf8(capacityFile.readAll())
|
|
.trimmed()
|
|
.toInt(&ok);
|
|
|
|
if (ok) {
|
|
percent = qBound(0, percent, 100);
|
|
|
|
if (percent != m_batteryPercent) {
|
|
m_batteryPercent = percent;
|
|
emit batteryPercentChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────
|
|
// Charging state
|
|
// ─────────────────────────────────────────────────────────────
|
|
|
|
// m_capacityPath is something like:
|
|
// /sys/class/power_supply/battery/capacity
|
|
//
|
|
// The status file lives beside it.
|
|
const QString batteryDirectory =
|
|
QFileInfo(m_capacityPath).absolutePath();
|
|
|
|
QFile statusFile(batteryDirectory + "/status");
|
|
|
|
if (statusFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
const QString status =
|
|
QString::fromUtf8(statusFile.readAll()).trimmed();
|
|
|
|
const bool charging = (status == "Charging");
|
|
|
|
if (charging != m_charging) {
|
|
m_charging = charging;
|
|
emit chargingChanged();
|
|
}
|
|
}
|
|
} |