diff --git a/lib/src/dbus_client.dart b/lib/src/dbus_client.dart index 421ba24..f4df261 100644 --- a/lib/src/dbus_client.dart +++ b/lib/src/dbus_client.dart @@ -132,6 +132,8 @@ class DBusSignalStream extends Stream { _client._findUniqueName(_rule.sender!); } _client._addMatch(_rule.toDBusString()); + } else { + _client._connect(); } } @@ -1043,7 +1045,7 @@ class DBusClient { } var signal = DBusSignal( - sender: message.sender?.value ?? '', + sender: message.sender?.value, path: message.path ?? DBusObjectPath.root, interface: message.interface?.value ?? '', name: message.member?.value ?? '', diff --git a/lib/src/dbus_server.dart b/lib/src/dbus_server.dart index 2feed00..6f21ad8 100644 --- a/lib/src/dbus_server.dart +++ b/lib/src/dbus_server.dart @@ -385,6 +385,25 @@ class DBusServer { } } + /// Emits a signal from the D-Bus server. + void emitSignal( + {required DBusObjectPath path, + required String interface, + required String name, + Iterable values = const []}) { + var message = DBusMessage(DBusMessageType.signal, + flags: {DBusMessageFlag.noReplyExpected}, + serial: _nextSerial, + path: path, + interface: DBusInterfaceName(interface), + member: DBusMemberName(name), + values: values.toList()); + _nextSerial++; + for (var client in _clients) { + client.sendMessage(message); + } + } + /// Listens for connections on a Unix socket. Future _listenUnixSocket(DBusAddress address) async { var path = address.properties['path']; diff --git a/lib/src/dbus_signal.dart b/lib/src/dbus_signal.dart index 64fd5cf..a23e067 100644 --- a/lib/src/dbus_signal.dart +++ b/lib/src/dbus_signal.dart @@ -3,7 +3,7 @@ import 'dbus_value.dart'; /// A D-Bus signal. class DBusSignal { /// Client that sent the signal. - final String sender; + final String? sender; /// Path of the object emitting the signal. final DBusObjectPath path; diff --git a/test/dbus_test.dart b/test/dbus_test.dart index 65dc440..06427b3 100644 --- a/test/dbus_test.dart +++ b/test/dbus_test.dart @@ -5040,6 +5040,36 @@ void main() { expect(node.toXml().toXmlString(), equals('')); }); + test('no message bus - subscribe signal', () async { + var server = DBusServer(messageBus: false); + var address = + await server.listenAddress(DBusAddress.unix(dir: Directory.systemTemp)); + var client = DBusClient(address, messageBus: false); + addTearDown(() async { + await client.close(); + await server.close(); + }); + + var signals = + DBusSignalStream(client, interface: 'com.example.Test', name: 'Ping'); + signals.listen(expectAsync1((signal) { + expect(signal.sender, isNull); + expect(signal.path, equals(DBusObjectPath('/'))); + expect(signal.interface, equals('com.example.Test')); + expect(signal.name, equals('Ping')); + expect(signal.values, equals([DBusString('Hello'), DBusUint32(42)])); + })); + + // Ensure client is connected. + await client.ping(); + + server.emitSignal( + path: DBusObjectPath('/'), + interface: 'com.example.Test', + name: 'Ping', + values: [DBusString('Hello'), DBusUint32(42)]); + }); + test('introspect xml - empty', () { expect(() => parseDBusIntrospectXml(''), throwsFormatException); });