2 * empathy-geoclue-helper.c
4 * Copyright (C) 2013 Collabora Ltd. <http://www.collabora.co.uk/>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "empathy-geoclue-helper.h"
27 #define DEBUG_FLAG EMPATHY_DEBUG_LOCATION
28 #include "empathy-debug.h"
30 #define GEOCLUE_BUS_NAME "org.freedesktop.GeoClue2"
33 * SECTION: empathy-geoclue-helper
34 * @title: EmpathyGeoclueHelper
35 * @short_description: TODO
41 * EmpathyGeoclueHelper:
43 * Data structure representing a #EmpathyGeoclueHelper.
49 * EmpathyGeoclueHelperClass:
51 * The class of a #EmpathyGeoclueHelper.
56 static void async_initable_iface_init (GAsyncInitableIface
*iface
);
58 G_DEFINE_TYPE_WITH_CODE (EmpathyGeoclueHelper
, empathy_geoclue_helper
,
60 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE
, async_initable_iface_init
));
64 PROP_DISTANCE_THRESHOLD
= 1,
75 static guint signals
[LAST_SIGNAL
];
77 struct _EmpathyGeoclueHelperPriv
79 guint distance_threshold
;
80 GClueLocation
*location
;
87 empathy_geoclue_helper_get_property (GObject
*object
,
92 EmpathyGeoclueHelper
*self
= EMPATHY_GEOCLUE_HELPER (object
);
96 case PROP_DISTANCE_THRESHOLD
:
97 g_value_set_uint (value
, self
->priv
->distance_threshold
);
100 g_value_set_object (value
, self
->priv
->location
);
103 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
109 empathy_geoclue_helper_set_property (GObject
*object
,
114 EmpathyGeoclueHelper
*self
= EMPATHY_GEOCLUE_HELPER (object
);
118 case PROP_DISTANCE_THRESHOLD
:
119 self
->priv
->distance_threshold
= g_value_get_uint (value
);
122 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
128 empathy_geoclue_helper_constructed (GObject
*object
)
130 //EmpathyGeoclueHelper *self = EMPATHY_GEOCLUE_HELPER (object);
131 void (*chain_up
) (GObject
*) =
132 ((GObjectClass
*) empathy_geoclue_helper_parent_class
)->constructed
;
138 empathy_geoclue_helper_dispose (GObject
*object
)
140 EmpathyGeoclueHelper
*self
= EMPATHY_GEOCLUE_HELPER (object
);
141 void (*chain_up
) (GObject
*) =
142 ((GObjectClass
*) empathy_geoclue_helper_parent_class
)->dispose
;
144 if (self
->priv
->started
)
146 gclue_client_call_stop (self
->priv
->client
, NULL
, NULL
, NULL
);
148 self
->priv
->started
= FALSE
;
151 g_clear_object (&self
->priv
->location
);
152 g_clear_object (&self
->priv
->client
);
158 empathy_geoclue_helper_finalize (GObject
*object
)
160 //EmpathyGeoclueHelper *self = EMPATHY_GEOCLUE_HELPER (object);
161 void (*chain_up
) (GObject
*) =
162 ((GObjectClass
*) empathy_geoclue_helper_parent_class
)->finalize
;
168 empathy_geoclue_helper_class_init (
169 EmpathyGeoclueHelperClass
*klass
)
171 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
174 oclass
->get_property
= empathy_geoclue_helper_get_property
;
175 oclass
->set_property
= empathy_geoclue_helper_set_property
;
176 oclass
->constructed
= empathy_geoclue_helper_constructed
;
177 oclass
->dispose
= empathy_geoclue_helper_dispose
;
178 oclass
->finalize
= empathy_geoclue_helper_finalize
;
181 * EmpathyGeoclueHelper:distance-threshold:
187 spec
= g_param_spec_uint ("distance-threshold", "distance-threshold",
190 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
| G_PARAM_STATIC_STRINGS
);
191 g_object_class_install_property (oclass
, PROP_DISTANCE_THRESHOLD
, spec
);
194 * EmpathyGeoclueHelper:location:
200 spec
= g_param_spec_object ("location", "location", "GClueLocation",
202 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
203 g_object_class_install_property (oclass
, PROP_LOCATION
, spec
);
206 * EmpathyGeoclueHelper::location-changed:
207 * @self: a #EmpathyGeoclueHelper
213 signals
[SIG_LOCATION_CHANGED
] = g_signal_new ("location-changed",
214 G_OBJECT_CLASS_TYPE (klass
),
218 1, GCLUE_TYPE_LOCATION
);
220 g_type_class_add_private (klass
, sizeof (EmpathyGeoclueHelperPriv
));
224 empathy_geoclue_helper_init (EmpathyGeoclueHelper
*self
)
226 self
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (self
,
227 EMPATHY_TYPE_GEOCLUE_HELPER
, EmpathyGeoclueHelperPriv
);
231 location_cb (GObject
*source
,
232 GAsyncResult
*result
,
235 EmpathyGeoclueHelper
*self
= user_data
;
236 GError
*error
= NULL
;
238 g_clear_object (&self
->priv
->location
);
240 self
->priv
->location
= gclue_location_proxy_new_finish (result
, &error
);
241 if (self
->priv
->location
== NULL
)
243 DEBUG ("Failed to create Location proxy: %s", error
->message
);
244 g_error_free (error
);
247 g_signal_emit (self
, signals
[SIG_LOCATION_CHANGED
], 0, self
->priv
->location
);
249 g_object_notify (G_OBJECT (self
), "location");
253 location_updated_cb (GClueClient
*client
,
256 EmpathyGeoclueHelper
*self
)
258 gclue_location_proxy_new_for_bus (G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
,
259 GEOCLUE_BUS_NAME
, new,
260 NULL
, location_cb
, self
);
264 client_start_cb (GObject
*source
,
265 GAsyncResult
*result
,
268 GTask
*task
= user_data
;
269 EmpathyGeoclueHelper
*self
= g_task_get_source_object (task
);
270 GClueClient
*client
= GCLUE_CLIENT (source
);
271 GError
*error
= NULL
;
273 if (!gclue_client_call_start_finish (client
, result
, &error
))
275 DEBUG ("Failed to start Geoclue client: %s", error
->message
);
276 g_error_free (error
);
280 self
->priv
->started
= TRUE
;
282 g_task_return_boolean (task
, TRUE
);
283 g_object_unref (task
);
287 client_cb (GObject
*source
,
288 GAsyncResult
*result
,
291 GTask
*task
= user_data
;
292 EmpathyGeoclueHelper
*self
= g_task_get_source_object (task
);
293 GError
*error
= NULL
;
295 self
->priv
->client
= gclue_client_proxy_new_finish (result
, &error
);
296 if (!gclue_client_proxy_new_for_bus_finish (result
, &error
))
298 DEBUG ("Failed to create Geoclue client: %s", error
->message
);
299 g_task_return_error (task
, error
);
303 g_signal_connect_object (self
->priv
->client
, "location-updated",
304 G_CALLBACK (location_updated_cb
), self
, 0);
306 g_object_set (self
->priv
->client
,
307 "distance-threshold", self
->priv
->distance_threshold
,
310 g_task_return_boolean (task
, TRUE
);
313 g_object_unref (task
);
317 get_client_cb (GObject
*source
,
318 GAsyncResult
*result
,
321 GTask
*task
= user_data
;
322 GError
*error
= NULL
;
325 if (!gclue_manager_call_get_client_finish (GCLUE_MANAGER (source
), &path
,
328 DEBUG ("GetClient failed: %s", error
->message
);
329 g_task_return_error (task
, error
);
330 g_object_unref (task
);
334 gclue_client_proxy_new_for_bus (G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
,
335 GEOCLUE_BUS_NAME
, path
, NULL
, client_cb
, task
);
341 manager_cb (GObject
*source
,
342 GAsyncResult
*result
,
345 GTask
*task
= user_data
;
346 GError
*error
= NULL
;
349 mgr
= gclue_manager_proxy_new_for_bus_finish (result
, &error
);
352 DEBUG ("Failed to create Geoclue manager: %s", error
->message
);
353 g_task_return_error (task
, error
);
354 g_object_unref (task
);
358 gclue_manager_call_get_client (mgr
, NULL
, get_client_cb
, task
);
359 g_object_unref (mgr
);
363 empathy_geoclue_helper_start_async (EmpathyGeoclueHelper
*self
,
364 GAsyncReadyCallback callback
,
369 task
= g_task_new (self
, NULL
, callback
, user_data
);
371 if (self
->priv
->started
)
373 g_task_return_boolean (task
, TRUE
);
374 g_object_unref (task
);
378 gclue_client_call_start (self
->priv
->client
, NULL
, client_start_cb
, task
);
382 empathy_geoclue_helper_start_finish (EmpathyGeoclueHelper
*self
,
383 GAsyncResult
*result
,
386 g_return_val_if_fail (g_task_is_valid (result
, self
), FALSE
);
388 return g_task_propagate_boolean (G_TASK (result
), error
);
392 empathy_geoclue_helper_get_location (EmpathyGeoclueHelper
*self
)
394 return self
->priv
->location
;
398 empathy_geoclue_helper_init_async (GAsyncInitable
*initable
,
400 GCancellable
*cancellable
,
401 GAsyncReadyCallback callback
,
406 task
= g_task_new (initable
, cancellable
, callback
, user_data
);
408 gclue_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
,
409 GEOCLUE_BUS_NAME
, "/org/freedesktop/GeoClue2/Manager",
410 NULL
, manager_cb
, task
);
414 empathy_geoclue_helper_init_finish (GAsyncInitable
*initable
,
415 GAsyncResult
*result
,
418 g_return_val_if_fail (g_task_is_valid (result
, initable
), FALSE
);
420 return g_task_propagate_boolean (G_TASK (result
), error
);
424 async_initable_iface_init (GAsyncInitableIface
*iface
)
426 iface
->init_async
= empathy_geoclue_helper_init_async
;
427 iface
->init_finish
= empathy_geoclue_helper_init_finish
;
431 empathy_geoclue_helper_new_async (guint distance_threshold
,
432 GAsyncReadyCallback callback
,
435 g_async_initable_new_async (EMPATHY_TYPE_GEOCLUE_HELPER
,
436 G_PRIORITY_DEFAULT
, NULL
, callback
, user_data
,
437 "distance-threshold", distance_threshold
,
441 EmpathyGeoclueHelper
*
442 empathy_geoclue_helper_new_finish (GAsyncResult
*result
,
445 GObject
*object
, *source_object
;
447 source_object
= g_async_result_get_source_object (result
);
449 object
= g_async_initable_new_finish (G_ASYNC_INITABLE (source_object
),
451 g_object_unref (source_object
);
454 return EMPATHY_GEOCLUE_HELPER (object
);
460 new_started_cb (GObject
*source
,
461 GAsyncResult
*result
,
464 EmpathyGeoclueHelper
*self
= EMPATHY_GEOCLUE_HELPER (source
);
465 GTask
*new_started_task
= user_data
;
466 GError
*error
= NULL
;
468 if (!empathy_geoclue_helper_start_finish (self
, result
, &error
))
470 g_task_return_error (new_started_task
, error
);
471 g_object_unref (self
);
475 /* pass ownership of self to g_task_return_error */
476 g_task_return_pointer (new_started_task
, self
, g_object_unref
);
479 g_object_unref (new_started_task
);
483 new_started_init_cb (GObject
*source
,
484 GAsyncResult
*result
,
487 GTask
*new_started_task
= user_data
;
488 EmpathyGeoclueHelper
*self
;
489 GError
*error
= NULL
;
491 self
= empathy_geoclue_helper_new_finish (result
, &error
);
494 g_task_return_error (new_started_task
, error
);
495 g_object_unref (new_started_task
);
499 /* Pass owernship of 'self' to new_started_cb */
500 empathy_geoclue_helper_start_async (self
, new_started_cb
, new_started_task
);
504 empathy_geoclue_helper_new_started_async (guint distance_threshold
,
505 GAsyncReadyCallback callback
,
508 GTask
*new_started_task
;
510 new_started_task
= g_task_new (NULL
, NULL
, callback
, user_data
);
512 empathy_geoclue_helper_new_async (distance_threshold
, new_started_init_cb
,
516 EmpathyGeoclueHelper
*
517 empathy_geoclue_helper_new_started_finish (GAsyncResult
*result
,
520 g_return_val_if_fail (g_task_is_valid (result
, NULL
), NULL
);
522 return g_task_propagate_pointer (G_TASK (result
), error
);