[gnome-control-center] datetime: Port to systemd's timedated service



commit 90f78394f60882b95793976c2d113b5f275acad5
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Thu Jan 19 14:15:01 2012 +0100

    datetime: Port to systemd's timedated service
    
    https://bugzilla.gnome.org/show_bug.cgi?id=658352

 configure.ac                                       |    2 +-
 panels/datetime/Makefile.am                        |   47 +-
 panels/datetime/cc-datetime-panel.c                |  245 +-
 panels/datetime/dtm.c                              | 3066 --------------------
 panels/datetime/dtm.h                              |  475 ---
 .../org.gnome.controlcenter.datetime.policy.in     |   21 +
 panels/datetime/set-timezone.c                     |  479 ---
 panels/datetime/set-timezone.h                     |   57 -
 panels/datetime/timedated1-interface.xml           |   27 +
 po/POTFILES.in                                     |    1 +
 10 files changed, 238 insertions(+), 4182 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 43b2ed8..850d1e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,7 +76,7 @@ DESKTOP_SCHEMAS_REQUIRED_VERSION=3.0.2
 PA_REQUIRED_VERSION=0.9.16
 CANBERRA_REQUIRED_VERSION=0.13
 GDKPIXBUF_REQUIRED_VERSION=2.23.0
-POLKIT_REQUIRED_VERSION=0.97
+POLKIT_REQUIRED_VERSION=0.103
 GSD_REQUIRED_VERSION=3.3.4
 NETWORK_MANAGER_REQUIRED_VERSION=0.8.992
 LIBNOTIFY_REQUIRED_VERSION=0.7.3
diff --git a/panels/datetime/Makefile.am b/panels/datetime/Makefile.am
index e32929f..e08425a 100644
--- a/panels/datetime/Makefile.am
+++ b/panels/datetime/Makefile.am
@@ -98,11 +98,23 @@ check-local: test-timezone-gfx test-endianess test-timezone
 ccpanelsdir = $(PANELS_DIR)
 ccpanels_LTLIBRARIES = libdate_time.la
 
-# FIXME add a way to regenerate the dtm.[ch]
-# gdbus-codegen --generate-c-code dtm  --interface-prefix org.gnome.SettingsDaemon  /path/to/gnome-settings-daemon/plugins/datetime/gsd-datetime-mechanism.xml
-# See also:
-# https://bugzilla.gnome.org/show_bug.cgi?id=650875
-# https://bugzilla.gnome.org/show_bug.cgi?id=650874
+
+# This requires running d-bus session and accessible timedate1 daemon
+# FIXME: need to find a way how to filter out unnecessary d-bus stuff (introspectable, properties)
+#timedated1-interface.xml:
+#	gdbus introspect					\
+#		--xml						\
+#		--system					\
+#		--dest org.freedesktop.timedate1		\
+#		--object-path /org/freedesktop/timedate1	\
+#		 > timedated1-interface.xml
+
+dbus_built_sources = timedated.c timedated.h
+$(dbus_built_sources) : Makefile.am timedated1-interface.xml
+	gdbus-codegen						\
+		--interface-prefix org.freedesktop.		\
+		--generate-c-code timedated			\
+		timedated1-interface.xml
 
 libdate_time_la_SOURCES =	\
 	datetime-module.c	\
@@ -110,22 +122,37 @@ libdate_time_la_SOURCES =	\
 	cc-datetime-panel.h	\
 	cc-timezone-map.c	\
 	cc-timezone-map.h	\
-	dtm.c			\
-	dtm.h			\
 	date-endian.c		\
 	date-endian.h		\
-	tz.c tz.h
+	tz.c tz.h		\
+	$(dbus_built_sources)	\
+	$(NULL)
 
 libdate_time_la_LIBADD = $(PANEL_LIBS) $(DATETIME_PANEL_LIBS)
 libdate_time_la_LDFLAGS = $(PANEL_LDFLAGS)
 
+
+polkitdir = $(datadir)/polkit-1/actions
+polkit_in_files = org.gnome.controlcenter.datetime.policy.in
+
+ INTLTOOL_POLICY_RULE@
+polkit_DATA = $(polkit_in_files:.policy.in=.policy)
+
+
 @INTLTOOL_DESKTOP_RULE@
 
 desktopdir = $(datadir)/applications
 desktop_in_files = gnome-datetime-panel.desktop.in
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 
-CLEANFILES = $(desktop_in_files) $(desktop_DATA)
+CLEANFILES =					\
+	$(desktop_in_files)			\
+	$(desktop_DATA)				\
+	$(dbus_built_sources)			\
+	org.gnome.controlcenter.datetime.policy
 
