aboutsummaryrefslogtreecommitdiff
path: root/src/timezone-timedated.cpp
diff options
context:
space:
mode:
authorIain Lane <iain.lane@canonical.com>2015-09-09 16:40:41 +0000
committerCI Train Bot <ci-train-bot@canonical.com>2015-09-09 16:40:41 +0000
commit13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee (patch)
tree30705f0a3f047a46020c7204397649ff2c609936 /src/timezone-timedated.cpp
parentad2d17a82ebe369adca6b477d5ecb362e243f585 (diff)
parentec001e64b2225a3c80b7e89d9a570728fcbca830 (diff)
downloadayatana-indicator-datetime-13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee.tar.gz
ayatana-indicator-datetime-13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee.tar.bz2
ayatana-indicator-datetime-13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee.zip
Remove warnings from test logs. Swallow the ones that are expected and fail the test if they don't show up. In addition, fail tests if unexpected warnings show up again.
Approved by: Charles Kerr
Diffstat (limited to 'src/timezone-timedated.cpp')
-rw-r--r--src/timezone-timedated.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/timezone-timedated.cpp b/src/timezone-timedated.cpp
new file mode 100644
index 0000000..fa99cd2
--- /dev/null
+++ b/src/timezone-timedated.cpp
@@ -0,0 +1,212 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include <datetime/timezone-timedated.h>
+
+#include <gio/gio.h>
+
+#include <cerrno>
+#include <cstdlib>
+
+namespace unity {
+namespace indicator {
+namespace datetime {
+
+/***
+****
+***/
+
+class TimedatedTimezone::Impl
+{
+public:
+
+ Impl(TimedatedTimezone& owner, std::string filename):
+ m_owner(owner),
+ m_filename(filename)
+ {
+ g_debug("Filename is '%s'", filename.c_str());
+ monitor_timezone_property();
+ }
+
+ ~Impl()
+ {
+ clear();
+ }
+
+private:
+
+ void clear()
+ {
+ if (m_connection && m_signal_subscription_id)
+ {
+ g_dbus_connection_signal_unsubscribe (m_connection, m_signal_subscription_id);
+ m_signal_subscription_id = 0;
+ }
+
+ g_clear_object(&m_connection);
+ }
+
+ static void on_properties_changed (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,
+ gpointer gself)
+ {
+ auto self = static_cast<Impl*>(gself);
+ const char *tz;
+ GVariant *changed_properties;
+ gchar **invalidated_properties;
+
+ g_variant_get (parameters, "(s@a{sv}^as)", NULL, &changed_properties, &invalidated_properties);
+
+ if (g_variant_lookup(changed_properties, "Timezone", "&s", &tz, NULL))
+ self->notify_timezone(tz);
+ else if (g_strv_contains (invalidated_properties, "Timezone"))
+ self->notify_timezone(self->get_timezone_from_file(self->m_filename));
+
+ g_variant_unref (changed_properties);
+ g_strfreev (invalidated_properties);
+ }
+
+ void monitor_timezone_property()
+ {
+ GError *err = nullptr;
+
+ /*
+ * There is an unlikely race which happens if there is an activation
+ * and timezone change before our match rule is added.
+ */
+ notify_timezone(get_timezone_from_file(m_filename));
+
+ /*
+ * Make sure the bus is around at least until we add the match rules,
+ * otherwise things (tests) are sad.
+ */
+ m_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM,
+ nullptr,
+ &err);
+
+ if (err)
+ {
+ g_warning("Couldn't get bus connection: '%s'", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ m_signal_subscription_id = g_dbus_connection_signal_subscribe(m_connection,
+ "org.freedesktop.timedate1",
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ "/org/freedesktop/timedate1",
+ NULL, G_DBUS_SIGNAL_FLAGS_NONE,
+ on_properties_changed,
+ this, nullptr);
+ }
+
+ void notify_timezone(std::string new_timezone)
+ {
+ g_debug("notify_timezone '%s'", new_timezone.c_str());
+ if (!new_timezone.empty())
+ m_owner.timezone.set(new_timezone);
+ }
+
+ std::string get_timezone_from_file(const std::string& filename)
+ {
+ GError * error;
+ GIOChannel * io_channel;
+ std::string ret;
+
+ // read through filename line-by-line until we fine a nonempty non-comment line
+ error = nullptr;
+ io_channel = g_io_channel_new_file(filename.c_str(), "r", &error);
+ if (error == nullptr)
+ {
+ auto line = g_string_new(nullptr);
+
+ while(ret.empty())
+ {
+ const auto io_status = g_io_channel_read_line_string(io_channel, line, nullptr, &error);
+ if ((io_status == G_IO_STATUS_EOF) || (io_status == G_IO_STATUS_ERROR))
+ break;
+ if (error != nullptr)
+ break;
+
+ g_strstrip(line->str);
+
+ if (!line->len) // skip empty lines
+ continue;
+
+ if (*line->str=='#') // skip comments
+ continue;
+
+ ret = line->str;
+ }
+
+ g_string_free(line, true);
+ } else
+ /* Default to UTC */
+ ret = "Etc/Utc";
+
+ if (io_channel != nullptr)
+ {
+ g_io_channel_shutdown(io_channel, false, nullptr);
+ g_io_channel_unref(io_channel);
+ }
+
+ if (error != nullptr)
+ {
+ g_warning("%s Unable to read timezone file '%s': %s", G_STRLOC, filename.c_str(), error->message);
+ g_error_free(error);
+ }
+
+ return ret;
+ }
+
+ /***
+ ****
+ ***/
+
+ TimedatedTimezone & m_owner;
+ GDBusConnection *m_connection = nullptr;
+ unsigned long m_signal_subscription_id = 0;
+ std::string m_filename;
+};
+
+/***
+****
+***/
+
+TimedatedTimezone::TimedatedTimezone(std::string filename):
+ impl(new Impl{*this, filename})
+{
+}
+
+TimedatedTimezone::~TimedatedTimezone()
+{
+}
+
+/***
+****
+***/
+
+} // namespace datetime
+} // namespace indicator
+} // namespace unity