From 060bc69d8bdfe9860a71109ecf92810beb99f4da Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 17 Dec 2013 21:59:43 -0600 Subject: add clock + tests --- src/clock-live.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/clock.cpp | 98 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 src/clock-live.cpp create mode 100644 src/clock.cpp (limited to 'src') diff --git a/src/clock-live.cpp b/src/clock-live.cpp new file mode 100644 index 0000000..80e91a3 --- /dev/null +++ b/src/clock-live.cpp @@ -0,0 +1,137 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + */ + +#include + +namespace unity { +namespace indicator { +namespace datetime { + +class LiveClock::Impl +{ +public: + + Impl(LiveClock& owner, const std::shared_ptr& tzd): + owner_(owner), + timezones_(tzd) + { + if (timezones_) + { + timezones_->timezone.changed().connect ([this](const std::string& z) {setTimezone(z);}); + setTimezone(timezones_->timezone.get()); + } + + owner_.skewTestIntervalSec.changed().connect([this](unsigned int intervalSec) {setInterval(intervalSec);}); + setInterval(owner_.skewTestIntervalSec.get()); + } + + ~Impl() + { + clearTimer(); + + g_clear_pointer (&timezone_, g_time_zone_unref); + } + + GDateTime* localtime() const + { + g_assert (timezone_ != nullptr); + + return g_date_time_new_now (timezone_); + } + +private: + + void setTimezone (const std::string& str) + { + g_clear_pointer (&timezone_, g_time_zone_unref); + timezone_= g_time_zone_new (str.c_str()); + owner_.skewDetected(); + } + +private: + + void clearTimer() + { + if (skew_timeout_id_) + { + g_source_remove(skew_timeout_id_); + skew_timeout_id_ = 0; + } + + g_clear_pointer(&prev_datetime_, g_date_time_unref); + } + + void setInterval(unsigned int seconds) + { + clearTimer(); + + if (seconds > 0) + { + prev_datetime_ = owner_.localtime(); + skew_timeout_id_ = g_timeout_add_seconds(seconds, onTimerPulse, this); + } + } + + static gboolean onTimerPulse(gpointer gself) + { + auto self = static_cast(gself); + + // check to see if too much time passed since the last check */ + GDateTime * now = self->owner_.localtime(); + const GTimeSpan diff = g_date_time_difference(now, self->prev_datetime_); + const GTimeSpan fuzz = 5; + const GTimeSpan max = (self->owner_.skewTestIntervalSec.get() + fuzz) * G_USEC_PER_SEC; + if (abs(diff) > max) + self->owner_.skewDetected(); + + // update prev_datetime + g_clear_pointer(&self->prev_datetime_, g_date_time_unref); + self->prev_datetime_ = now; + + return G_SOURCE_CONTINUE; + } + +protected: + + LiveClock& owner_; + GTimeZone * timezone_ = nullptr; + std::shared_ptr timezones_; + + GDateTime * prev_datetime_ = nullptr; + unsigned int skew_timeout_id_ = 0; + unsigned int sleep_subscription_id_ = 0; +}; + +LiveClock::LiveClock(const std::shared_ptr& tzd): + p (new Impl (*this, tzd)) +{ +} + +LiveClock::~LiveClock() =default; + +GDateTime * +LiveClock::localtime() const +{ + return p->localtime(); +} + +} // namespace datetime +} // namespace indicator +} // namespace unity + diff --git a/src/clock.cpp b/src/clock.cpp new file mode 100644 index 0000000..4a75ceb --- /dev/null +++ b/src/clock.cpp @@ -0,0 +1,98 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Charles Kerr + */ + +#include + +#include +#include + +namespace unity { +namespace indicator { +namespace datetime { + +/*** +**** +***/ + +Clock::Clock(): + cancellable_(g_cancellable_new()) +{ + g_bus_get(G_BUS_TYPE_SYSTEM, cancellable_, onSystemBusReady, this); + + timezones.changed().connect([this](const std::set& timezones){ + g_message ("timezones changed... new count is %d", (int)timezones.size()); + skewDetected(); + }); +} + +Clock::~Clock() +{ + g_cancellable_cancel(cancellable_); + g_clear_object(&cancellable_); + + if (sleep_subscription_id_) + g_dbus_connection_signal_unsubscribe(system_bus_ , sleep_subscription_id_); + + g_clear_object(&system_bus_); +} + +void +Clock::onSystemBusReady(GObject*, GAsyncResult * res, gpointer gself) +{ + GDBusConnection * system_bus; + + if ((system_bus = g_bus_get_finish(res, nullptr))) + { + auto self = static_cast(gself); + + self->system_bus_ = system_bus; + + self->sleep_subscription_id_ = g_dbus_connection_signal_subscribe( + system_bus, + nullptr, + "org.freedesktop.login1.Manager", // interface + "PrepareForSleep", // signal name + "/org/freedesktop/login1", // object path + nullptr, // arg0 + G_DBUS_SIGNAL_FLAGS_NONE, + onPrepareForSleep, + self, + nullptr); + } +} + +void +Clock::onPrepareForSleep(GDBusConnection * connection G_GNUC_UNUSED, + const gchar * sender_name G_GNUC_UNUSED, + const gchar * object_path G_GNUC_UNUSED, + const gchar * interface_name G_GNUC_UNUSED, + const gchar * signal_name G_GNUC_UNUSED, + GVariant * parameters G_GNUC_UNUSED, + gpointer gself) +{ + static_cast(gself)->skewDetected(); +} + +/*** +**** +***/ + +} // namespace datetime +} // namespace indicator +} // namespace unity -- cgit v1.2.3