diff --git a/src/iio-sensor-proxy.c b/src/iio-sensor-proxy.c index c69913c..2f4a172 100644 --- a/src/iio-sensor-proxy.c +++ b/src/iio-sensor-proxy.c @@ -132,6 +132,23 @@ find_sensors (GUdevClient *client, return found; } +static void +free_client_watch (gpointer data) +{ + guint watch_id = GPOINTER_TO_UINT (data); + + if (watch_id == 0) + return; + g_bus_unwatch_name (watch_id); +} + +static GHashTable * +create_clients_hash_table (void) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, free_client_watch); +} + typedef enum { PROP_HAS_ACCELEROMETER = 1 << 0, PROP_ACCELEROMETER_ORIENTATION = 1 << 1, @@ -233,11 +250,10 @@ any_sensors_left (SensorData *data) return exists; } -static gboolean +static void client_release (SensorData *data, const char *sender, - DriverType driver_type, - GDBusMethodInvocation *invocation) + DriverType driver_type) { GHashTable *ht; guint watch_id; @@ -245,24 +261,13 @@ client_release (SensorData *data, ht = data->clients[driver_type]; watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); - if (watch_id == 0) { - if (invocation) { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "D-Bus client '%s' is not monitoring %s", - sender, driver_type_to_str (driver_type)); - } - return FALSE; - } + if (watch_id == 0) + return; - g_bus_unwatch_name (watch_id); g_hash_table_remove (ht, sender); if (g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), FALSE); - - return TRUE; } static void @@ -288,7 +293,7 @@ client_vanished_cb (GDBusConnection *connection, watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); if (watch_id > 0) - client_release (data, sender, i, NULL); + client_release (data, sender, i); } g_free (sender); @@ -323,15 +328,6 @@ handle_method_call (GDBusConnection *connection, return; } - /* Check if we have a sensor for that type */ - if (!driver_type_exists (data, driver_type)) { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_INVALID_ARGS, - "Driver type '%s' is not present", driver_type_to_str (driver_type)); - return; - } - ht = data->clients[driver_type]; if (g_str_has_prefix (method_name, "Claim")) { @@ -346,7 +342,8 @@ handle_method_call (GDBusConnection *connection, } /* No other clients for this sensor? Start it */ - if (g_hash_table_size (ht) == 0) + if (driver_type_exists (data, driver_type) && + g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), TRUE); watch_id = g_bus_watch_name_on_connection (data->connection, @@ -360,8 +357,8 @@ handle_method_call (GDBusConnection *connection, g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_str_has_prefix (method_name, "Release")) { - if (client_release (data, sender, driver_type, invocation)) - g_dbus_method_invocation_return_value (invocation, NULL); + client_release (data, sender, driver_type); + g_dbus_method_invocation_return_value (invocation, NULL); } } @@ -576,8 +573,13 @@ sensor_changes (GUdevClient *client, g_debug ("Sensor type %s got removed (%s)", driver_type_to_str (i), g_udev_device_get_sysfs_path (dev)); + g_clear_object (&DEVICE_FOR_TYPE(i)); DRIVER_FOR_TYPE(i) = NULL; + + g_clear_pointer (&data->clients[i], g_hash_table_unref); + data->clients[i] = create_clients_hash_table (); + send_driver_changed_dbus_event (data, i); } } @@ -598,9 +600,16 @@ sensor_changes (GUdevClient *client, if (driver_open (driver, device, driver_type_to_callback_func (driver->type), data)) { + GHashTable *ht; + DEVICE_FOR_TYPE(driver->type) = g_object_ref (device); DRIVER_FOR_TYPE(driver->type) = (SensorDriver *) driver; send_driver_changed_dbus_event (data, driver->type); + + ht = data->clients[driver->type]; + + if (g_hash_table_size (ht) > 0) + driver_set_polling (DRIVER_FOR_TYPE(driver->type), TRUE); } break; } @@ -634,10 +643,7 @@ int main (int argc, char **argv) G_CALLBACK (sensor_changes), data); for (i = 0; i < NUM_SENSOR_TYPES; i++) { - data->clients[i] = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); + data->clients[i] = create_clients_hash_table (); if (!driver_type_exists (data, i)) continue; diff --git a/src/monitor-sensor.c b/src/monitor-sensor.c index 1fbdb1e..955c657 100644 --- a/src/monitor-sensor.c +++ b/src/monitor-sensor.c @@ -58,10 +58,6 @@ appeared_cb (GDBusConnection *connection, gpointer user_data) { GError *error = NULL; - gboolean has_accel, has_als; - GVariant *v; - - has_accel = has_als = FALSE; iio_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, @@ -75,38 +71,22 @@ appeared_cb (GDBusConnection *connection, G_CALLBACK (properties_changed), NULL); /* Accelerometer */ - v = g_dbus_proxy_get_cached_property (iio_proxy, "HasAccelerometer"); - if (v) { - has_accel = g_variant_get_boolean (v); - g_variant_unref (v); - } - if (has_accel && !accel_claimed) { - g_dbus_proxy_call_sync (iio_proxy, - "ClaimAccelerometer", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &error); - g_assert_no_error (error); - accel_claimed = TRUE; - } + g_dbus_proxy_call_sync (iio_proxy, + "ClaimAccelerometer", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, &error); + g_assert_no_error (error); /* ALS */ - v = g_dbus_proxy_get_cached_property (iio_proxy, "HasAmbientLight"); - if (v) { - has_als = g_variant_get_boolean (v); - g_variant_unref (v); - } - if (has_als && !als_claimed) { - g_dbus_proxy_call_sync (iio_proxy, - "ClaimLight", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &error); - g_assert_no_error (error); - als_claimed = TRUE; - } + g_dbus_proxy_call_sync (iio_proxy, + "ClaimLight", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, &error); + g_assert_no_error (error); } static void diff --git a/src/net.hadess.SensorProxy.xml b/src/net.hadess.SensorProxy.xml index 5f034f3..34bfa68 100644 --- a/src/net.hadess.SensorProxy.xml +++ b/src/net.hadess.SensorProxy.xml @@ -66,7 +66,9 @@ ClaimAccelerometer: To start receiving accelerometer reading updates from the proxy, the application - must call the net.hadess.SensorProxy.ClaimAccelerometer() method. + must call the net.hadess.SensorProxy.ClaimAccelerometer() method. It can do so + whether an accelerometer is available or not, updates would then be sent when an + accelerometer appears. Applications should call net.hadess.SensorProxy.ReleaseAccelerometer() when readings are not required anymore. For example, an application that monitors @@ -83,7 +85,7 @@ This should be called as soon as readings are not required anymore. Note that resources are freed up if a monitoring application exits without - calling net.hadess.SensorProxy.Release(), or crashes. + calling net.hadess.SensorProxy.Release(), crashes or the sensor disappears. --> @@ -91,7 +93,9 @@ ClaimLight: To start receiving ambient light sensor reading updates from the proxy, the - application must call the net.hadess.SensorProxy.ClaimLight() method. + application must call the net.hadess.SensorProxy.ClaimLight() method. It can do so + whether an ambient light sensor is available or not, updates would then be sent + when such a sensor appears. Applications should call net.hadess.SensorProxy.ReleaseLight() when readings are not required anymore. For example, an application that monitors the ambient light @@ -108,7 +112,7 @@ This should be called as soon as readings are not required anymore. Note that resources are freed up if a monitoring application exits without - calling net.hadess.SensorProxy.Release(), or crashes. + calling net.hadess.SensorProxy.Release(), crashes or the sensor disappears. -->