--include $(top_srcdir)/git.mk
+EXTRA_DIST =				\
+	timedated1-interface.xml	\
+	$(polkit_in_files)
 
+-include $(top_srcdir)/git.mk
diff --git a/panels/datetime/cc-datetime-panel.c b/panels/datetime/cc-datetime-panel.c
index e327221..111cbe9 100644
--- a/panels/datetime/cc-datetime-panel.c
+++ b/panels/datetime/cc-datetime-panel.c
@@ -24,7 +24,7 @@
 
 #include <sys/time.h>
 #include "cc-timezone-map.h"
-#include "dtm.h"
+#include "timedated.h"
 #include "date-endian.h"
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 
@@ -82,7 +82,7 @@ struct _CcDateTimePanelPrivate
 
   GnomeWallClock *clock_tracker;
 
-  DateTimeMechanism *dtm;
+  Timedate1 *dtm;
   GCancellable *cancellable;
 
   GPermission *permission;
@@ -300,9 +300,9 @@ set_time_cb (GObject      *source,
   GError *error;
 
   error = NULL;
-  if (!date_time_mechanism_call_set_time_finish (self->priv->dtm,
-                                                 res,
-                                                 &error))
+  if (!timedate1_call_set_time_finish (self->priv->dtm,
+                                       res,
+                                       &error))
     {
       /* TODO: display any error in a user friendly way */
       g_warning ("Could not set system time: %s", error->message);
@@ -323,9 +323,9 @@ set_timezone_cb (GObject      *source,
   GError *error;
 
   error = NULL;
-  if (!date_time_mechanism_call_set_timezone_finish (self->priv->dtm,
-                                                     res,
-                                                     &error))
+  if (!timedate1_call_set_timezone_finish (self->priv->dtm,
+                                           res,
+                                           &error))
     {
       /* TODO: display any error in a user friendly way */
       g_warning ("Could not set system timezone: %s", error->message);
@@ -342,9 +342,9 @@ set_using_ntp_cb (GObject      *source,
   GError *error;
 
   error = NULL;
-  if (!date_time_mechanism_call_set_using_ntp_finish (self->priv->dtm,
-                                                      res,
-                                                      &error))
+  if (!timedate1_call_set_ntp_finish (self->priv->dtm,
+                                      res,
+                                      &error))
     {
       /* TODO: display any error in a user friendly way */
       g_warning ("Could not set system to use NTP: %s", error->message);
@@ -357,14 +357,16 @@ queue_set_datetime (CcDateTimePanel *self)
 {
   time_t unixtime;
 
-  /* for now just do it */
+  /* timedated expects number of microseconds since 1 Jan 1970 UTC */
   unixtime = g_date_time_to_unix (self->priv->date);
 
-  date_time_mechanism_call_set_time (self->priv->dtm,
-                                     unixtime,
-                                     self->priv->cancellable,
-                                     set_time_cb,
-                                     self);
+  timedate1_call_set_time (self->priv->dtm,
+                           unixtime * 1000000,
+                           FALSE,
+                           TRUE,
+                           self->priv->cancellable,
+                           set_time_cb,
+                           self);
 }
 
 static void
@@ -375,11 +377,12 @@ queue_set_ntp (CcDateTimePanel *self)
   /* for now just do it */
   using_ntp = gtk_switch_get_active (GTK_SWITCH (W("network_time_switch")));
 
-  date_time_mechanism_call_set_using_ntp (self->priv->dtm,
-                                          using_ntp,
-                                          self->priv->cancellable,
-                                          set_using_ntp_cb,
-                                          self);
+  timedate1_call_set_ntp (self->priv->dtm,
+                          using_ntp,
+                          TRUE,
+                          self->priv->cancellable,
+                          set_using_ntp_cb,
+                          self);
 }
 
 static void
@@ -388,11 +391,12 @@ queue_set_timezone (CcDateTimePanel *self)
   /* for now just do it */
   if (self->priv->current_location)
     {
-      date_time_mechanism_call_set_timezone (self->priv->dtm,
-                                             self->priv->current_location->zone,
-                                             self->priv->cancellable,
-                                             set_timezone_cb,
-                                             self);
+      timedate1_call_set_timezone (self->priv->dtm,
+                                   self->priv->current_location->zone,
+                                   TRUE,
+                                   self->priv->cancellable,
+                                   set_timezone_cb,
+                                   self);
     }
 }
 
@@ -549,46 +553,18 @@ location_changed_cb (CcTimezoneMap   *map,
 }
 
 static void
-get_timezone_cb (GObject      *source,
-                 GAsyncResult *res,
-                 gpointer      user_data)
+get_initial_timezone (CcDateTimePanel *self)
 {
-  CcDateTimePanel *self = user_data;
-  GtkWidget *widget;
-  gchar *timezone;
-  GError *error;
+  const gchar *timezone;
 
-  error = NULL;
-  if (!date_time_mechanism_call_get_timezone_finish (self->priv->dtm, &timezone, res, &error))
-    {
-      g_warning ("Could not get current timezone: %s", error->message);
-      g_error_free (error);
-    }
-  else
+  timezone = timedate1_get_timezone (self->priv->dtm);
+  if (!cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->priv->map), timezone))
     {
-      if (!cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->priv->map), timezone))
-        {
-          g_warning ("Timezone '%s' is unhandled, setting %s as default", timezone, DEFAULT_TZ);
-          cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->priv->map), DEFAULT_TZ);
-        }
-      self->priv->current_location = cc_timezone_map_get_location (CC_TIMEZONE_MAP (self->priv->map));
-      update_timezone (self);
+      g_warning ("Timezone '%s' is unhandled, setting %s as default", timezone, DEFAULT_TZ);
+      cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->priv->map), DEFAULT_TZ);
     }
