summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeemu Ikonen <tpikonen@mailbox.org>2021-12-18 15:26:28 +0200
committerTeemu Ikonen <tpikonen@mailbox.org>2022-01-13 12:05:05 +0000
commitdc9c975362cb69507d86b69ee6e76efafa26b37e (patch)
treeaa9349a336cdfb049ce47ed06e1599dc424c76d4
parente5b6c6ec154bcf267f087f43eec0929bc757ea31 (diff)
service-client: Be strict with time and distance thresholds
The 'LocationUpdated' signal should be emitted when a new location either has a timestamp that is newer by 'TimeThreshold' than the previous signaled location, or if the distance of the new location is larger than 'DistanceThreshold' from the previous signaled location. The 'Location' property can be updated even if the location is below the thresholds for signaling it, allowing clients to monitor location updates which are below the signaling thresholds. When a new location arrives, it is compared to the Location property to check if time and distance thresholds are exceeded. However, as Location can be updated without signaling, a client expecting LocationUpdated signals every N seconds may never receive one, if updates are always less than N seconds apart. The same can happen with the distance threshold, if the location moves slowly enough. Remember the signaled location and make time and distance comparisons for new locations against it, so that clients get LocationUpdated signals strictly within the requested time and distance thresholds.
-rw-r--r--src/gclue-service-client.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/src/gclue-service-client.c b/src/gclue-service-client.c
index e276613..0f1193d 100644
--- a/src/gclue-service-client.c
+++ b/src/gclue-service-client.c
@@ -49,6 +49,7 @@ struct _GClueServiceClientPrivate
GClueServiceLocation *location;
GClueServiceLocation *prev_location;
+ GClueLocation *signaled_location;
guint distance_threshold;
guint time_threshold;
@@ -124,19 +125,17 @@ distance_below_threshold (GClueServiceClient *client,
GClueLocation *location)
{
GClueServiceClientPrivate *priv = client->priv;
- GClueLocation *cur_location;
gdouble distance;
gdouble threshold;
if (priv->distance_threshold == 0)
return FALSE;
- g_object_get (priv->location,
- "location", &cur_location,
- NULL);
- distance = gclue_location_get_distance_from (cur_location, location);
- g_object_unref (cur_location);
+ if (!priv->signaled_location)
+ return FALSE;
+ distance = gclue_location_get_distance_from (priv->signaled_location,
+ location);
threshold = priv->distance_threshold;
if (distance < threshold) {
g_debug ("Distance from previous location is %f m and "
@@ -153,22 +152,18 @@ time_below_threshold (GClueServiceClient *client,
GClueLocation *location)
{
GClueServiceClientPrivate *priv = client->priv;
- GClueLocation *cur_location;
- gint64 cur_ts, ts;
+ gint64 cur_ts, new_ts;
guint64 diff_ts;
if (priv->time_threshold == 0)
return FALSE;
- g_object_get (priv->location,
- "location", &cur_location,
- NULL);
-
- cur_ts = gclue_location_get_timestamp (cur_location);
- ts = gclue_location_get_timestamp (location);
- diff_ts = ABS (ts - cur_ts);
+ if (!priv->signaled_location)
+ return FALSE;
- g_object_unref (cur_location);
+ cur_ts = gclue_location_get_timestamp (priv->signaled_location);
+ new_ts = gclue_location_get_timestamp (location);
+ diff_ts = ABS (new_ts - cur_ts);
if (diff_ts < priv->time_threshold) {
g_debug ("Time difference between previous and new location"
@@ -244,8 +239,12 @@ on_locator_location_changed (GObject *gobject,
gclue_dbus_client_set_location (GCLUE_DBUS_CLIENT (client), path);
+ g_clear_object (&priv->signaled_location);
+ priv->signaled_location = g_object_ref (new_location);
+
if (!emit_location_updated (client, prev_path, path, &error))
goto error_out;
+
goto out;
error_out:
@@ -653,6 +652,7 @@ gclue_service_client_finalize (GObject *object)
g_clear_object (&priv->locator);
g_clear_object (&priv->location);
g_clear_object (&priv->prev_location);
+ g_clear_object (&priv->signaled_location);
g_clear_object (&priv->client_info);
/* Chain up to the parent class */