mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	bluetooth: handle absence of bluez D-Bus service properly
This commit is contained in:
		
							parent
							
								
									1104141d78
								
							
						
					
					
						commit
						c3958aaa07
					
				
					 1 changed files with 66 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -309,6 +309,17 @@ static void run_callback(pa_bluetooth_discovery *y, pa_bluetooth_device *d, pa_b
 | 
			
		|||
    pa_hook_fire(&y->hook, d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remove_all_devices(pa_bluetooth_discovery *y) {
 | 
			
		||||
    pa_bluetooth_device *d;
 | 
			
		||||
 | 
			
		||||
    pa_assert(y);
 | 
			
		||||
 | 
			
		||||
    while ((d = pa_hashmap_steal_first(y->devices))) {
 | 
			
		||||
        run_callback(y, d, TRUE);
 | 
			
		||||
        device_free(d);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		||||
    DBusMessage *r;
 | 
			
		||||
    DBusMessageIter arg_i, element_i;
 | 
			
		||||
| 
						 | 
				
			
			@ -332,6 +343,12 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
    if (dbus_message_is_method_call(p->message, "org.bluez.Device", "GetProperties"))
 | 
			
		||||
        d->device_info_valid = valid;
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
 | 
			
		||||
        pa_log_debug("Bluetooth daemon is apparently not available.");
 | 
			
		||||
        remove_all_devices(y);
 | 
			
		||||
        goto finish2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
 | 
			
		||||
 | 
			
		||||
        if (!dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD))
 | 
			
		||||
| 
						 | 
				
			
			@ -383,6 +400,7 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
finish:
 | 
			
		||||
    run_callback(y, d, FALSE);
 | 
			
		||||
 | 
			
		||||
finish2:
 | 
			
		||||
    dbus_message_unref(r);
 | 
			
		||||
 | 
			
		||||
    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
 | 
			
		||||
| 
						 | 
				
			
			@ -412,6 +430,9 @@ static void found_device(pa_bluetooth_discovery *y, const char* path) {
 | 
			
		|||
    pa_assert(y);
 | 
			
		||||
    pa_assert(path);
 | 
			
		||||
 | 
			
		||||
    if (pa_hashmap_get(y->devices, path))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    d = device_new(path);
 | 
			
		||||
 | 
			
		||||
    pa_hashmap_put(y->devices, d->path, d);
 | 
			
		||||
| 
						 | 
				
			
			@ -439,9 +460,15 @@ static void list_devices_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
    pa_assert_se(y = p->context_data);
 | 
			
		||||
    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
 | 
			
		||||
        pa_log_debug("Bluetooth daemon is apparently not available.");
 | 
			
		||||
        remove_all_devices(y);
 | 
			
		||||
        goto finish;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
 | 
			
		||||
        pa_log("Error from ListDevices reply: %s", dbus_message_get_error_name(r));
 | 
			
		||||
        goto end;
 | 
			
		||||
        goto finish;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!dbus_message_get_args(r, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &num, DBUS_TYPE_INVALID)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -454,7 +481,7 @@ static void list_devices_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
            found_device(y, paths[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
end:
 | 
			
		||||
finish:
 | 
			
		||||
    if (paths)
 | 
			
		||||
        dbus_free_string_array (paths);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -487,9 +514,15 @@ static void list_adapters_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
    pa_assert_se(y = p->context_data);
 | 
			
		||||
    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
 | 
			
		||||
        pa_log_debug("Bluetooth daemon is apparently not available.");
 | 
			
		||||
        remove_all_devices(y);
 | 
			
		||||
        goto finish;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
 | 
			
		||||
        pa_log("Error from ListAdapters reply: %s", dbus_message_get_error_name(r));
 | 
			
		||||
        goto end;
 | 
			
		||||
        goto finish;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!dbus_message_get_args(r, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &num, DBUS_TYPE_INVALID)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -502,7 +535,7 @@ static void list_adapters_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
            found_adapter(y, paths[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
end:
 | 
			
		||||
finish:
 | 
			
		||||
    if (paths)
 | 
			
		||||
        dbus_free_string_array (paths);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -615,6 +648,32 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
 | 
			
		|||
            run_callback(y, d, FALSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
			
		||||
 | 
			
		||||
    } else if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
 | 
			
		||||
        const char *name, *old_owner, *new_owner;
 | 
			
		||||
 | 
			
		||||
        if (!dbus_message_get_args(m, &err,
 | 
			
		||||
                                   DBUS_TYPE_STRING, &name,
 | 
			
		||||
                                   DBUS_TYPE_STRING, &old_owner,
 | 
			
		||||
                                   DBUS_TYPE_STRING, &new_owner,
 | 
			
		||||
                                   DBUS_TYPE_INVALID)) {
 | 
			
		||||
            pa_log("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pa_streq(name, "org.bluez")) {
 | 
			
		||||
            if (old_owner && *old_owner) {
 | 
			
		||||
                pa_log_debug("Bluetooth daemon disappeared.");
 | 
			
		||||
                remove_all_devices(y);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (new_owner && *new_owner) {
 | 
			
		||||
                pa_log_debug("Bluetooth daemon appeared.");
 | 
			
		||||
                list_adapters(y);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -699,6 +758,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
 | 
			
		|||
 | 
			
		||||
    if (pa_dbus_add_matches(
 | 
			
		||||
                pa_dbus_connection_get(y->connection), &err,
 | 
			
		||||
                "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'",
 | 
			
		||||
                "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
 | 
			
		||||
                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
 | 
			
		||||
                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
 | 
			
		||||
| 
						 | 
				
			
			@ -734,8 +794,6 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 | 
			
		||||
    pa_bluetooth_device *d;
 | 
			
		||||
 | 
			
		||||
    pa_assert(y);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(y) > 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -745,16 +803,13 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 | 
			
		|||
    pa_dbus_free_pending_list(&y->pending);
 | 
			
		||||
 | 
			
		||||
    if (y->devices) {
 | 
			
		||||
        while ((d = pa_hashmap_steal_first(y->devices))) {
 | 
			
		||||
            run_callback(y, d, TRUE);
 | 
			
		||||
            device_free(d);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        remove_all_devices(y);
 | 
			
		||||
        pa_hashmap_free(y->devices, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (y->connection) {
 | 
			
		||||
        pa_dbus_remove_matches(pa_dbus_connection_get(y->connection),
 | 
			
		||||
                               "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'",
 | 
			
		||||
                               "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
 | 
			
		||||
                               "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterRemoved'",
 | 
			
		||||
                               "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue