1
+ import io.rebble.libpebblecommon.protocolhelpers.PebblePacket
2
+ import io.rebble.libpebblecommon.protocolhelpers.ProtocolEndpoint
3
+ import io.rebble.libpebblecommon.ProtocolHandler
4
+
5
+ /* *
6
+ * Test double of the protocol handler.
7
+ *
8
+ * If you specify [sender] parameter, it will be called whenever packet is supposed to be sent.
9
+ * Otherwise outgoing packets collect in the [sentPackets] list.
10
+ *
11
+ * You can manually receive packets by calling [receivePacket].
12
+ */
13
+ @OptIn(ExperimentalUnsignedTypes ::class )
14
+ class TestProtocolHandler (private val sender : (suspend TestProtocolHandler .(PebblePacket ) -> Unit )? = null ) :
15
+ ProtocolHandler {
16
+ val sentPackets = ArrayList <PebblePacket >()
17
+
18
+ private val receiveRegistry = HashMap <ProtocolEndpoint , suspend (PebblePacket ) - > Unit > ()
19
+
20
+
21
+ /* *
22
+ * Send data to the watch. MUST be called within [withWatchContext]
23
+ */
24
+ override suspend fun send (packet : PebblePacket ) {
25
+ if (sender != null ) {
26
+ sender.invoke(this , packet)
27
+ } else {
28
+ sentPackets + = packet
29
+ }
30
+ }
31
+
32
+ /* *
33
+ * Calls the specified block within watch sending context. Only one block within watch context
34
+ * can be active at the same time, ensuring atomic bluetooth sending.
35
+ */
36
+ override suspend fun <T > withWatchContext (block : suspend () -> T ): T {
37
+ // Assume tests are run as single thread, no need for mutexes
38
+ return block()
39
+ }
40
+
41
+ override fun registerReceiveCallback (
42
+ endpoint : ProtocolEndpoint ,
43
+ callback : suspend (PebblePacket ) -> Unit
44
+ ) {
45
+ val existingCallback = receiveRegistry.put(endpoint, callback)
46
+ if (existingCallback != null ) {
47
+ throw IllegalStateException (
48
+ " Duplicate callback registered for $endpoint : $callback , $existingCallback "
49
+ )
50
+ }
51
+ }
52
+
53
+ /* *
54
+ * Handle pebble packet
55
+ */
56
+ suspend fun receivePacket (packet : PebblePacket ): Boolean {
57
+ val receiveCallback = receiveRegistry[packet.endpoint]
58
+ if (receiveCallback == null ) {
59
+ throw IllegalStateException (" ${packet.endpoint} does not have receive callback" )
60
+ } else {
61
+ receiveCallback.invoke(packet)
62
+ }
63
+
64
+ return true
65
+ }
66
+ }
0 commit comments