Implement BackgroundActivity-based timers

This commit is contained in:
Matti Viljanen 2021-07-25 20:54:27 +03:00
parent 8e89b48f63
commit 5627c5fc47
9 changed files with 166 additions and 109 deletions

View file

@ -45,9 +45,9 @@ Page {
highAlertSlider.value = settings.highAlert
healthSelector.currentIndex = settings.healthAlert
lowAlertSlider.value = settings.lowAlert
highIntervalSlider.value = settings.highNotificationsInterval
lowIntervalSlider.value = settings.lowNotificationsInterval
healthIntervalSlider.value = settings.healthNotificationsInterval
highIntervalCombo.currentIndex = settings.highNotificationsInterval
lowIntervalCombo.currentIndex = settings.lowNotificationsInterval
healthIntervalCombo.currentIndex = settings.healthNotificationsInterval
if(logger.debug) logger.log("SettingsPage values updated")
daemonCheck.start()
}
@ -314,60 +314,52 @@ Page {
SectionHeader { text: qsTr("Battery high notification interval") }
MySlider {
id: highIntervalSlider
minimumValue: 50
maximumValue: 610
stepSize: 10
valueText: updateValueText()
onValueChanged: updateValueText()
function updateValueText() {
if(value == 50)
return qsTr("Once")
if(value == 610)
return qsTr("Never")
return Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60)
ComboBox {
id: highIntervalCombo
label: qsTr("Battery high notification interval")
menu: ContextMenu {
Repeater {
model: frequencyNames
MenuItem {
enabled: index > 0
visible: index > 0
text: modelData
onClicked: {
highIntervalCombo.currentIndex = index
highIntervalCombo.save()
}
}
}
}
onReleased: save()
function save() {
settings.highNotificationsInterval = value
settings.highNotificationsInterval = currentIndex
}
}
AdjustmentButtons {
targetSlider: highIntervalSlider
smallChange: 10
largeChange: 60
}
SectionHeader { text: qsTr("Battery low notification interval") }
MySlider {
id: lowIntervalSlider
minimumValue: 50
maximumValue: 610
stepSize: 10
valueText: updateValueText()
onValueChanged: updateValueText()
function updateValueText() {
if(value == 50)
return qsTr("Once")
if(value == 610)
return qsTr("Never")
return Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60)
ComboBox {
id: lowIntervalCombo
label: qsTr("Battery low notification interval")
menu: ContextMenu {
Repeater {
model: frequencyNames
MenuItem {
enabled: index > 0
visible: index > 0
text: modelData
onClicked: {
lowIntervalCombo.currentIndex = index
lowIntervalCombo.save()
}
}
}
}
onReleased: save()
function save() {
settings.lowNotificationsInterval = value
settings.lowNotificationsInterval = currentIndex
}
}
AdjustmentButtons {
targetSlider: lowIntervalSlider
smallChange: 10
largeChange: 60
}
Label {
x: Theme.paddingLarge
text: qsTr("Health notification settings")
@ -406,31 +398,27 @@ Page {
SectionHeader { text: qsTr("Health notification interval") }
MySlider {
id: healthIntervalSlider
minimumValue: 50
maximumValue: 610
stepSize: 10
valueText: updateValueText()
onValueChanged: updateValueText()
function updateValueText() {
if(value == 50)
return qsTr("Once")
if(value == 610)
return qsTr("Never")
return Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60)
ComboBox {
id: healthIntervalCombo
label: qsTr("Health notification interval")
menu: ContextMenu {
Repeater {
model: frequencyNames
MenuItem {
enabled: index > 0
visible: index > 0
text: modelData
onClicked: {
healthIntervalCombo.currentIndex = index
healthIntervalCombo.save()
}
}
}
}
onReleased: save()
function save() {
settings.healthNotificationsInterval = value
settings.healthNotificationsInterval = currentIndex
}
}
AdjustmentButtons {
targetSlider: healthIntervalSlider
smallChange: 10
largeChange: 60
}
}
}
}

View file

@ -26,6 +26,7 @@
#include <QQuickView>
#include <QQmlEngine>
#include <QTimer>
#include <QStringList>
#include "logger.h"
#include "battery.h"
@ -87,10 +88,28 @@ int main(int argc, char *argv[])
qmlRegisterType<Process>("Process", 1, 0, "Process");
const QStringList frequencyNames = {
QObject::tr("Never"),
QObject::tr("30 seconds"),
QObject::tr("2.5 minutes"),
QObject::tr("5 minutes"),
QObject::tr("10 minutes"),
QObject::tr("15 minutes"),
QObject::tr("30 minutes"),
QObject::tr("1 hour"),
QObject::tr("2 hours"),
QObject::tr("4 hours"),
QObject::tr("8 hours"),
QObject::tr("10 hours"),
QObject::tr("12 hours"),
QObject::tr("24 hours"),
};
view->rootContext()->setContextProperty("battery", battery);
view->rootContext()->setContextProperty("settings", settings);
view->rootContext()->setContextProperty("logger", logger);
view->rootContext()->setContextProperty("app_version", APP_VERSION);
view->rootContext()->setContextProperty("frequencyNames", frequencyNames);
view->setSource(SailfishApp::pathTo("qml/harbour-batterybuddy.qml"));
view->showFullScreen();

View file

@ -32,9 +32,9 @@ Settings::Settings(Logger *newLogger, QObject *parent) : QObject(parent)
loadInteger(sLowAlert, lowAlert, 5, 99);
loadInteger(sHighAlert, highAlert, 6, 100);
loadInteger(sHealthAlert, healthAlert, 0, 2);
loadInteger(sHighNotificationsInterval, highNotificationsInterval, 50, 610);
loadInteger(sLowNotificationsInterval, lowNotificationsInterval, 50, 610);
loadInteger(sHealthNotificationsInterval, healthNotificationsInterval, 50, 610);
loadInteger(sHighNotificationsInterval, highNotificationsInterval, 0, 13);
loadInteger(sLowNotificationsInterval, lowNotificationsInterval, 0, 13);
loadInteger(sHealthNotificationsInterval, healthNotificationsInterval, 0, 13);
loadInteger(sLimitEnabled, limitEnabled, 0, 1);
loadInteger(sLowLimit, lowLimit, 5, 99);
loadInteger(sHighLimit, highLimit, 6, 100);

View file

@ -20,13 +20,14 @@ Source0: %{name}-%{version}.tar.bz2
Requires: sailfishsilica-qt5 >= 0.10.9
Requires: nemo-qml-plugin-configuration-qt5
Requires: nemo-qml-plugin-notifications-qt5
Requires: libkeepalive-glib-tools
Requires: libkeepalive
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
BuildRequires: pkgconfig(nemonotifications-qt5)
BuildRequires: pkgconfig(Qt5Core)
BuildRequires: pkgconfig(Qt5Qml)
BuildRequires: pkgconfig(Qt5Quick)
BuildRequires: desktop-file-utils
BuildRequires: libkeepalive
%description
Prolong your battery life.

View file

@ -24,6 +24,8 @@ DEFINES += LEGACY_BUILD=$${LEGACY_BUILD}
# See main() and logger.h for details.
DEFINES += QT_NO_DEBUG_OUTPUT
LIBS += -lkeepalive
HEADERS += \
src/battery.h \
src/logger.h \

View file

@ -17,7 +17,7 @@
*/
#include "battery.h"
Battery::Battery(Logger* newLogger, bool loglevelSet, QObject *parent) : QObject(parent)
Battery::Battery(Logger* newLogger, bool loglevelSet, QCoreApplication *app, QObject *parent) : QObject(parent)
{
logger = newLogger;
settings = new Settings(logger, this);
@ -30,10 +30,6 @@ Battery::Battery(Logger* newLogger, bool loglevelSet, QObject *parent) : QObject
logE(QString("Log level set to %1").arg((logLevel == 0 ? "low" : (logLevel == 1 ? "medium" : "high"))));
}
updateTimer = new QTimer(this);
highNotifyTimer = new QTimer(this);
lowNotifyTimer = new QTimer(this);
healthNotifyTimer = new QTimer(this);
#if LEGACY_BUILD == 1
chargeNotification = new MyNotification(logger, this);
healthNotification = new MyNotification(logger, this);
@ -111,26 +107,48 @@ Battery::Battery(Logger* newLogger, bool loglevelSet, QObject *parent) : QObject
logE("Please contact the developer with your device model!");
}
connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateData()));
connect(settings, SIGNAL(resetTimers()), this, SLOT(resetTimers()));
connect(highNotifyTimer, SIGNAL(timeout()), this, SLOT(showHighNotification()));
connect(lowNotifyTimer, SIGNAL(timeout()), this, SLOT(showLowNotification()));
connect(healthNotifyTimer, SIGNAL(timeout()), this, SLOT(showHealthNotification()));
updateTimer = new BackgroundActivity(app);
highNotifyTimer = new BackgroundActivity(app);
lowNotifyTimer = new BackgroundActivity(app);
healthNotifyTimer = new BackgroundActivity(app);
connect(updateTimer, SIGNAL(running()), this, SLOT(updateData()));
connect(highNotifyTimer, SIGNAL(running()), this, SLOT(showHighNotification()));
connect(lowNotifyTimer, SIGNAL(running()), this, SLOT(showLowNotification()));
connect(healthNotifyTimer, SIGNAL(running()), this, SLOT(showHealthNotification()));
connect(updateTimer, SIGNAL(running()), updateTimer, SLOT(wait()));
connect(highNotifyTimer, SIGNAL(running()), highNotifyTimer, SLOT(wait()));
connect(lowNotifyTimer, SIGNAL(running()), lowNotifyTimer, SLOT(wait()));
connect(healthNotifyTimer, SIGNAL(running()), healthNotifyTimer, SLOT(wait()));
updateData();
updateTimer->start(5000);
updateTimer->setWakeupFrequency(BackgroundActivity::ThirtySeconds);
updateTimer->wait();
// If updateData() didn't start the timers
// aka. "charging" status didn't change
// (or if both times are disabled, actually)
// manually trigger the timer startup.
if(!highNotifyTimer->isActive() && !lowNotifyTimer->isActive() && !healthNotifyTimer->isActive()) {
if(!highNotifyTimer->isWaiting() && !lowNotifyTimer->isWaiting() && !healthNotifyTimer->isWaiting()) {
resetTimers();
}
}
Battery::~Battery() { }
Battery::~Battery() {
updateTimer->stop();
highNotifyTimer->stop();
lowNotifyTimer->stop();
healthNotifyTimer->stop();
delete updateTimer;
delete highNotifyTimer;
delete lowNotifyTimer;
delete healthNotifyTimer;
}
void Battery::updateData()
{
@ -204,31 +222,41 @@ void Battery::resetTimers() {
highNotifyTimer->stop();
lowNotifyTimer->stop();
healthNotifyTimer->stop();
highNotifyTimer->setInterval(settings->getHighNotificationsInterval() * 1000);
lowNotifyTimer->setInterval(settings->getLowNotificationsInterval() * 1000);
healthNotifyTimer->setInterval(settings->getHealthNotificationsInterval() * 1000);
if(settings->getHighNotificationsInterval() < 610) {
if(settings->getHighNotificationsInterval() > 0) {
highNotifyTimer->setWakeupFrequency(frequencies[settings->getHighNotificationsInterval()]);
logD(QString("High notifications frequency %1 => %2 seconds")
.arg(settings->getHighNotificationsInterval())
.arg(static_cast<int>(frequencies[settings->getHighNotificationsInterval()])));
logD("Starting high battery timer");
highNotifyTimer->start();
highNotifyTimer->wait();
showHighNotification();
}
else {
logD("High battery timer not started");
}
if(settings->getLowNotificationsInterval() < 610) {
if(settings->getLowNotificationsInterval() > 0) {
lowNotifyTimer->setWakeupFrequency(frequencies[settings->getLowNotificationsInterval()]);
logD(QString("Low notifications frequency %1 => %2 seconds")
.arg(settings->getLowNotificationsInterval())
.arg(static_cast<int>(frequencies[settings->getLowNotificationsInterval()])));
logD("Start low battery timer");
lowNotifyTimer->start();
lowNotifyTimer->wait();
showLowNotification();
}
else {
logD("Low battery timer not started");
}
if(settings->getHealthNotificationsInterval() < 610) {
if(settings->getHealthNotificationsInterval() > 0) {
healthNotifyTimer->setWakeupFrequency(frequencies[settings->getHealthNotificationsInterval()]);
logD(QString("Health notifications frequency %1 => %2 seconds")
.arg(settings->getHealthNotificationsInterval())
.arg(static_cast<int>(frequencies[settings->getHealthNotificationsInterval()])));
logD("Start health timer");
healthNotifyTimer->start();
healthNotifyTimer->wait();
showHealthNotification();
}
else {
@ -237,7 +265,7 @@ void Battery::resetTimers() {
}
void Battery::showHighNotification() {
if(settings->getHighNotificationsInterval() < 610 && (charge >= settings->getHighAlert() && state != "discharging")
if(settings->getHighNotificationsInterval() > 0 && (charge >= settings->getHighAlert() && state != "discharging")
&& !(charge == 100 && state == "idle")) {
logV(QString("Notification: %1").arg(settings->getNotificationTitle().arg(charge)));
chargeNotification->send(settings->getNotificationTitle().arg(charge), settings->getNotificationHighText(), settings->getHighAlertFile());
@ -253,7 +281,7 @@ void Battery::showHighNotification() {
}
void Battery::showLowNotification() {
if(settings->getLowNotificationsInterval() < 610 && charge <= settings->getLowAlert() && state != "charging") {
if(settings->getLowNotificationsInterval() > 0 && charge <= settings->getLowAlert() && state != "charging") {
logV(QString("Notification: %1").arg(settings->getNotificationTitle().arg(charge)));
chargeNotification->send(settings->getNotificationTitle().arg(charge), settings->getNotificationLowText(), settings->getLowAlertFile());
if(settings->getLowNotificationsInterval() == 50) {
@ -284,7 +312,7 @@ void Battery::showHealthNotification() {
{ "overheat" , HealthThresh["crit"] },
{ "cold" , HealthThresh["crit"] }
};
if(settings->getHealthNotificationsInterval() < 610 && temperature != 0x7FFFFFFF && ( HealthState[health] != HealthThresh["ok"] && HealthState[health] >= settings->getHealthAlert() ) ) {
if(settings->getHealthNotificationsInterval() > 0 && temperature != 0x7FFFFFFF && ( HealthState[health] != HealthThresh["ok"] && HealthState[health] >= settings->getHealthAlert() ) ) {
QString displayTemp = QString::number(temperature / 10.0);
if (QLocale().measurementSystem() == QLocale::ImperialUSSystem)
displayTemp = QString::number((temperature / 10) * 1.8 + 32) + " F";

View file

@ -25,6 +25,8 @@
#include <QStandardPaths>
#include <QHostInfo>
#include <QLocale>
#include <QCoreApplication>
#include <keepalive/backgroundactivity.h>
#include "settings.h"
#if LEGACY_BUILD == 1
#include "mynotification_sfos2.h"
@ -38,7 +40,7 @@ class Battery : public QObject
Q_OBJECT
public:
Battery(Logger* newLogger, bool loglevelSet, QObject *parent = nullptr);
Battery(Logger* newLogger, bool loglevelSet, QCoreApplication *app, QObject *parent = nullptr);
~Battery();
int getCharge();
@ -57,6 +59,24 @@ public slots:
void shutdown();
private:
BackgroundActivity::Frequency frequencies[14] = {
BackgroundActivity::Range,
BackgroundActivity::ThirtySeconds,
BackgroundActivity::TwoAndHalfMinutes,
BackgroundActivity::FiveMinutes,
BackgroundActivity::TenMinutes,
BackgroundActivity::FifteenMinutes,
BackgroundActivity::ThirtyMinutes,
BackgroundActivity::OneHour,
BackgroundActivity::TwoHours,
BackgroundActivity::FourHours,
BackgroundActivity::EightHours,
BackgroundActivity::TenHours,
BackgroundActivity::TwelveHours,
BackgroundActivity::TwentyFourHours
};
Logger *logger;
QFile *chargeFile = nullptr;
QFile *chargerConnectedFile = nullptr;
@ -65,10 +85,10 @@ private:
QFile *temperatureFile = nullptr;
QFile *healthFile = nullptr;
Settings *settings = nullptr;
QTimer *updateTimer = nullptr;
QTimer *highNotifyTimer = nullptr;
QTimer *lowNotifyTimer = nullptr;
QTimer *healthNotifyTimer = nullptr;
BackgroundActivity *updateTimer = nullptr;
BackgroundActivity *highNotifyTimer = nullptr;
BackgroundActivity *lowNotifyTimer = nullptr;
BackgroundActivity *healthNotifyTimer = nullptr;
MyNotification *chargeNotification = nullptr;
MyNotification *healthNotification = nullptr;

View file

@ -17,7 +17,6 @@
*/
#include <QCoreApplication>
#include <QObject>
#include <QTimer>
#include "logger.h"
#include "battery.h"
@ -71,7 +70,7 @@ int main(int argc, char** argv)
Logger* logger = new Logger(verbose, debug, logfile);
logE(QString("%1 %2").arg(APP_NAME, APP_VERSION));
Battery* battery = new Battery(logger, logLevelSet);
Battery* battery = new Battery(logger, logLevelSet, &app);
// Exit gracefully on Ctrl-C and service stop
QObject::connect(&app, SIGNAL(aboutToQuit()), battery, SLOT(shutdown()));

View file

@ -53,8 +53,8 @@ Settings::Settings(Logger* newLogger, QObject *parent) : QObject(parent)
key = "notificationsEnabled";
if(mySettings->contains(key)) {
if(mySettings->value(key).toInt() == 0) {
mySettings->setValue(sHighNotificationsInterval, 610);
mySettings->setValue(sLowNotificationsInterval, 610);
mySettings->setValue(sHighNotificationsInterval, 2);
mySettings->setValue(sLowNotificationsInterval, 2);
}
else {
mySettings->setValue(sHighNotificationsInterval, highNotificationsInterval);
@ -75,7 +75,7 @@ Settings::Settings(Logger* newLogger, QObject *parent) : QObject(parent)
key = "highNotificationsEnabled";
if(mySettings->contains(key)) {
if(mySettings->value(key).toInt() == 0)
mySettings->setValue(sHighNotificationsInterval, 610);
mySettings->setValue(sHighNotificationsInterval, 2);
mySettings->remove(key);
logV(migrate.arg(key));
}
@ -83,7 +83,7 @@ Settings::Settings(Logger* newLogger, QObject *parent) : QObject(parent)
key = "lowNotificationsEnabled";
if(mySettings->contains(key)) {
if(mySettings->value(key).toInt() == 0)
mySettings->setValue(sLowNotificationsInterval, 610);
mySettings->setValue(sLowNotificationsInterval, 2);
mySettings->remove(key);
logV(migrate.arg(key));
}
@ -133,9 +133,9 @@ void Settings::updateConfig(const QString path) {
loadInteger(sLowAlert, lowAlert, 5, 99);
loadInteger(sHighAlert, highAlert, 6, 100);
loadInteger(sHealthAlert, healthAlert, 0, 2);
restartTimers |= loadInteger(sHighNotificationsInterval, highNotificationsInterval, 50, 610);
restartTimers |= loadInteger(sLowNotificationsInterval, lowNotificationsInterval, 50, 610);
restartTimers |= loadInteger(sHealthNotificationsInterval, healthNotificationsInterval, 50, 610);
restartTimers |= loadInteger(sHighNotificationsInterval, highNotificationsInterval, 0, 13);
restartTimers |= loadInteger(sLowNotificationsInterval, lowNotificationsInterval, 0, 13);
restartTimers |= loadInteger(sHealthNotificationsInterval, healthNotificationsInterval, 0, 13);
loadInteger(sLimitEnabled, limitEnabled, 0, 1);
loadInteger(sLowLimit, lowLimit, 5, 99);
loadInteger(sHighLimit, highLimit, 6, 100);