diff options
-rw-r--r-- | demo/where-am-i.c | 4 | ||||
-rw-r--r-- | src/gclue-locator.c | 52 | ||||
-rw-r--r-- | src/gclue-min-uint.c | 128 | ||||
-rw-r--r-- | src/gclue-min-uint.h | 8 | ||||
-rw-r--r-- | src/gclue-modem-gps.c | 19 | ||||
-rw-r--r-- | src/gclue-modem-manager.c | 27 | ||||
-rw-r--r-- | src/gclue-service-client.c | 1 |
7 files changed, 130 insertions, 109 deletions
diff --git a/demo/where-am-i.c b/demo/where-am-i.c index 6cc65e1..3e5de21 100644 --- a/demo/where-am-i.c +++ b/demo/where-am-i.c @@ -155,7 +155,9 @@ on_simple_ready (GObject *source_object, g_object_ref (client); g_print ("Client object: %s\n", g_dbus_proxy_get_object_path (G_DBUS_PROXY (client))); - gclue_client_set_time_threshold (client, time_threshold); + if (time_threshold > 0) { + gclue_client_set_time_threshold (client, time_threshold); + } print_location (simple); diff --git a/src/gclue-locator.c b/src/gclue-locator.c index 5a413ae..3318225 100644 --- a/src/gclue-locator.c +++ b/src/gclue-locator.c @@ -228,30 +228,31 @@ on_avail_accuracy_level_changed (GObject *gobject, } static void -reset_time_threshold (GClueLocationSource *source, - guint cur_value, - guint new_value) +reset_time_threshold (GClueLocator *locator, + GClueLocationSource *source, + guint value) { GClueMinUINT *threshold; threshold = gclue_location_source_get_time_threshold (source); - gclue_min_uint_exchage_value (threshold, cur_value, new_value); + gclue_min_uint_add_value (threshold, value, G_OBJECT (locator)); } static void -on_time_threshold_changed(GObject *gobject, - GParamSpec *pspec, - gpointer user_data) +on_time_threshold_changed (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) { GClueMinUINT *threshold = GCLUE_MIN_UINT (gobject); GClueLocator *locator = GCLUE_LOCATOR (user_data); guint value = gclue_min_uint_get_value (threshold); GList *node; + g_debug ("Locator: on_time_threshold_changed"); for (node = locator->priv->sources; node != NULL; node = node->next) { - reset_time_threshold (GCLUE_LOCATION_SOURCE (node->data), - locator->priv->time_threshold, + reset_time_threshold (locator, + GCLUE_LOCATION_SOURCE (node->data), value); } } @@ -298,16 +299,18 @@ gclue_locator_finalize (GObject *gsource) GClueLocator *locator = GCLUE_LOCATOR (gsource); GClueLocatorPrivate *priv = locator->priv; GList *node; + GClueMinUINT *threshold; G_OBJECT_CLASS (gclue_locator_parent_class)->finalize (gsource); - for (node = locator->priv->sources; node != NULL; node = node->next) { - GClueMinUINT *threshold; - - threshold = gclue_location_source_get_time_threshold - (GCLUE_LOCATION_SOURCE (node->data)); - gclue_min_uint_drop_value (threshold, priv->time_threshold); + threshold = gclue_location_source_get_time_threshold + (GCLUE_LOCATION_SOURCE (locator)); + g_signal_handlers_disconnect_by_func + (G_OBJECT (threshold), + G_CALLBACK (on_time_threshold_changed), + locator); + for (node = locator->priv->sources; node != NULL; node = node->next) { g_signal_handlers_disconnect_by_func (G_OBJECT (node->data), G_CALLBACK (on_avail_accuracy_level_changed), @@ -522,9 +525,14 @@ gclue_locator_get_accuracy_level (GClueLocator *locator) guint gclue_locator_get_time_threshold (GClueLocator *locator) { + GClueMinUINT *threshold; + g_return_val_if_fail (GCLUE_IS_LOCATOR (locator), 0); - return locator->priv->time_threshold; + threshold = gclue_location_source_get_time_threshold + (GCLUE_LOCATION_SOURCE (locator)); + + return gclue_min_uint_get_value (threshold); } /** @@ -545,15 +553,7 @@ gclue_locator_set_time_threshold (GClueLocator *locator, { g_return_if_fail (GCLUE_IS_LOCATOR (locator)); - if (locator->priv->time_threshold == value) { - return; - } - - reset_time_threshold (GCLUE_LOCATION_SOURCE (locator), - locator->priv->time_threshold, + reset_time_threshold (locator, + GCLUE_LOCATION_SOURCE (locator), value); - locator->priv->time_threshold = value; - g_debug ("%s: New time-threshold: %u", - G_OBJECT_TYPE_NAME (locator), - value); } diff --git a/src/gclue-min-uint.c b/src/gclue-min-uint.c index 1f421aa..e3a28d5 100644 --- a/src/gclue-min-uint.c +++ b/src/gclue-min-uint.c @@ -51,6 +51,34 @@ enum static GParamSpec *gParamSpecs[LAST_PROP]; +typedef struct +{ + GClueMinUINT *muint; + GObject *owner; +} OwnerData; + +static gboolean +on_owner_weak_ref_notify_defered (OwnerData *data) +{ + gclue_min_uint_drop_value (data->muint, data->owner); + g_object_unref (data->muint); + g_slice_free (OwnerData, data); + + return FALSE; +} + +static void +on_owner_weak_ref_notify (gpointer data, GObject *object) +{ + OwnerData *owner_data = g_slice_new (OwnerData); + owner_data->muint = GCLUE_MIN_UINT (data); + g_object_ref (owner_data->muint); + owner_data->owner = object; + + // Let's ensure owner is really gone before we drop its value + g_idle_add ((GSourceFunc) on_owner_weak_ref_notify_defered, owner_data); +} + static void gclue_min_uint_finalize (GObject *object) { @@ -134,17 +162,17 @@ guint gclue_min_uint_get_value (GClueMinUINT *muint) { guint value; - GList *keys, *l; + GList *values, *l; g_return_val_if_fail (GCLUE_IS_MIN_UINT(muint), 0); if (g_hash_table_size (muint->priv->all_values) == 0) return 0; - keys = g_hash_table_get_keys (muint->priv->all_values); - value = GPOINTER_TO_UINT (keys->data); + values = g_hash_table_get_values (muint->priv->all_values); + value = GPOINTER_TO_UINT (values->data); - for (l = keys->next; l; l = l->next) { + for (l = values->next; l; l = l->next) { guint i = GPOINTER_TO_UINT (l->data); if (value > i) { @@ -159,93 +187,61 @@ gclue_min_uint_get_value (GClueMinUINT *muint) * gclue_min_uint_add_value * @muint: a #GClueMinUINT * @value: A value to add to the list + * @owner: the object adding this value + * + * If @owner has already added a value previously, this call will simply replace + * that. i-e Each object can only add one value at a time. **/ void gclue_min_uint_add_value (GClueMinUINT *muint, - guint value) + guint value, + GObject *owner) { - gpointer key, hash_value; - guint cur_value, new_value; - guint num_users = 1; + guint new_value; g_return_if_fail (GCLUE_IS_MIN_UINT(muint)); - key = GUINT_TO_POINTER (value); - hash_value = g_hash_table_lookup (muint->priv->all_values, key); - if (hash_value != NULL) { - num_users = GPOINTER_TO_UINT (hash_value) + 1; - } - - cur_value = gclue_min_uint_get_value (muint); g_hash_table_replace (muint->priv->all_values, - key, - GUINT_TO_POINTER (num_users)); + owner, + GUINT_TO_POINTER (value)); + g_object_weak_ref (owner, on_owner_weak_ref_notify, muint); new_value = gclue_min_uint_get_value (muint); + g_debug ("%s: Added %u for %s. New minimum value: %u", + G_OBJECT_TYPE_NAME (muint), + value, + G_OBJECT_TYPE_NAME (owner), + new_value); - if (cur_value != new_value && muint->priv->notify_value) { - g_object_notify_by_pspec (G_OBJECT (muint), - gParamSpecs[PROP_VALUE]); - } + g_object_notify_by_pspec (G_OBJECT (muint), gParamSpecs[PROP_VALUE]); } /** * gclue_min_uint_drop_value * @muint: a #GClueMinUINT - * @value: A value to drop from the list + * @owner: the object that adadded a value previously **/ void gclue_min_uint_drop_value (GClueMinUINT *muint, - guint value) + GObject *owner) { - gpointer key, hash_value; - guint cur_value, new_value; - guint num_users; + gpointer hash_value; + guint new_value; g_return_if_fail (GCLUE_IS_MIN_UINT(muint)); - key = GUINT_TO_POINTER (value); - hash_value = g_hash_table_lookup (muint->priv->all_values, key); - if (hash_value == NULL) { + if (!g_hash_table_lookup_extended (muint->priv->all_values, + owner, + NULL, + &hash_value)) { return; } - cur_value = gclue_min_uint_get_value (muint); - num_users = GPOINTER_TO_UINT (hash_value) - 1; - if (num_users == 0) { - g_hash_table_remove (muint->priv->all_values, key); - } else { - g_hash_table_replace (muint->priv->all_values, - key, - GUINT_TO_POINTER (num_users)); - } + g_hash_table_remove (muint->priv->all_values, owner); new_value = gclue_min_uint_get_value (muint); + g_debug ("%s: Dropped %u. New minimum value: %u", + G_OBJECT_TYPE_NAME (muint), + GPOINTER_TO_INT (hash_value), + new_value); - if (cur_value != new_value && muint->priv->notify_value) { - g_object_notify_by_pspec (G_OBJECT (muint), - gParamSpecs[PROP_VALUE]); - } -} - -/** - * gclue_min_uint_exchange_value - * @muint: a #GClueMinUINT - * @to_drop: A value to drop from the list - * @to_add: A value to add to the list - * - * Use this method instead of #gclue_min_uint_drop_value and - * #gclue_min_uint_add_value to ensure #GClueMinUINT:value property is only - * notified once. - **/ -void -gclue_min_uint_exchage_value (GClueMinUINT *muint, - guint to_drop, - guint to_add) -{ - g_return_if_fail (GCLUE_IS_MIN_UINT(muint)); - - muint->priv->notify_value = FALSE; - gclue_min_uint_drop_value (muint, to_drop); - muint->priv->notify_value = TRUE; - - gclue_min_uint_add_value (muint, to_add); + g_object_notify_by_pspec (G_OBJECT (muint), gParamSpecs[PROP_VALUE]); } diff --git a/src/gclue-min-uint.h b/src/gclue-min-uint.h index 041b1a7..d286ec5 100644 --- a/src/gclue-min-uint.h +++ b/src/gclue-min-uint.h @@ -57,12 +57,10 @@ GType gclue_min_uint_get_type (void) G_GNUC_CONST; GClueMinUINT * gclue_min_uint_new (void); guint gclue_min_uint_get_value (GClueMinUINT *muint); void gclue_min_uint_add_value (GClueMinUINT *muint, - guint value); + guint value, + GObject *owner); void gclue_min_uint_drop_value (GClueMinUINT *muint, - guint value); -void gclue_min_uint_exchage_value (GClueMinUINT *muint, - guint to_drop, - guint to_add); + GObject *owner); G_END_DECLS #endif /* GCLUE_MIN_UINT_H */ diff --git a/src/gclue-modem-gps.c b/src/gclue-modem-gps.c index 1a44f22..bd0c473 100644 --- a/src/gclue-modem-gps.c +++ b/src/gclue-modem-gps.c @@ -107,6 +107,18 @@ on_is_gps_available_notify (GObject *gobject, } static void +on_time_threshold_changed (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + GClueModemGPS *source = GCLUE_MODEM_GPS (user_data); + guint threshold; + + threshold = gclue_min_uint_get_value (GCLUE_MIN_UINT (gobject)); + gclue_modem_set_time_threshold (source->priv->modem, threshold); +} + +static void gclue_modem_gps_finalize (GObject *ggps) { GClueModemGPSPrivate *priv = GCLUE_MODEM_GPS (ggps)->priv; @@ -140,6 +152,7 @@ static void gclue_modem_gps_init (GClueModemGPS *source) { GClueModemGPSPrivate *priv; + GClueMinUINT *threshold; source->priv = G_TYPE_INSTANCE_GET_PRIVATE ((source), GCLUE_TYPE_MODEM_GPS, GClueModemGPSPrivate); priv = source->priv; @@ -152,6 +165,12 @@ gclue_modem_gps_init (GClueModemGPS *source) "notify::is-gps-available", G_CALLBACK (on_is_gps_available_notify), source); + threshold = gclue_location_source_get_time_threshold + (GCLUE_LOCATION_SOURCE (source)); + g_signal_connect (threshold, + "notify::value", + G_CALLBACK (on_time_threshold_changed), + source); } static void diff --git a/src/gclue-modem-manager.c b/src/gclue-modem-manager.c index 34e2716..4ae49cf 100644 --- a/src/gclue-modem-manager.c +++ b/src/gclue-modem-manager.c @@ -230,12 +230,12 @@ gclue_modem_manager_class_init (GClueModemManagerClass *klass) gParamSpecs[PROP_IS_GPS_AVAILABLE] = g_object_class_find_property (gmodem_class, "is-gps-available"); - gParamSpecs[PROP_TIME_THRESHOLD] = - g_object_class_find_property (gmodem_class, - "time-threshold"); g_object_class_override_property (gmodem_class, PROP_TIME_THRESHOLD, "time-threshold"); + gParamSpecs[PROP_TIME_THRESHOLD] = + g_object_class_find_property (gmodem_class, + "time-threshold"); signals[FIX_3G] = g_signal_lookup ("fix-3g", GCLUE_TYPE_MODEM); signals[FIX_CDMA] = g_signal_lookup ("fix-cdma", GCLUE_TYPE_MODEM); @@ -320,7 +320,7 @@ on_get_3gpp_ready (GObject *source_object, cell_id = mm_location_3gpp_get_cell_id (location_3gpp); if (is_location_3gpp_same (manager, mcc, mnc, lac, cell_id)) { - g_debug ("New 3GPP location is same as last one"); + //g_debug ("New 3GPP location is same as last one"); return; } g_clear_object (&priv->location_3gpp); @@ -409,13 +409,13 @@ on_get_gps_nmea_ready (GObject *source_object, } if (is_location_gga_same (manager, gga)) { - g_debug ("New GGA trace is same as last one: %s", gga); + //g_debug ("New GGA trace is same as last one: %s", gga); return; } g_clear_object (&priv->location_nmea); priv->location_nmea = location_nmea; - g_debug ("New GPGGA trace: %s", gga); + //g_debug ("New GPGGA trace: %s", gga); g_signal_emit (manager, signals[FIX_GPS], 0, gga); } @@ -641,11 +641,15 @@ on_mm_object_added (GDBusObjectManager *object_manager, manager->priv->modem = mm_modem; manager->priv->modem_location = mm_object_get_modem_location (mm_object); - mm_modem_location_set_gps_refresh_rate (manager->priv->modem_location, - manager->priv->time_threshold, - manager->priv->cancellable, - on_gps_refresh_rate_set, - NULL); + g_debug ("Setting GPS refresh rate to %u on Modem '%s'", + manager->priv->time_threshold, + mm_object_get_path (mm_object)); + mm_modem_location_set_gps_refresh_rate + (manager->priv->modem_location, + manager->priv->time_threshold, + manager->priv->cancellable, + on_gps_refresh_rate_set, + NULL); g_signal_connect (G_OBJECT (manager->priv->modem_location), "notify::location", @@ -762,6 +766,7 @@ gclue_modem_manager_constructed (GObject *object) priv->cancellable, on_bus_get_ready, object); + } static void diff --git a/src/gclue-service-client.c b/src/gclue-service-client.c index 91e1a95..1f442f6 100644 --- a/src/gclue-service-client.c +++ b/src/gclue-service-client.c @@ -258,6 +258,7 @@ start_client (GClueServiceClient *client, GClueAccuracyLevel accuracy_level) gclue_dbus_client_set_active (GCLUE_DBUS_CLIENT (client), TRUE); priv->locator = gclue_locator_new (accuracy_level); + gclue_locator_set_time_threshold (priv->locator, 0); g_signal_connect (priv->locator, "notify::location", G_CALLBACK (on_locator_location_changed), |