feat(core): Remove the PresenceReceivedEvent

This commit is contained in:
PapaTutuWawa 2023-06-07 15:12:34 +02:00
parent cbd90b1163
commit da1d28a6d6
6 changed files with 183 additions and 167 deletions

View File

@ -14,6 +14,7 @@
- **BREAKING**: `MessageManager.sendMessage` does not use `MessageDetails` anymore. Instead, use `TypedMap`. - **BREAKING**: `MessageManager.sendMessage` does not use `MessageDetails` anymore. Instead, use `TypedMap`.
- `MessageManager` now allows registering callbacks for adding data whenever a message is sent. - `MessageManager` now allows registering callbacks for adding data whenever a message is sent.
- **BREAKING**: `MessageEvent` now makes use of `TypedMap`. - **BREAKING**: `MessageEvent` now makes use of `TypedMap`.
- **BREAKING**: Removed `PresenceReceivedEvent`. Use a manager registering handlers with priority greater than `[PresenceManager.presenceHandlerPriority]` instead.
## 0.3.1 ## 0.3.1

View File

@ -138,13 +138,6 @@ class ResourceBoundEvent extends XmppEvent {
final String resource; final String resource;
} }
/// Triggered when we receive presence
class PresenceReceivedEvent extends XmppEvent {
PresenceReceivedEvent(this.jid, this.presence);
final JID jid;
final Stanza presence;
}
/// Triggered when we are starting an connection attempt /// Triggered when we are starting an connection attempt
class ConnectingEvent extends XmppEvent {} class ConnectingEvent extends XmppEvent {}

View File

@ -46,6 +46,11 @@ class MessageIdData {
class MessageManager extends XmppManagerBase { class MessageManager extends XmppManagerBase {
MessageManager() : super(messageManager); MessageManager() : super(messageManager);
/// The priority of the message handler. If a handler should run before this one,
/// which emits the [MessageEvent] event and terminates processing, make sure it
/// has a priority greater than [messageHandlerPriority].
static int messageHandlerPriority = -100;
/// A list of callbacks that are called when a message is sent in order to add /// A list of callbacks that are called when a message is sent in order to add
/// appropriate child elements. /// appropriate child elements.
final List<MessageSendingCallback> _messageSendingCallbacks = final List<MessageSendingCallback> _messageSendingCallbacks =
@ -60,7 +65,7 @@ class MessageManager extends XmppManagerBase {
StanzaHandler( StanzaHandler(
stanzaTag: 'message', stanzaTag: 'message',
callback: _onMessage, callback: _onMessage,
priority: -100, priority: messageHandlerPriority,
) )
]; ];

View File

@ -23,11 +23,17 @@ class PresenceManager extends XmppManagerBase {
final List<PresencePreSendCallback> _presenceCallbacks = final List<PresencePreSendCallback> _presenceCallbacks =
List.empty(growable: true); List.empty(growable: true);
/// The priority of the presence handler. If a handler should run before this one,
/// which terminates processing, make sure the handler has a priority greater than
/// [presenceHandlerPriority].
static int presenceHandlerPriority = -100;
@override @override
List<StanzaHandler> getIncomingStanzaHandlers() => [ List<StanzaHandler> getIncomingStanzaHandlers() => [
StanzaHandler( StanzaHandler(
stanzaTag: 'presence', stanzaTag: 'presence',
callback: _onPresence, callback: _onPresence,
priority: presenceHandlerPriority,
) )
]; ];
@ -75,9 +81,6 @@ class PresenceManager extends XmppManagerBase {
if (presence.from != null) { if (presence.from != null) {
logger.finest("Received presence from '${presence.from}'"); logger.finest("Received presence from '${presence.from}'");
getAttributes().sendEvent(
PresenceReceivedEvent(JID.fromString(presence.from!), presence),
);
return state..done = true; return state..done = true;
} }

View File

@ -4,10 +4,13 @@ import 'package:meta/meta.dart';
import 'package:moxxmpp/src/events.dart'; import 'package:moxxmpp/src/events.dart';
import 'package:moxxmpp/src/jid.dart'; import 'package:moxxmpp/src/jid.dart';
import 'package:moxxmpp/src/managers/base.dart'; import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/presence.dart'; import 'package:moxxmpp/src/presence.dart';
import 'package:moxxmpp/src/rfcs/rfc_4790.dart'; import 'package:moxxmpp/src/rfcs/rfc_4790.dart';
import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
import 'package:moxxmpp/src/util/list.dart'; import 'package:moxxmpp/src/util/list.dart';
import 'package:moxxmpp/src/xeps/xep_0004.dart'; import 'package:moxxmpp/src/xeps/xep_0004.dart';
@ -105,7 +108,20 @@ class EntityCapabilitiesManager extends XmppManagerBase {
Future<bool> isSupported() async => true; Future<bool> isSupported() async => true;
@override @override
List<String> getDiscoFeatures() => [capsXmlns]; List<String> getDiscoFeatures() => [
capsXmlns,
];
@override
List<StanzaHandler> getIncomingStanzaHandlers() => [
StanzaHandler(
stanzaTag: 'presence',
tagName: 'c',
tagXmlns: capsXmlns,
callback: onPresence,
priority: PresenceManager.presenceHandlerPriority + 1,
),
];
/// Computes, if required, the capability hash of the data provided by /// Computes, if required, the capability hash of the data provided by
/// the DiscoManager. /// the DiscoManager.
@ -159,33 +175,38 @@ class EntityCapabilitiesManager extends XmppManagerBase {
} }
@visibleForTesting @visibleForTesting
Future<void> onPresence(PresenceReceivedEvent event) async { Future<StanzaHandlerData> onPresence(
final c = event.presence.firstTag('c', xmlns: capsXmlns); Stanza stanza,
if (c == null) { StanzaHandlerData state,
return; ) async {
if (stanza.from == null) {
return state;
} }
final from = JID.fromString(stanza.from!);
final c = stanza.firstTag('c', xmlns: capsXmlns)!;
final hashFunctionName = c.attributes['hash'] as String?; final hashFunctionName = c.attributes['hash'] as String?;
final capabilityNode = c.attributes['node'] as String?; final capabilityNode = c.attributes['node'] as String?;
final ver = c.attributes['ver'] as String?; final ver = c.attributes['ver'] as String?;
if (hashFunctionName == null || capabilityNode == null || ver == null) { if (hashFunctionName == null || capabilityNode == null || ver == null) {
return; return state;
} }
// Check if we know of the hash // Check if we know of the hash
final isCached = final isCached =
await _cacheLock.synchronized(() => _capHashCache.containsKey(ver)); await _cacheLock.synchronized(() => _capHashCache.containsKey(ver));
if (isCached) { if (isCached) {
return; return state;
} }
final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!; final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!;
final discoRequest = await dm.discoInfoQuery( final discoRequest = await dm.discoInfoQuery(
event.jid, from,
node: capabilityNode, node: capabilityNode,
); );
if (discoRequest.isType<DiscoError>()) { if (discoRequest.isType<DiscoError>()) {
return; return state;
} }
final discoInfo = discoRequest.get<DiscoInfo>(); final discoInfo = discoRequest.get<DiscoInfo>();
@ -194,13 +215,13 @@ class EntityCapabilitiesManager extends XmppManagerBase {
await dm.addCachedDiscoInfo( await dm.addCachedDiscoInfo(
MapEntry<DiscoCacheKey, DiscoInfo>( MapEntry<DiscoCacheKey, DiscoInfo>(
DiscoCacheKey( DiscoCacheKey(
event.jid, from,
null, null,
), ),
discoInfo, discoInfo,
), ),
); );
return; return state;
} }
// Validate the disco#info result according to XEP-0115 § 5.4 // Validate the disco#info result according to XEP-0115 § 5.4
@ -214,7 +235,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
logger.warning( logger.warning(
'Malformed disco#info response: More than one equal identity', 'Malformed disco#info response: More than one equal identity',
); );
return; return state;
} }
} }
@ -225,7 +246,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
logger.warning( logger.warning(
'Malformed disco#info response: More than one equal feature', 'Malformed disco#info response: More than one equal feature',
); );
return; return state;
} }
} }
@ -253,7 +274,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
logger.warning( logger.warning(
'Malformed disco#info response: Extended Info FORM_TYPE contains more than one value(s) of different value.', 'Malformed disco#info response: Extended Info FORM_TYPE contains more than one value(s) of different value.',
); );
return; return state;
} }
} }
@ -268,7 +289,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
logger.warning( logger.warning(
'Malformed disco#info response: More than one Extended Disco Info forms with the same FORM_TYPE value', 'Malformed disco#info response: More than one Extended Disco Info forms with the same FORM_TYPE value',
); );
return; return state;
} }
// Check if the field type is hidden // Check if the field type is hidden
@ -297,14 +318,16 @@ class EntityCapabilitiesManager extends XmppManagerBase {
if (computedCapabilityHash == ver) { if (computedCapabilityHash == ver) {
await _cacheLock.synchronized(() { await _cacheLock.synchronized(() {
_jidToCapHashCache[event.jid.toString()] = ver; _jidToCapHashCache[from.toString()] = ver;
_capHashCache[ver] = newDiscoInfo; _capHashCache[ver] = newDiscoInfo;
}); });
} else { } else {
logger.warning( logger.warning(
'Capability hash mismatch from ${event.jid}: Received "$ver", expected "$computedCapabilityHash".', 'Capability hash mismatch from $from: Received "$ver", expected "$computedCapabilityHash".',
); );
} }
return state;
} }
@visibleForTesting @visibleForTesting
@ -315,9 +338,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
@override @override
Future<void> onXmppEvent(XmppEvent event) async { Future<void> onXmppEvent(XmppEvent event) async {
if (event is PresenceReceivedEvent) { if (event is StreamNegotiationsDoneEvent) {
unawaited(onPresence(event));
} else if (event is StreamNegotiationsDoneEvent) {
// Clear the JID to cap. hash mapping. // Clear the JID to cap. hash mapping.
await _cacheLock.synchronized(_jidToCapHashCache.clear); await _cacheLock.synchronized(_jidToCapHashCache.clear);
} }

View File

@ -1,4 +1,5 @@
import 'package:moxxmpp/moxxmpp.dart'; import 'package:moxxmpp/moxxmpp.dart';
import 'package:moxxmpp/src/util/typed_map.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../helpers/logging.dart'; import '../helpers/logging.dart';
@ -324,24 +325,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
expect( expect(
@ -359,24 +359,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94AAAAA=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94AAAAA=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
expect( expect(
@ -394,24 +393,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
expect( expect(
@ -429,24 +427,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
expect( expect(
@ -464,24 +461,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
expect( expect(
@ -499,24 +495,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
final cachedItem = await manager.getCachedDiscoInfoFromJid(aliceJid); final cachedItem = await manager.getCachedDiscoInfoFromJid(aliceJid);
@ -536,24 +531,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
final cachedItem = await manager.getCachedDiscoInfoFromJid(aliceJid); final cachedItem = await manager.getCachedDiscoInfoFromJid(aliceJid);
@ -573,24 +567,23 @@ void main() {
manager, manager,
]); ]);
await manager.onPresence( final stanza = Stanza.presence(
PresenceReceivedEvent( from: aliceJid.toString(),
aliceJid, children: [
Stanza.presence( XMLNode.xmlns(
from: aliceJid.toString(), tag: 'c',
children: [ xmlns: capsXmlns,
XMLNode.xmlns( attributes: {
tag: 'c', 'hash': 'sha-1',
xmlns: capsXmlns, 'node': 'http://example.org/client',
attributes: { 'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
'hash': 'sha-1', },
'node': 'http://example.org/client',
'ver': 'QgayPKawpkPSDYmwT/WM94uAlu0=',
},
),
],
), ),
), ],
);
await manager.onPresence(
stanza,
StanzaHandlerData(false, false, stanza, TypedMap()),
); );
expect( expect(