fix: Correct D-Bus signal handling and agent capability

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2025-12-30 22:12:17 +00:00
parent 19deff17a7
commit 8e624950aa

27
main.py
View File

@@ -14,7 +14,7 @@ from dbus_next.aio import MessageBus
from dbus_next.service import ServiceInterface, method from dbus_next.service import ServiceInterface, method
from dbus_next.constants import BusType from dbus_next.constants import BusType
from dbus_next.errors import DBusError from dbus_next.errors import DBusError
from dbus_next import Variant from dbus_next import Variant, Message, MessageType
bus = None bus = None
@@ -27,7 +27,7 @@ DEVICE_IFACE = 'org.bluez.Device1'
AGENT_IFACE = 'org.bluez.Agent1' AGENT_IFACE = 'org.bluez.Agent1'
AGENT_MANAGER_IFACE = 'org.bluez.AgentManager1' AGENT_MANAGER_IFACE = 'org.bluez.AgentManager1'
AGENT_PATH = '/io/bluetooth_speaker/agent' AGENT_PATH = '/io/bluetooth_speaker/agent'
CAPABILITY = 'NoInputNoOutput' CAPABILITY = 'DisplayYesNo'
CALLS_SERVICE_UUID = '0000111e-0000-1000-8000-00805f9b34fb' CALLS_SERVICE_UUID = '0000111e-0000-1000-8000-00805f9b34fb'
AUDIO_SERVICE_UUID = '0000110d-0000-1000-8000-00805f9b34fb' AUDIO_SERVICE_UUID = '0000110d-0000-1000-8000-00805f9b34fb'
@@ -167,18 +167,27 @@ async def monitor_unpairing():
adapter_iface = adapter_obj.get_interface(ADAPTER_IFACE) adapter_iface = adapter_obj.get_interface(ADAPTER_IFACE)
def _properties_changed_handler(interface_name, changed_properties, invalidated_properties, msg): def _properties_changed_handler(msg):
if msg.message_type != MessageType.SIGNAL or msg.member != 'PropertiesChanged' or msg.interface != 'org.freedesktop.DBus.Properties':
return
interface_name, changed_properties, invalidated_properties = msg.body
if interface_name == DEVICE_IFACE and 'Paired' in changed_properties and not changed_properties['Paired'].value: if interface_name == DEVICE_IFACE and 'Paired' in changed_properties and not changed_properties['Paired'].value:
device_path = msg.path device_path = msg.path
logging.info(f"Device {device_path} was unpaired by the remote host. Removing it.") logging.info(f"Device {device_path} was unpaired by the remote host. Removing it.")
asyncio.create_task(adapter_iface.call_remove_device(device_path)) asyncio.create_task(adapter_iface.call_remove_device(device_path))
bus.add_signal_receiver( bus.add_message_handler(_properties_changed_handler)
_properties_changed_handler,
signal_name='PropertiesChanged', await bus.call(
dbus_interface='org.freedesktop.DBus.Properties', Message(
path_namespace='/org/bluez' destination='org.freedesktop.DBus',
) path='/org/freedesktop/DBus',
interface='org.freedesktop.DBus',
member='AddMatch',
signature='s',
body=[f"type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path_namespace='/org/bluez'"]))
# Keep the task alive to listen for signals # Keep the task alive to listen for signals
while True: while True: