diff options
author | Bastien Nocera <hadess@hadess.net> | 2022-08-25 16:09:48 +0200 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2022-08-31 11:11:32 +0200 |
commit | c9de6bc6c867860cb4ec1f2bec2c6d881c17155d (patch) | |
tree | 9f884b517293bd5300993a970e0efd7515254315 | |
parent | 6d57122b13698e26434a09697ea7b1b9d5ae7905 (diff) | |
download | gnome-bluetooth-c9de6bc6c867860cb4ec1f2bec2c6d881c17155d.tar.gz |
lib: Implement default-adapter-state property using bluez
Use new adapter property in bluez to implement the
default-adapter-state. It should work better, as it doesn't rely only on
internal BluetoothClient state in a single process, and can get
information when bluetoothd is powering up the adapter.
Note that this property still works in the absence of a new enough
bluetoothd, without the transitional states.
Closes: #121
-rw-r--r-- | lib/bluetooth-client.c | 69 | ||||
-rw-r--r-- | lib/bluetooth-client.xml | 1 | ||||
-rwxr-xr-x | tests/integration-test.py | 6 |
3 files changed, 33 insertions, 43 deletions
diff --git a/lib/bluetooth-client.c b/lib/bluetooth-client.c index a39317bb..e005f2d0 100644 --- a/lib/bluetooth-client.c +++ b/lib/bluetooth-client.c @@ -54,19 +54,12 @@ #define BLUEZ_ADAPTER_INTERFACE "org.bluez.Adapter1" #define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1" -/* Subset of BluetoothAdapterState */ -typedef enum { - POWER_STATE_REQUEST_NONE = 0, - POWER_STATE_REQUEST_ON, - POWER_STATE_REQUEST_OFF, -} PowerStateRequest; - struct _BluetoothClient { GObject parent; GListStore *list_store; Adapter1 *default_adapter; - PowerStateRequest power_req; + gboolean has_power_state; GDBusObjectManager *manager; GCancellable *cancellable; guint num_adapters; @@ -418,31 +411,15 @@ adapter_set_powered_cb (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) { - BluetoothClient *client; g_autoptr(GError) error = NULL; g_autoptr(GVariant) ret = NULL; ret = g_dbus_proxy_call_finish (proxy, res, &error); if (!ret) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; g_debug ("Error setting property 'Powered' on %s: %s (%s, %d)", g_dbus_proxy_get_object_path (proxy), error->message, g_quark_to_string (error->domain), error->code); } - - client = user_data; - if (client->default_adapter) { - gboolean powered; - - powered = adapter1_get_powered (client->default_adapter); - if ((powered && client->power_req == POWER_STATE_REQUEST_ON) || - (!powered && client->power_req == POWER_STATE_REQUEST_OFF)) { - /* Only reset if we don't have a conflicting state in progress */ - client->power_req = POWER_STATE_REQUEST_NONE; - } - } - g_object_notify (G_OBJECT (client), "default-adapter-state"); } static void @@ -458,12 +435,6 @@ adapter_set_powered (BluetoothClient *client, return; } - if ((powered && client->power_req == POWER_STATE_REQUEST_ON) || - (!powered && client->power_req == POWER_STATE_REQUEST_OFF)) { - g_debug ("Default adapter is already being powered %s", powered ? "on" : "off"); - return; - } - if (powered == adapter1_get_powered (client->default_adapter)) { g_debug ("Default adapter is already %spowered", powered ? "" : "un"); return; @@ -473,9 +444,6 @@ adapter_set_powered (BluetoothClient *client, powered ? "up" : "down", g_dbus_proxy_get_object_path (G_DBUS_PROXY (client->default_adapter))); variant = g_variant_new_boolean (powered); - client->power_req = powered ? - POWER_STATE_REQUEST_ON : POWER_STATE_REQUEST_OFF; - g_object_notify (G_OBJECT (client), "default-adapter-state"); g_dbus_proxy_call (G_DBUS_PROXY (client->default_adapter), "org.freedesktop.DBus.Properties.Set", g_variant_new ("(ssv)", "org.bluez.Adapter1", "Powered", variant), @@ -588,6 +556,9 @@ adapter_notify_cb (Adapter1 *adapter, g_object_notify (G_OBJECT (client), "default-adapter-setup-mode"); } else if (g_strcmp0 (property, "powered") == 0) { g_object_notify (G_OBJECT (client), "default-adapter-powered"); + if (!client->has_power_state) + g_object_notify (G_OBJECT (client), "default-adapter-state"); + } else if (g_strcmp0 (property, "power-state") == 0) { g_object_notify (G_OBJECT (client), "default-adapter-state"); } } @@ -639,6 +610,7 @@ default_adapter_changed (GDBusObjectManager *manager, g_list_store_remove_all (client->list_store); g_debug ("Disabling discovery on old default adapter"); _bluetooth_client_set_default_adapter_discovering (client, FALSE); + g_clear_object (&client->default_adapter); } client->default_adapter = ADAPTER1 (g_object_ref (G_OBJECT (adapter))); @@ -739,7 +711,6 @@ adapter_removed (GDBusObjectManager *manager, if (!was_default) goto out; - new_default_adapter = NULL; object_list = g_dbus_object_manager_get_objects (client->manager); for (l = object_list; l != NULL; l = l->next) { @@ -1114,6 +1085,7 @@ static void bluetooth_client_init(BluetoothClient *client) { client->cancellable = g_cancellable_new (); client->list_store = g_list_store_new (BLUETOOTH_TYPE_DEVICE); + client->has_power_state = TRUE; g_dbus_object_manager_client_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, @@ -1248,14 +1220,31 @@ _bluetooth_client_set_default_adapter_discovering (BluetoothClient *client, static BluetoothAdapterState adapter_get_state (BluetoothClient *client) { + const char *str; + if (!client->default_adapter) return BLUETOOTH_ADAPTER_STATE_ABSENT; - if (client->power_req == POWER_STATE_REQUEST_NONE) - return adapter1_get_powered (client->default_adapter) ? - BLUETOOTH_ADAPTER_STATE_ON : BLUETOOTH_ADAPTER_STATE_OFF; - return client->power_req == POWER_STATE_REQUEST_ON ? - BLUETOOTH_ADAPTER_STATE_TURNING_ON : - BLUETOOTH_ADAPTER_STATE_TURNING_OFF; + + str = adapter1_get_power_state (client->default_adapter); + if (str) { + if (g_str_equal (str, "on")) + return BLUETOOTH_ADAPTER_STATE_ON; + if (g_str_equal (str, "off") || + g_str_equal (str, "off-blocked")) + return BLUETOOTH_ADAPTER_STATE_OFF; + if (g_str_equal (str, "off-enabling")) + return BLUETOOTH_ADAPTER_STATE_TURNING_ON; + if (g_str_equal (str, "on-disabling")) + return BLUETOOTH_ADAPTER_STATE_TURNING_OFF; + g_warning_once ("Unexpected adapter PowerState value '%s'", str); + } else { + client->has_power_state = FALSE; + } + + /* Fallback if property is missing, or value is unexpected */ + return adapter1_get_powered (client->default_adapter) ? + BLUETOOTH_ADAPTER_STATE_ON : BLUETOOTH_ADAPTER_STATE_OFF; + } static void diff --git a/lib/bluetooth-client.xml b/lib/bluetooth-client.xml index 13248214..57b958ff 100644 --- a/lib/bluetooth-client.xml +++ b/lib/bluetooth-client.xml @@ -12,6 +12,7 @@ <property name="Alias" type="s" access="readwrite"></property> <property name="Class" type="u" access="read"></property> <property name="Powered" type="b" access="readwrite"></property> + <property name="PowerState" type="s" access="read"></property> <property name="Discoverable" type="b" access="readwrite"></property> <property name="DiscoverableTimeout" type="u" access="readwrite"></property> <property name="Pairable" type="b" access="readwrite"></property> diff --git a/tests/integration-test.py b/tests/integration-test.py index 83550c3a..a3648c25 100755 --- a/tests/integration-test.py +++ b/tests/integration-test.py @@ -267,7 +267,8 @@ class OopTests(dbusmock.DBusTestCase): self.assertEqual(dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered'), False) self.assertEqual(self.client.props.default_adapter_state, GnomeBluetoothPriv.AdapterState.OFF) self.client.props.default_adapter_powered = True - self.assertEqual(self.client.props.default_adapter_state, GnomeBluetoothPriv.AdapterState.TURNING_ON) + # NOTE: this should be "turning on" + self.assertEqual(self.client.props.default_adapter_state, GnomeBluetoothPriv.AdapterState.OFF) self.wait_for_condition(lambda: dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered') == True) self.assertEqual(self.client.props.num_adapters, 1) self.assertEqual(dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered'), True) @@ -278,7 +279,6 @@ class OopTests(dbusmock.DBusTestCase): self.client.props.default_adapter_powered = False self.wait_for_condition(lambda: dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered') == False) self.assertEqual(dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered'), False) - self.assertEqual(self.client.props.default_adapter_state, GnomeBluetoothPriv.AdapterState.TURNING_OFF) self.wait_for_mainloop() self.assertEqual(self.client.props.default_adapter_powered, False) self.assertEqual(self.client.props.default_adapter_state, GnomeBluetoothPriv.AdapterState.OFF) @@ -286,7 +286,7 @@ class OopTests(dbusmock.DBusTestCase): dbusmock_bluez.UpdateProperties('org.bluez.Adapter1', { 'Powered': True, }) - # NOTE: this should be "turning on" when we have bluez API to keep track of it + # NOTE: this should be "turning on" self.assertEqual(self.client.props.default_adapter_state, GnomeBluetoothPriv.AdapterState.OFF) self.wait_for_condition(lambda: dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered') == True) self.assertEqual(dbusprops_bluez.Get('org.bluez.Adapter1', 'Powered'), True) |