File indexing completed on 2024-05-19 05:37:54
0001 /* 0002 SPDX-FileCopyrightText: 2007 Aaron Seigo <aseigo@kde.org> 0003 SPDX-FileCopyrightText: 2008 Alex Merry <alex.merry@kdemail.net> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "timeengine.h" 0009 0010 #include <QDBusConnection> 0011 #include <QDate> 0012 #include <QSocketNotifier> 0013 #include <QStringList> 0014 #include <QTime> 0015 0016 #ifdef Q_OS_LINUX 0017 #include <fcntl.h> 0018 #include <sys/timerfd.h> 0019 #include <unistd.h> 0020 #endif 0021 0022 #include "debug.h" 0023 #include "timesource.h" 0024 0025 // timezone is defined in msvc 0026 #ifdef timezone 0027 #undef timezone 0028 #endif 0029 0030 TimeEngine::TimeEngine(QObject *parent) 0031 : Plasma5Support::DataEngine(parent) 0032 { 0033 setMinimumPollingInterval(333); 0034 0035 // To have translated timezone names 0036 // (effectively a noop if the catalog is already present). 0037 ////KF5 port: remove this line and define TRANSLATION_DOMAIN in CMakeLists.txt instead 0038 // KLocale::global()->insertCatalog("timezones4"); 0039 QTimer::singleShot(0, this, &TimeEngine::init); 0040 } 0041 0042 TimeEngine::~TimeEngine() 0043 { 0044 } 0045 0046 void TimeEngine::init() 0047 { 0048 QDBusConnection dbus = QDBusConnection::sessionBus(); 0049 dbus.connect(QString(), QString(), QStringLiteral("org.kde.KTimeZoned"), QStringLiteral("timeZoneChanged"), this, SLOT(tzConfigChanged())); 0050 0051 #ifdef Q_OS_LINUX 0052 // monitor for the system clock being changed 0053 auto timeChangedFd = timerfd_create(CLOCK_REALTIME, O_CLOEXEC | O_NONBLOCK); 0054 itimerspec timespec; 0055 memset(×pec, 0, sizeof(timespec)); // set all timers to 0 seconds, which creates a timer that won't do anything 0056 0057 int err = timerfd_settime(timeChangedFd, 3, ×pec, nullptr); // monitor for the time changing 0058 //(flags == TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET). However these are not exposed in glibc so value is hardcoded 0059 if (err) { 0060 qCWarning(DATAENGINE_TIME) << "Could not create timer with TFD_TIMER_CANCEL_ON_SET. Clock skews will not be detected. Error:" 0061 << qPrintable(strerror(err)); 0062 } 0063 0064 connect(this, &QObject::destroyed, [timeChangedFd]() { 0065 close(timeChangedFd); 0066 }); 0067 0068 auto notifier = new QSocketNotifier(timeChangedFd, QSocketNotifier::Read, this); 0069 connect(notifier, &QSocketNotifier::activated, this, [this](int fd) { 0070 uint64_t c; 0071 read(fd, &c, 8); 0072 clockSkewed(); 0073 }); 0074 #else 0075 dbus.connect(QString(), "/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated", this, SLOT(clockSkewed())); 0076 dbus.connect(QStringLiteral("org.kde.Solid.PowerManagement"), 0077 QStringLiteral("/org/kde/Solid/PowerManagement/Actions/SuspendSession"), 0078 QStringLiteral("org.kde.Solid.PowerManagement.Actions.SuspendSession"), 0079 QStringLiteral("resumingFromSuspend"), 0080 this, 0081 SLOT(clockSkewed())); 0082 #endif 0083 } 0084 0085 void TimeEngine::clockSkewed() 0086 { 0087 qCDebug(DATAENGINE_TIME) << "Time engine Clock skew signaled"; 0088 updateAllSources(); 0089 forceImmediateUpdateOfAllVisualizations(); 0090 } 0091 0092 void TimeEngine::tzConfigChanged() 0093 { 0094 qCDebug(DATAENGINE_TIME) << "Local timezone changed signaled"; 0095 TimeSource *s = qobject_cast<TimeSource *>(containerForSource(QStringLiteral("Local"))); 0096 0097 if (s) { 0098 s->setTimeZone(QStringLiteral("Local")); 0099 } 0100 0101 updateAllSources(); 0102 forceImmediateUpdateOfAllVisualizations(); 0103 } 0104 0105 QStringList TimeEngine::sources() const 0106 { 0107 QStringList sources; 0108 Q_FOREACH (const QByteArray &tz, QTimeZone::availableTimeZoneIds()) { 0109 sources << QString(tz.constData()); 0110 } 0111 sources << QStringLiteral("Local"); 0112 return sources; 0113 } 0114 0115 bool TimeEngine::sourceRequestEvent(const QString &name) 0116 { 0117 addSource(new TimeSource(name, this)); 0118 return true; 0119 } 0120 0121 bool TimeEngine::updateSourceEvent(const QString &tz) 0122 { 0123 TimeSource *s = qobject_cast<TimeSource *>(containerForSource(tz)); 0124 0125 if (s) { 0126 s->updateTime(); 0127 return true; 0128 } 0129 0130 return false; 0131 } 0132 0133 K_PLUGIN_CLASS_WITH_JSON(TimeEngine, "plasma-dataengine-time.json") 0134 0135 #include "timeengine.moc"