diff options
author | Teemu Ikonen <tpikonen@mailbox.org> | 2021-12-18 15:26:28 +0200 |
---|---|---|
committer | Teemu Ikonen <tpikonen@mailbox.org> | 2022-01-13 12:05:05 +0000 |
commit | dc9c975362cb69507d86b69ee6e76efafa26b37e (patch) | |
tree | aa9349a336cdfb049ce47ed06e1599dc424c76d4 | |
parent | e5b6c6ec154bcf267f087f43eec0929bc757ea31 (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.c | 32 |
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 */ |