-
-  /* now that the initial state is loaded set connect the signals */
-  widget = (GtkWidget*) gtk_builder_get_object (self->priv->builder,
-                                                "region_combobox");
-  g_signal_connect (widget, "changed", G_CALLBACK (region_changed_cb), self);
-
-  widget = (GtkWidget*) gtk_builder_get_object (self->priv->builder,
-                                                "city_combobox");
-  g_signal_connect (widget, "changed", G_CALLBACK (city_changed_cb), self);
-
-  g_signal_connect (self->priv->map, "location-changed",
-                    G_CALLBACK (location_changed_cb), self);
-
-
-  g_free (timezone);
+  self->priv->current_location = cc_timezone_map_get_location (CC_TIMEZONE_MAP (self->priv->map));
+  update_timezone (self);
 }
 
 /* load region and city tree models */
@@ -719,9 +695,13 @@ update_widget_state_for_ntp (CcDateTimePanel *panel,
                              gboolean         using_ntp)
 {
   CcDateTimePanelPrivate *priv = panel->priv;
+  gboolean allowed;
+
+  /* need to check polkit before revealing to user */
+  allowed = (! priv->permission || g_permission_get_allowed (priv->permission));
 
-  gtk_widget_set_sensitive (W("table1"), !using_ntp);
-  gtk_widget_set_sensitive (W("table2"), !using_ntp);
+  gtk_widget_set_sensitive (W("table1"), !using_ntp && allowed);
+  gtk_widget_set_sensitive (W("table2"), !using_ntp && allowed);
 }
 
 static void
