[gnome-initial-setup/wip/timezone: 6/11] timezone: Finish up geoclue integration
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-initial-setup/wip/timezone: 6/11] timezone: Finish up geoclue integration
- Date: Tue, 18 Mar 2014 21:05:50 +0000 (UTC)
commit be71187a5c6eb6aceececf2bc5d00a260ae62a73
Author: Kalev Lember <kalevlember gmail com>
Date: Tue Mar 18 17:31:07 2014 +0100
timezone: Finish up geoclue integration
.gitignore | 1 +
configure.ac | 8 +
gnome-initial-setup/pages/timezone/Makefile.am | 9 +
.../pages/timezone/gis-timezone-page.c | 246 ++++++++++++++------
.../pages/timezone/gis-timezone-page.ui | 1 +
5 files changed, 192 insertions(+), 73 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 2d1a0c5..ccbc106 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@ gnome-initial-setup/pages/keyboard/keyboard-resources.[ch]
gnome-initial-setup/pages/eulas/eulas-resources.[ch]
gnome-initial-setup/pages/network/network-resources.[ch]
gnome-initial-setup/pages/password/password-resources.[ch]
+gnome-initial-setup/pages/timezone/geoclue.[ch]
gnome-initial-setup/pages/timezone/timedated.[ch]
gnome-initial-setup/pages/timezone/cc-datetime-resources.[ch]
gnome-initial-setup/pages/timezone/timezone-resources.[ch]
diff --git a/configure.ac b/configure.ac
index 34f23f6..55733f9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,6 +26,7 @@ IBUS_REQUIRED_VERSION=1.4.99
GNOME_DESKTOP_REQUIRED_VERSION=3.7.5
POLKIT_REQUIRED_VERSION=0.103
GDM_REQUIRED_VERSION=3.8.3
+GEOCLUE_REQUIRED_VERSION=2.1.2
PKG_CHECK_MODULES(INITIAL_SETUP,
NetworkManager >= $NETWORK_MANAGER_REQUIRED_VERSION
@@ -43,12 +44,19 @@ PKG_CHECK_MODULES(INITIAL_SETUP,
gtk+-3.0 >= $GTK_REQUIRED_VERSION
gio-unix-2.0 >= $GLIB_REQUIRED_VERSION
gdm >= $GDM_REQUIRED_VERSION
+ geoclue-2.0 >= $GEOCLUE_REQUIRED_VERSION
pango >= $PANGO_REQUIRED_VERSION
rest-0.7
json-glib-1.0
libsecret-1
pwquality)
+GEOCLUE_DBUS_INTERFACE_XML=`pkg-config --variable=dbus_interface geoclue-2.0`
+if test "x$GEOCLUE_DBUS_INTERFACE_XML" = "x"; then
+ AC_MSG_ERROR([Cannot find dbus_interface variable in geoclue-2.0.pc])
+fi
+AC_SUBST(GEOCLUE_DBUS_INTERFACE_XML)
+
PKG_CHECK_MODULES(CHEESE,
cheese
cheese-gtk >= 3.3.5,
diff --git a/gnome-initial-setup/pages/timezone/Makefile.am b/gnome-initial-setup/pages/timezone/Makefile.am
index 1384cdb..ff6f410 100644
--- a/gnome-initial-setup/pages/timezone/Makefile.am
+++ b/gnome-initial-setup/pages/timezone/Makefile.am
@@ -7,6 +7,15 @@ BUILT_SOURCES =
AM_CPPFLAGS = \
-DGNOMECC_DATA_DIR="\"$(datadir)/gnome-control-center\""
+geoclue.c: geoclue.h
+geoclue.h: Makefile.am $(GEOCLUE_DBUS_INTERFACE_XML)
+ $(AM_V_GEN) gdbus-codegen \
+ --interface-prefix org.freedesktop.GeoClue2 \
+ --generate-c-code geoclue \
+ --c-namespace Geoclue \
+ $(GEOCLUE_DBUS_INTERFACE_XML)
+BUILT_SOURCES += geoclue.c geoclue.h
+
timedated.c: timedated.h
timedated.h: Makefile.am timedated1-interface.xml
$(AM_V_GEN) gdbus-codegen \
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.c
b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
index a5d8cb9..154e345 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.c
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
@@ -35,6 +35,7 @@
#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
#include <libgweather/gweather.h>
+#include "geoclue.h"
#include "timedated.h"
#include "cc-datetime-resources.h"
#include "timezone-resources.h"
@@ -43,6 +44,10 @@
#include "gis-bubble-widget.h"
#define DEFAULT_TZ "Europe/London"
+#define DESKTOP_ID "gnome-datetime-panel"
+
+/* Defines from geoclue private header src/public-api/gclue-enums.h */
+#define GCLUE_ACCURACY_LEVEL_CITY 4
struct _GisTimezonePagePrivate
{
@@ -53,6 +58,9 @@ struct _GisTimezonePagePrivate
GtkWidget *search_entry;
GtkWidget *search_overlay;
+ GCancellable *geoclue_cancellable;
+ GeoclueClient *geoclue_client;
+ GeoclueManager *geoclue_manager;
GWeatherLocation *auto_location;
GWeatherLocation *current_location;
Timedate1 *dtm;
@@ -155,99 +163,181 @@ set_auto_location (GisTimezonePage *page,
gtk_label_set_markup (GTK_LABEL (priv->auto_result), markup);
g_free (tzname);
g_free (markup);
+
+ gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "status");
+ gtk_widget_show (priv->search_button);
}
else
{
priv->auto_location = NULL;
/* We have no automatic location; transition to search automatically */
+ gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "search");
gtk_widget_hide (priv->search_button);
- gtk_widget_hide (priv->auto_result);
}
-
- gtk_widget_show (priv->stack);
}
static void
-get_location_from_geoclue (GisTimezonePage *page)
+on_location_proxy_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GDBusProxy *manager = NULL, *client = NULL, *location = NULL;
- GVariant *value;
- const char *object_path;
- double latitude, longitude;
+ GisTimezonePage *page = user_data;
+ GeoclueLocation *location;
+ gdouble latitude, longitude;
+ GError *error = NULL;
GWeatherLocation *glocation = NULL;
- manager = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.GeoClue2",
- "/org/freedesktop/GeoClue2/Manager",
- "org.freedesktop.GeoClue2.Manager",
- NULL, NULL);
- if (!manager)
- goto out;
-
- value = g_dbus_proxy_call_sync (manager, "GetClient", NULL,
- G_DBUS_CALL_FLAGS_NONE, -1,
- NULL, NULL);
- if (!value)
- goto out;
-
- g_variant_get_child (value, 0, "&o", &object_path);
-
- client = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.GeoClue2",
- object_path,
- "org.freedesktop.GeoClue2.Client",
- NULL, NULL);
- g_variant_unref (value);
-
- if (!client)
- goto out;
-
- value = g_dbus_proxy_get_cached_property (client, "Location");
- object_path = g_variant_get_string (value, NULL);
-
- location = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.GeoClue2",
- object_path,
- "org.freedesktop.GeoClue2.Location",
- NULL, NULL);
- g_variant_unref (value);
-
- if (!location)
- goto out;
-
- value = g_dbus_proxy_get_cached_property (location, "Latitude");
-
- /* this happens under some circumstances, iunno why. needs zeenix */
- if (!value)
- goto out;
+ location = geoclue_location_proxy_new_for_bus_finish (res, &error);
+ if (error != NULL)
+ {
+ g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
+ g_error_free (error);
+ return;
+ }
- latitude = g_variant_get_double (value);
- g_variant_unref (value);
- value = g_dbus_proxy_get_cached_property (location, "Longitude");
- longitude = g_variant_get_double (value);
- g_variant_unref (value);
+ latitude = geoclue_location_get_latitude (location);
+ longitude = geoclue_location_get_longitude (location);
glocation = gweather_location_find_nearest_city (NULL, latitude, longitude);
- out:
set_auto_location (page, glocation);
set_location (page, glocation);
- if (glocation)
- gweather_location_unref (glocation);
- if (manager)
- g_object_unref (manager);
- if (client)
- g_object_unref (client);
- if (location)
- g_object_unref (location);
+ g_object_unref (location);
+ gweather_location_unref (glocation);
+}
+
+static void
+on_location_updated (GDBusProxy *client,
+ gchar *location_path_old,
+ gchar *location_path_new,
+ gpointer user_data)
+{
+ GisTimezonePage *page = user_data;
+ GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+
+ geoclue_location_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.freedesktop.GeoClue2",
+ location_path_new,
+ priv->geoclue_cancellable,
+ on_location_proxy_ready,
+ page);
+}
+
+static void
+on_start_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ if (!geoclue_client_call_start_finish (GEOCLUE_CLIENT (source_object),
+ res,
+ &error))
+ {
+ g_critical ("Failed to start GeoClue2 client: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+}
+
+static void
+on_client_proxy_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GisTimezonePage *page = user_data;
+ GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+ GError *error = NULL;
+
+ priv->geoclue_client = geoclue_client_proxy_new_for_bus_finish (res, &error);
+ if (error != NULL)
+ {
+ g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ geoclue_client_set_desktop_id (priv->geoclue_client, DESKTOP_ID);
+ geoclue_client_set_requested_accuracy_level (priv->geoclue_client,
+ GCLUE_ACCURACY_LEVEL_CITY);
+
+ g_signal_connect (priv->geoclue_client, "location-updated",
+ G_CALLBACK (on_location_updated), page);
+
+ geoclue_client_call_start (priv->geoclue_client,
+ priv->geoclue_cancellable,
+ on_start_ready,
+ page);
+}
+
+static void
+on_get_client_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GisTimezonePage *page = user_data;
+ GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+ gchar *client_path;
+ GError *error = NULL;
+
+ if (!geoclue_manager_call_get_client_finish (GEOCLUE_MANAGER (source_object),
+ &client_path,
+ res,
+ &error))
+ {
+ g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ geoclue_client_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.freedesktop.GeoClue2",
+ client_path,
+ priv->geoclue_cancellable,
+ on_client_proxy_ready,
+ page);
+}
+
+static void
+on_manager_proxy_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+
+ GisTimezonePage *page = user_data;
+ GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+ GError *error = NULL;
+
+ priv->geoclue_manager = geoclue_manager_proxy_new_for_bus_finish (res, &error);
+ if (error != NULL)
+ {
+ g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ geoclue_manager_call_get_client (priv->geoclue_manager,
+ priv->geoclue_cancellable,
+ on_get_client_ready,
+ page);
+}
+
+static void
+get_location_from_geoclue_async (GisTimezonePage *page)
+{
+ GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+
+ geoclue_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.freedesktop.GeoClue2",
+ "/org/freedesktop/GeoClue2/Manager",
+ priv->geoclue_cancellable,
+ on_manager_proxy_ready,
+ page);
}
static void
@@ -314,7 +404,9 @@ gis_timezone_page_constructed (GObject *object)
exit (1);
}
- get_location_from_geoclue (page);
+ set_auto_location (page, NULL);
+ set_location (page, NULL);
+ get_location_from_geoclue_async (page);
g_signal_connect (priv->search_entry, "notify::location",
G_CALLBACK (entry_location_changed), page);
@@ -334,7 +426,15 @@ gis_timezone_page_dispose (GObject *object)
GisTimezonePage *page = GIS_TIMEZONE_PAGE (object);
GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+ if (priv->geoclue_cancellable)
+ {
+ g_cancellable_cancel (priv->geoclue_cancellable);
+ g_clear_object (&priv->geoclue_cancellable);
+ }
+
g_clear_object (&priv->dtm);
+ g_clear_object (&priv->geoclue_client);
+ g_clear_object (&priv->geoclue_manager);
G_OBJECT_CLASS (gis_timezone_page_parent_class)->dispose (object);
}
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
b/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
index 056d37c..6eef211 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
@@ -39,6 +39,7 @@
<property name="spacing">8</property>
<child>
<object class="GtkStack" id="stack">
+ <property name="visible">True</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkLabel" id="auto_result">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]