99
99
location_manager_dispose (GObject *object)
101
EmpathyLocationManagerPriv *priv = GET_PRIV (object);
101
EmpathyLocationManager *self = (EmpathyLocationManager *) object;
102
102
void (*dispose) (GObject *) =
103
103
G_OBJECT_CLASS (empathy_location_manager_parent_class)->dispose;
105
if (priv->account_manager != NULL)
107
g_object_unref (priv->account_manager);
108
priv->account_manager = NULL;
111
if (priv->gsettings_loc != NULL)
113
g_object_unref (priv->gsettings_loc);
114
priv->gsettings_loc = NULL;
117
if (priv->gc_client != NULL)
119
g_object_unref (priv->gc_client);
120
priv->gc_client = NULL;
123
if (priv->gc_position != NULL)
125
g_object_unref (priv->gc_position);
126
priv->gc_position = NULL;
129
if (priv->gc_address != NULL)
131
g_object_unref (priv->gc_address);
132
priv->gc_address = NULL;
135
if (priv->location != NULL)
137
g_hash_table_unref (priv->location);
138
priv->location = NULL;
105
tp_clear_object (&self->priv->account_manager);
106
tp_clear_object (&self->priv->gsettings_loc);
107
tp_clear_object (&self->priv->gc_client);
108
tp_clear_object (&self->priv->gc_position);
109
tp_clear_object (&self->priv->gc_address);
110
tp_clear_pointer (&self->priv->location, g_hash_table_unref);
141
112
if (dispose != NULL)
142
113
dispose (object);
146
location_manager_get_property (GObject *object,
151
/*EmpathyLocationManagerPriv *priv = GET_PRIV (object); */
156
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
162
location_manager_set_property (GObject *object,
167
/* EmpathyLocationManagerPriv *priv = GET_PRIV (object); */
172
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
178
117
empathy_location_manager_class_init (EmpathyLocationManagerClass *class)
180
119
GObjectClass *object_class;
225
161
DEBUG ("Publishing %s location to connection %p",
226
(g_hash_table_size (priv->location) == 0 ? "empty" : ""),
162
(g_hash_table_size (self->priv->location) == 0 ? "empty" : ""),
229
165
tp_cli_connection_interface_location_call_set_location (conn, -1,
230
priv->location, publish_location_cb, NULL, NULL, G_OBJECT (self));
166
self->priv->location, publish_location_cb, NULL, NULL, G_OBJECT (self));
272
208
publish_to_all_connections (EmpathyLocationManager *self,
273
209
gboolean force_publication)
275
EmpathyLocationManagerPriv *priv = GET_PRIV (self);
276
211
PublishToAllData *data;
278
213
data = g_slice_new0 (PublishToAllData);
279
214
data->self = g_object_ref (self);
280
215
data->force_publication = force_publication;
282
tp_account_manager_prepare_async (priv->account_manager, NULL,
217
tp_account_manager_prepare_async (self->priv->account_manager, NULL,
283
218
publish_to_all_am_prepared_cb, data);
322
256
update_timestamp (EmpathyLocationManager *self)
324
EmpathyLocationManagerPriv *priv= GET_PRIV (self);
329
timestamp = time (NULL);
330
stamp64 = (gint64) timestamp;
331
new_value = tp_g_value_slice_new_int64 (stamp64);
332
g_hash_table_insert (priv->location, g_strdup (EMPATHY_LOCATION_TIMESTAMP),
334
DEBUG ("\t - Timestamp: %" G_GINT64_FORMAT, stamp64);
260
timestamp = empathy_time_get_current ();
261
tp_asv_set_int64 (self->priv->location, EMPATHY_LOCATION_TIMESTAMP,
264
DEBUG ("\t - Timestamp: %" G_GINT64_FORMAT, timestamp);
350
280
DEBUG ("New address (accuracy level %d):", level);
351
281
/* FIXME: Publish accuracy level also considering the position's */
353
g_hash_table_remove (priv->location, EMPATHY_LOCATION_STREET);
354
g_hash_table_remove (priv->location, EMPATHY_LOCATION_AREA);
355
g_hash_table_remove (priv->location, EMPATHY_LOCATION_REGION);
356
g_hash_table_remove (priv->location, EMPATHY_LOCATION_COUNTRY);
357
g_hash_table_remove (priv->location, EMPATHY_LOCATION_COUNTRY_CODE);
358
g_hash_table_remove (priv->location, EMPATHY_LOCATION_POSTAL_CODE);
283
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_STREET);
284
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_AREA);
285
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_REGION);
286
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_COUNTRY);
287
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_COUNTRY_CODE);
288
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_POSTAL_CODE);
360
290
if (g_hash_table_size (details) == 0)
366
296
g_hash_table_iter_init (&iter, details);
367
297
while (g_hash_table_iter_next (&iter, &key, &value))
370
299
/* Discard street information if reduced accuracy is on */
371
if (priv->reduce_accuracy &&
300
if (self->priv->reduce_accuracy &&
372
301
!tp_strdiff (key, EMPATHY_LOCATION_STREET))
375
new_value = tp_g_value_slice_new_string (value);
376
g_hash_table_insert (priv->location, g_strdup (key), new_value);
304
tp_asv_set_string (self->priv->location, key, value);
378
306
DEBUG ("\t - %s: %s", (gchar *) key, (gchar *) value);
381
309
update_timestamp (self);
382
if (priv->timeout_id == 0)
383
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, publish_on_idle, self);
310
if (self->priv->timeout_id == 0)
311
self->priv->timeout_id = g_timeout_add_seconds (TIMEOUT, publish_on_idle,
410
339
double longitude,
412
341
GeoclueAccuracy *accuracy,
415
EmpathyLocationManagerPriv *priv = GET_PRIV (self);
344
EmpathyLocationManager *self = user_data;
416
345
GeoclueAccuracyLevel level;
417
346
gdouble mean, horizontal, vertical;
421
348
geoclue_accuracy_get_details (accuracy, &level, &horizontal, &vertical);
422
349
DEBUG ("New position (accuracy level %d)", level);
426
353
if (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)
429
if (priv->reduce_accuracy)
356
if (self->priv->reduce_accuracy)
430
357
/* Truncate at 1 decimal place */
431
358
longitude = ((int) (longitude * 10)) / 10.0;
433
new_value = tp_g_value_slice_new_double (longitude);
434
g_hash_table_insert (priv->location, g_strdup (EMPATHY_LOCATION_LON),
360
tp_asv_set_double (self->priv->location, EMPATHY_LOCATION_LON, longitude);
436
362
DEBUG ("\t - Longitude: %f", longitude);
440
g_hash_table_remove (priv->location, EMPATHY_LOCATION_LON);
366
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_LON);
443
369
if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE)
445
if (priv->reduce_accuracy)
371
if (self->priv->reduce_accuracy)
446
372
/* Truncate at 1 decimal place */
447
373
latitude = ((int) (latitude * 10)) / 10.0;
449
new_value = tp_g_value_slice_new_double (latitude);
450
g_hash_table_replace (priv->location, g_strdup (EMPATHY_LOCATION_LAT),
375
tp_asv_set_double (self->priv->location, EMPATHY_LOCATION_LAT, latitude);
452
377
DEBUG ("\t - Latitude: %f", latitude);
456
g_hash_table_remove (priv->location, EMPATHY_LOCATION_LAT);
381
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_LAT);
459
384
if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
461
new_value = tp_g_value_slice_new_double (altitude);
462
g_hash_table_replace (priv->location, g_strdup (EMPATHY_LOCATION_ALT),
386
tp_asv_set_double (self->priv->location, EMPATHY_LOCATION_ALT, altitude);
464
388
DEBUG ("\t - Altitude: %f", altitude);
468
g_hash_table_remove (priv->location, EMPATHY_LOCATION_ALT);
392
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_ALT);
471
395
if (level == GEOCLUE_ACCURACY_LEVEL_DETAILED)
473
397
mean = (horizontal + vertical) / 2.0;
474
new_value = tp_g_value_slice_new_double (mean);
475
g_hash_table_replace (priv->location,
476
g_strdup (EMPATHY_LOCATION_ACCURACY), new_value);
398
tp_asv_set_double (self->priv->location, EMPATHY_LOCATION_ACCURACY, mean);
477
400
DEBUG ("\t - Accuracy: %f", mean);
481
g_hash_table_remove (priv->location, EMPATHY_LOCATION_ACCURACY);
404
g_hash_table_remove (self->priv->location, EMPATHY_LOCATION_ACCURACY);
484
407
update_timestamp (self);
485
if (priv->timeout_id == 0)
486
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, publish_on_idle, self);
408
if (self->priv->timeout_id == 0)
409
self->priv->timeout_id = g_timeout_add_seconds (TIMEOUT, publish_on_idle,
513
437
set_requirements (EmpathyLocationManager *self)
515
EmpathyLocationManagerPriv *priv = GET_PRIV (self);
516
439
GError *error = NULL;
518
if (!geoclue_master_client_set_requirements (priv->gc_client,
519
GEOCLUE_ACCURACY_LEVEL_COUNTRY, 0, FALSE, priv->resources,
441
if (!geoclue_master_client_set_requirements (self->priv->gc_client,
442
GEOCLUE_ACCURACY_LEVEL_COUNTRY, 0, FALSE, self->priv->resources,
522
445
DEBUG ("set_requirements failed: %s", error->message);
531
454
update_resources (EmpathyLocationManager *self)
533
EmpathyLocationManagerPriv *priv = GET_PRIV (self);
535
DEBUG ("Updating resources %d", priv->resources);
537
if (!priv->geoclue_is_setup)
456
DEBUG ("Updating resources %d", self->priv->resources);
458
if (!self->priv->geoclue_is_setup)
540
461
/* As per Geoclue bug #15126, using NONE results in no address
543
464
if (!set_requirements (self))
546
geoclue_address_get_address_async (priv->gc_address,
467
geoclue_address_get_address_async (self->priv->gc_address,
547
468
initial_address_cb, self);
548
geoclue_position_get_position_async (priv->gc_position,
469
geoclue_position_get_position_async (self->priv->gc_position,
549
470
initial_position_cb, self);
553
474
setup_geoclue (EmpathyLocationManager *self)
555
EmpathyLocationManagerPriv *priv = GET_PRIV (self);
557
476
GeoclueMaster *master;
558
477
GError *error = NULL;
560
479
DEBUG ("Setting up Geoclue");
561
480
master = geoclue_master_get_default ();
562
priv->gc_client = geoclue_master_create_client (master, NULL, &error);
481
self->priv->gc_client = geoclue_master_create_client (master, NULL, &error);
563
482
g_object_unref (master);
565
if (priv->gc_client == NULL)
484
if (self->priv->gc_client == NULL)
567
486
DEBUG ("Failed to GeoclueMasterClient: %s", error->message);
568
487
g_error_free (error);
575
494
/* Get updated when the position is changes */
576
priv->gc_position = geoclue_master_client_create_position (
577
priv->gc_client, &error);
578
if (priv->gc_position == NULL)
495
self->priv->gc_position = geoclue_master_client_create_position (
496
self->priv->gc_client, &error);
497
if (self->priv->gc_position == NULL)
580
499
DEBUG ("Failed to create GeocluePosition: %s", error->message);
581
500
g_error_free (error);
585
g_signal_connect (G_OBJECT (priv->gc_position), "position-changed",
504
g_signal_connect (G_OBJECT (self->priv->gc_position), "position-changed",
586
505
G_CALLBACK (position_changed_cb), self);
588
507
/* Get updated when the address changes */
589
priv->gc_address = geoclue_master_client_create_address (
590
priv->gc_client, &error);
591
if (priv->gc_address == NULL)
508
self->priv->gc_address = geoclue_master_client_create_address (
509
self->priv->gc_client, &error);
510
if (self->priv->gc_address == NULL)
593
512
DEBUG ("Failed to create GeoclueAddress: %s", error->message);
594
513
g_error_free (error);
598
g_signal_connect (G_OBJECT (priv->gc_address), "address-changed",
517
g_signal_connect (G_OBJECT (self->priv->gc_address), "address-changed",
599
518
G_CALLBACK (address_changed_cb), self);
601
priv->geoclue_is_setup = TRUE;
520
self->priv->geoclue_is_setup = TRUE;
606
525
const gchar *key,
607
526
gpointer user_data)
609
EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
610
EmpathyLocationManagerPriv *priv = GET_PRIV (manager);
528
EmpathyLocationManager *self = EMPATHY_LOCATION_MANAGER (user_data);
612
530
DEBUG ("Publish Conf changed");
614
532
if (g_settings_get_boolean (gsettings_loc, key))
616
if (!priv->geoclue_is_setup)
617
setup_geoclue (manager);
534
if (!self->priv->geoclue_is_setup)
535
setup_geoclue (self);
618
536
/* if still not setup than the init failed */
619
if (!priv->geoclue_is_setup)
537
if (!self->priv->geoclue_is_setup)
622
geoclue_address_get_address_async (priv->gc_address,
623
initial_address_cb, manager);
624
geoclue_position_get_position_async (priv->gc_position,
625
initial_position_cb, manager);
540
geoclue_address_get_address_async (self->priv->gc_address,
541
initial_address_cb, self);
542
geoclue_position_get_position_async (self->priv->gc_position,
543
initial_position_cb, self);
629
547
/* As per XEP-0080: send an empty location to have remove current
630
548
* location from the servers
632
g_hash_table_remove_all (priv->location);
633
publish_to_all_connections (manager, TRUE);
550
g_hash_table_remove_all (self->priv->location);
551
publish_to_all_connections (self, TRUE);
654
571
resource = GEOCLUE_RESOURCE_GPS;
656
573
if (g_settings_get_boolean (gsettings_loc, key))
657
priv->resources |= resource;
574
self->priv->resources |= resource;
659
priv->resources &= ~resource;
576
self->priv->resources &= ~resource;
661
if (priv->geoclue_is_setup)
662
update_resources (manager);
578
if (self->priv->geoclue_is_setup)
579
update_resources (self);
667
584
const gchar *key,
668
585
gpointer user_data)
670
EmpathyLocationManager *manager = EMPATHY_LOCATION_MANAGER (user_data);
671
EmpathyLocationManagerPriv *priv = GET_PRIV (manager);
587
EmpathyLocationManager *self = EMPATHY_LOCATION_MANAGER (user_data);
673
589
DEBUG ("%s changed", key);
675
priv->reduce_accuracy = g_settings_get_boolean (gsettings_loc, key);
591
self->priv->reduce_accuracy = g_settings_get_boolean (gsettings_loc, key);
677
if (!priv->geoclue_is_setup)
593
if (!self->priv->geoclue_is_setup)
680
geoclue_address_get_address_async (priv->gc_address,
681
initial_address_cb, manager);
682
geoclue_position_get_position_async (priv->gc_position,
683
initial_position_cb, manager);
596
geoclue_address_get_address_async (self->priv->gc_address,
597
initial_address_cb, self);
598
geoclue_position_get_position_async (self->priv->gc_position,
599
initial_position_cb, self);
715
631
empathy_location_manager_init (EmpathyLocationManager *self)
717
EmpathyLocationManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
718
EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerPriv);
633
EmpathyLocationManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
634
EMPATHY_TYPE_LOCATION_MANAGER, EmpathyLocationManagerPrivate);
720
636
self->priv = priv;
721
637
priv->geoclue_is_setup = FALSE;
722
priv->location = g_hash_table_new_full (g_direct_hash, g_direct_equal,
723
g_free, (GDestroyNotify) tp_g_value_slice_free);
638
priv->location = tp_asv_new (NULL, NULL);
724
639
priv->gsettings_loc = g_settings_new (EMPATHY_PREFS_LOCATION_SCHEMA);
726
641
/* Setup account status callbacks */