@@ -830,7 +810,82 @@ on_permission_changed (GPermission *permission,
   gtk_widget_set_sensitive (W("map-vbox"), allowed);
   gtk_widget_set_sensitive (W("hbox2"), allowed);
   gtk_widget_set_sensitive (W("alignment2"), allowed);
-  gtk_widget_set_sensitive (W("table1"), allowed && !using_ntp);
+  update_widget_state_for_ntp (data, using_ntp);
+}
+
+static void
+update_ntp_switch_from_system (CcDateTimePanel *self)
+{
+  CcDateTimePanelPrivate *priv = self->priv;
+  gboolean using_ntp;
+  GtkWidget *switch_widget;
+
+  using_ntp = timedate1_get_ntp (self->priv->dtm);
+
+  switch_widget = W("network_time_switch");
+  g_signal_handlers_block_by_func (switch_widget, change_ntp, self);
+  gtk_switch_set_active (GTK_SWITCH (switch_widget), using_ntp);
+  update_widget_state_for_ntp (self, using_ntp);
+  g_signal_handlers_unblock_by_func (switch_widget, change_ntp, self);
+}
+
+static void
+on_ntp_changed (CcDateTimePanel *self)
+{
+  update_ntp_switch_from_system (self);
+}
+
+static void
+on_timezone_changed (CcDateTimePanel *self)
+{
+  CcDateTimePanelPrivate *priv = self->priv;
+  GtkWidget *region_combo, *city_combo;
+
+  region_combo = W("region_combobox");
+  city_combo = W("city_combobox");
+
+  g_signal_handlers_block_by_func (region_combo, region_changed_cb, self);
+  g_signal_handlers_block_by_func (city_combo, city_changed_cb, self);
+  g_signal_handlers_block_by_func (self->priv->map, location_changed_cb, self);
+
+  get_initial_timezone (self);
+
+  g_signal_handlers_unblock_by_func (region_combo, region_changed_cb, self);
+  g_signal_handlers_unblock_by_func (city_combo, city_changed_cb, self);
+  g_signal_handlers_unblock_by_func (self->priv->map, location_changed_cb, self);
+}
+
+static void
+on_timedated_properties_changed (GDBusProxy       *proxy,
+                                 GVariant         *changed_properties,
+                                 const gchar     **invalidated_properties,
+                                 CcDateTimePanel  *self)
+{
+  GError *error;
+  GVariant *variant;
+  GVariant *v;
+  guint i;
+
+  if (invalidated_properties != NULL)
+    for (i = 0; invalidated_properties[i] != NULL; i++) {
+        error = NULL;
+        /* See https://bugs.freedesktop.org/show_bug.cgi?id=37632 for the reason why we're doing this */
+        variant = g_dbus_proxy_call_sync (proxy,
+                                          "org.freedesktop.DBus.Properties.Get",
+                                          g_variant_new ("(ss)", "org.freedesktop.timedate1", invalidated_properties[i]),
+                                          G_DBUS_CALL_FLAGS_NONE,
+                                          -1,
+                                          NULL,
+                                          &error);
+        if (variant == NULL) {
+                g_warning ("Failed to get property '%s': %s", invalidated_properties[i], error->message);
+                g_error_free (error);
+        } else {
+                g_variant_get (variant, "(v)", &v);
+                g_dbus_proxy_set_cached_property (proxy, invalidated_properties[i], v);
+                g_variant_unref (variant);
+        }
+    }
 }
 
 static void
@@ -881,8 +936,6 @@ cc_date_time_panel_init (CcDateTimePanel *self)
   GtkTreeModelFilter *city_modelfilter;
   GtkTreeModelSort *city_modelsort;
   guint i, num_days;
-  gboolean using_ntp;
-  gboolean can_use_ntp;
   int ret;
   DateEndianess endianess;
   GError *error;
@@ -891,12 +944,12 @@ cc_date_time_panel_init (CcDateTimePanel *self)
 
   priv->cancellable = g_cancellable_new ();
   error = NULL;
-  priv->dtm = date_time_mechanism_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
-                                                          G_DBUS_PROXY_FLAGS_NONE,
-                                                          "org.gnome.SettingsDaemon.DateTimeMechanism",
-                                                          "/",
-                                                          priv->cancellable,
-                                                          &error);
+  priv->dtm = timedate1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                                G_DBUS_PROXY_FLAGS_NONE,
+                                                "org.freedesktop.timedate1",
+                                                "/org/freedesktop/timedate1",
+                                                priv->cancellable,
+                                                &error);
   if (priv->dtm == NULL) {
         g_warning ("could not get proxy for DateTimeMechanism: %s", error->message);
         g_error_free (error);
@@ -916,20 +969,7 @@ cc_date_time_panel_init (CcDateTimePanel *self)
     }
 
   /* set up network time button */
-  error = NULL;
-  using_ntp = can_use_ntp = FALSE;
-  if (!date_time_mechanism_call_get_using_ntp_sync (priv->dtm,
-                                                    &can_use_ntp,
-                                                    &using_ntp,
-                                                    priv->cancellable,
-                                                    &error))
-    {
-      g_warning ("Failed to get using ntp: %s", error->message);
-      g_error_free (error);
-    }
-
-  gtk_switch_set_active (GTK_SWITCH (W("network_time_switch")), using_ntp);
-  update_widget_state_for_ntp (self, using_ntp);
+  update_ntp_switch_from_system (self);
   g_signal_connect (W("network_time_switch"), "notify::active",
                     G_CALLBACK (change_ntp), self);
 
@@ -1020,17 +1060,34 @@ cc_date_time_panel_init (CcDateTimePanel *self)
 
   /* After the initial setup, so we can be sure that
    * the model is filled up */
