-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPcConnector.kt
More file actions
91 lines (80 loc) · 4.59 KB
/
Copy pathPcConnector.kt
File metadata and controls
91 lines (80 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.enaboapps.switchify.pc
import kotlinx.coroutines.flow.Flow
sealed class PcPairingResult {
data class Paired(val desktopId: String, val token: String, val endpointId: String) : PcPairingResult()
data class Failed(val reason: PcErrorReason, val message: String) : PcPairingResult()
}
sealed class PcPingResult {
data class Connected(val endpointId: String) : PcPingResult()
data class AuthFailed(val message: String = "Connection expired. Request access again.") : PcPingResult()
data class Failed(val reason: PcErrorReason, val message: String) : PcPingResult()
}
sealed class PcControlCommand {
data class Move(val dx: Int, val dy: Int) : PcControlCommand()
data class Scroll(val dx: Int, val dy: Int) : PcControlCommand()
data class RepeatStart(val command: PcControlCommand) : PcControlCommand()
data object RepeatStop : PcControlCommand()
data class DragStart(val button: String = "left") : PcControlCommand()
data class DragEnd(val button: String = "left") : PcControlCommand()
data class TypeText(val text: String) : PcControlCommand()
data class TextStreamOpen(val streamId: String) : PcControlCommand()
data class TextStreamChar(val streamId: String, val seq: Int, val text: String) : PcControlCommand()
data class TextStreamChunk(val streamId: String, val seq: Int, val text: String) : PcControlCommand()
data class TextStreamKey(val streamId: String, val seq: Int, val key: PcKeyboardKey) : PcControlCommand()
data class TextStreamClose(val streamId: String, val expectedCount: Int) : PcControlCommand()
data class PressKey(val key: PcKeyboardKey) : PcControlCommand()
data class KeyboardShortcut(val keys: List<PcKeyboardShortcutKey>) : PcControlCommand()
data class ModifierDown(val key: PcKeyboardModifierKey) : PcControlCommand()
data class ModifierUp(val key: PcKeyboardModifierKey) : PcControlCommand()
data class WindowControl(val action: PcWindowControlAction) : PcControlCommand()
data class SetPointerSpeed(val scalePercent: Double) : PcControlCommand()
data object LeftClick : PcControlCommand()
data object DoubleClick : PcControlCommand()
data object RightClick : PcControlCommand()
}
sealed class PcCommandResult {
data object Ack : PcCommandResult()
data class AuthFailed(val message: String = "Connection expired. Connect to PC from Switchify first.") : PcCommandResult()
data class Failed(val message: String = "Could not send command to PC.") : PcCommandResult()
}
sealed class PcLiveControlResult {
data class Connected(val connection: PcControlConnection) : PcLiveControlResult()
data class AuthFailed(val message: String = "Connection expired. Connect to PC from Switchify first.") : PcLiveControlResult()
data class Failed(val message: String = "Could not connect to PC.") : PcLiveControlResult()
}
interface PcControlConnection {
val pointerProfile: PcPointerMovementProfile?
val connectionEvents: Flow<PcControlConnectionEvent>
suspend fun checkHealth(): PcCommandResult
suspend fun sendCommand(command: PcControlCommand): PcCommandResult
suspend fun sendRealtimeCommand(command: PcControlCommand): PcCommandResult
fun close(reason: PcControlCloseReason = PcControlCloseReason.ExplicitStop)
}
enum class PcControlCloseReason(val logName: String) {
UiPauseGraceExpired("ui_pause_grace_expired"),
ExplicitStop("explicit_stop"),
CommandFailureRecovery("command_failure_recovery"),
AuthFailure("auth_failure"),
ConnectorShutdown("connector_shutdown"),
Reconnect("reconnect"),
UnexpectedDisconnect("unexpected_disconnect")
}
sealed class PcControlConnectionEvent {
data object Disconnected : PcControlConnectionEvent()
}
internal fun resolveExpectedResponse(response: PcProtocolResponse, requestId: String): PcProtocolResponse? {
return when (response) {
is PcProtocolResponse.Ack -> response.takeIf { it.id == requestId }
is PcProtocolResponse.PairingComplete -> response.takeIf { it.id == requestId }
is PcProtocolResponse.PointerProfile -> response.takeIf { it.id == requestId }
is PcProtocolResponse.Error -> response.takeIf { it.id == requestId || it.id == null }
PcProtocolResponse.Invalid -> null
}
}
interface PcConnector {
suspend fun requestApproval(pc: DiscoveredPc, requestNonce: String): PcPairingResult
suspend fun authenticatedPing(pc: DiscoveredPc, token: String): PcPingResult
suspend fun openControlSession(session: PcAuthenticatedSession): PcLiveControlResult
suspend fun sendCommand(session: PcAuthenticatedSession, command: PcControlCommand): PcCommandResult
fun close()
}