-  date_time_mechanism_call_get_timezone (priv->dtm,
-                                         priv->cancellable,
-                                         get_timezone_cb,
-                                         self);
+  get_initial_timezone (self);
+
+  widget = (GtkWidget*) gtk_builder_get_object (self->priv->builder,
+                                                "region_combobox");
+  g_signal_connect (widget, "changed", G_CALLBACK (region_changed_cb), self);
+
+  widget = (GtkWidget*) gtk_builder_get_object (self->priv->builder,
+                                                "city_combobox");
+  g_signal_connect (widget, "changed", G_CALLBACK (city_changed_cb), self);
+
+  g_signal_connect (self->priv->map, "location-changed",
+                    G_CALLBACK (location_changed_cb), self);
+
+  /* Watch changes of timedated remote service properties */
+  g_signal_connect (priv->dtm, "g-properties-changed",
+                    G_CALLBACK (on_timedated_properties_changed), self);
+  g_signal_connect_swapped (priv->dtm, "notify::ntp",
+                            G_CALLBACK (on_ntp_changed), self);
+  g_signal_connect_swapped (priv->dtm, "notify::timezone",
+                            G_CALLBACK (on_timezone_changed), self);
+  /* We ignore UTC <--> LocalRTC changes at the moment */
 
   /* add the lock button */
-  priv->permission = polkit_permission_new_sync ("org.gnome.settingsdaemon.datetimemechanism.configure", NULL, NULL, NULL);
+  priv->permission = polkit_permission_new_sync ("org.gnome.controlcenter.datetime.configure", NULL, NULL, NULL);
   if (priv->permission == NULL)
     {
       g_warning ("Your system does not have the '%s' PolicyKit files installed. Please check your installation",
-                 "org.gnome.settingsdaemon.datetimemechanism.configure");
+                 "org.gnome.controlcenter.datetime.configure");
       return;
     }
 
diff --git a/panels/datetime/org.gnome.controlcenter.datetime.policy.in b/panels/datetime/org.gnome.controlcenter.datetime.policy.in
new file mode 100644
index 0000000..5ac5be5
--- /dev/null
+++ b/panels/datetime/org.gnome.controlcenter.datetime.policy.in
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd";>
+
+<policyconfig>
+  <vendor>The GNOME Project</vendor>
+  <vendor_url>http://www.gnome.org/</vendor_url>
+
+  <action id="org.gnome.controlcenter.datetime.configure">
+    <_description>Change system time and date settings</_description>
+    <_message>To change time or date settings, you need to authenticate.</_message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep</allow_active>
+    </defaults>
+    <annotate key="org.freedesktop.policykit.imply">org.freedesktop.timedate1.set-time org.freedesktop.timedate1.set-timezone org.freedesktop.timedate1.set-local-rtc org.freedesktop.timedate1.set-ntp</annotate>
+  </action>
+
+</policyconfig>
diff --git a/panels/datetime/timedated1-interface.xml b/panels/datetime/timedated1-interface.xml
new file mode 100644
index 0000000..b035d10
--- /dev/null
+++ b/panels/datetime/timedated1-interface.xml
@@ -0,0 +1,27 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node>
+ <interface name="org.freedesktop.timedate1">
+  <property name="Timezone" type="s" access="read"/>
+  <property name="LocalRTC" type="b" access="read"/>
+  <property name="NTP" type="b" access="read"/>
+  <method name="SetTime">
+   <arg name="usec_utc" type="x" direction="in"/>
+   <arg name="relative" type="b" direction="in"/>
+   <arg name="user_interaction" type="b" direction="in"/>
+  </method>
+  <method name="SetTimezone">
+   <arg name="timezone" type="s" direction="in"/>
+   <arg name="user_interaction" type="b" direction="in"/>
+  </method>
+  <method name="SetLocalRTC">
+   <arg name="local_rtc" type="b" direction="in"/>
+   <arg name="fix_system" type="b" direction="in"/>
+   <arg name="user_interaction" type="b" direction="in"/>
+  </method>
+  <method name="SetNTP">
+   <arg name="use_ntp" type="b" direction="in"/>
+   <arg name="user_interaction" type="b" direction="in"/>
+  </method>
+ </interface>
+</node>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 52768d0..d3faa66 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -18,6 +18,7 @@ panels/common/gdm-languages.c
 [type: gettext/glade]panels/common/language-chooser.ui
 [type: gettext/glade]panels/datetime/datetime.ui
 panels/datetime/gnome-datetime-panel.desktop.in.in
+panels/datetime/org.gnome.controlcenter.datetime.policy.in
 panels/display/cc-display-panel.c
 [type: gettext/glade]panels/display/display-capplet.ui
 panels/display/gnome-display-panel.desktop.in.in



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]