feat: Enhance logging and debugging capabilities across Protocol and UI components

This commit is contained in:
k1ngsterr1
2026-01-09 00:34:45 +05:00
parent 28a0d7a601
commit 87cee5b9c3
7 changed files with 467 additions and 164 deletions

View File

@@ -24,7 +24,10 @@ enum class ProtocolState {
* Protocol client for Rosetta Messenger
* Handles WebSocket connection and packet exchange with server
*/
class Protocol(private val serverAddress: String) {
class Protocol(
private val serverAddress: String,
private val logger: (String) -> Unit = {}
) {
companion object {
private const val TAG = "RosettaProtocol"
private const val RECONNECT_INTERVAL = 10000L // 10 seconds
@@ -32,6 +35,11 @@ class Protocol(private val serverAddress: String) {
private const val HANDSHAKE_TIMEOUT = 10000L // 10 seconds
}
private fun log(message: String) {
Log.d(TAG, message)
logger(message)
}
private val client = OkHttpClient.Builder()
.readTimeout(0, TimeUnit.MILLISECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
@@ -75,7 +83,7 @@ class Protocol(private val serverAddress: String) {
// Register handshake response handler
waitPacket(0x00) { packet ->
if (packet is PacketHandshake) {
Log.d(TAG, "✅ Handshake response received, protocol version: ${packet.protocolVersion}")
log("✅ Handshake response received, protocol version: ${packet.protocolVersion}")
handshakeJob?.cancel()
handshakeComplete = true
_state.value = ProtocolState.AUTHENTICATED
@@ -89,7 +97,7 @@ class Protocol(private val serverAddress: String) {
*/
fun connect() {
if (_state.value == ProtocolState.CONNECTING || _state.value == ProtocolState.CONNECTED) {
Log.d(TAG, "Already connecting or connected")
log("Already connecting or connected")
return
}
@@ -97,7 +105,7 @@ class Protocol(private val serverAddress: String) {
_state.value = ProtocolState.CONNECTING
_lastError.value = null
Log.d(TAG, "🔌 Connecting to: $serverAddress")
log("🔌 Connecting to: $serverAddress")
val request = Request.Builder()
.url(serverAddress)
@@ -105,7 +113,7 @@ class Protocol(private val serverAddress: String) {
webSocket = client.newWebSocket(request, object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
Log.d(TAG, "✅ WebSocket connected")
log("✅ WebSocket connected")
reconnectAttempts = 0
_state.value = ProtocolState.CONNECTED
@@ -122,20 +130,20 @@ class Protocol(private val serverAddress: String) {
}
override fun onMessage(webSocket: WebSocket, text: String) {
Log.d(TAG, "Received text message (unexpected): $text")
log("Received text message (unexpected): $text")
}
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
Log.d(TAG, "WebSocket closing: $code - $reason")
log("WebSocket closing: $code - $reason")
}
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
Log.d(TAG, "WebSocket closed: $code - $reason")
log("WebSocket closed: $code - $reason")
handleDisconnect()
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
Log.e(TAG, "❌ WebSocket error: ${t.message}")
log("❌ WebSocket error: ${t.message}")
_lastError.value = t.message
handleDisconnect()
}
@@ -146,16 +154,16 @@ class Protocol(private val serverAddress: String) {
* Start handshake with server
*/
fun startHandshake(publicKey: String, privateHash: String) {
Log.d(TAG, "🤝 Starting handshake...")
Log.d(TAG, " Public key: ${publicKey.take(20)}...")
Log.d(TAG, " Private hash: ${privateHash.take(20)}...")
log("🤝 Starting handshake...")
log(" Public key: ${publicKey.take(20)}...")
log(" Private hash: ${privateHash.take(20)}...")
// Save credentials for reconnection
lastPublicKey = publicKey
lastPrivateHash = privateHash
if (_state.value != ProtocolState.CONNECTED && _state.value != ProtocolState.AUTHENTICATED) {
Log.d(TAG, "Not connected, will handshake after connection")
log("Not connected, will handshake after connection")
connect()
return
}
@@ -175,7 +183,7 @@ class Protocol(private val serverAddress: String) {
handshakeJob = scope.launch {
delay(HANDSHAKE_TIMEOUT)
if (!handshakeComplete) {
Log.e(TAG, "❌ Handshake timeout")
log("❌ Handshake timeout")
_lastError.value = "Handshake timeout"
disconnect()
}
@@ -188,7 +196,7 @@ class Protocol(private val serverAddress: String) {
*/
fun sendPacket(packet: Packet) {
if (!handshakeComplete && packet !is PacketHandshake) {
Log.d(TAG, "📦 Queueing packet: ${packet.getPacketId()}")
log("📦 Queueing packet: ${packet.getPacketId()}")
packetQueue.add(packet)
return
}
@@ -199,13 +207,13 @@ class Protocol(private val serverAddress: String) {
val stream = packet.send()
val data = stream.getStream()
Log.d(TAG, "📤 Sending packet: ${packet.getPacketId()} (${data.size} bytes)")
log("📤 Sending packet: ${packet.getPacketId()} (${data.size} bytes)")
webSocket?.send(ByteString.of(*data))
}
private fun flushPacketQueue() {
Log.d(TAG, "📬 Flushing ${packetQueue.size} queued packets")
log("📬 Flushing ${packetQueue.size} queued packets")
val packets = packetQueue.toList()
packetQueue.clear()
packets.forEach { sendPacketDirect(it) }
@@ -216,11 +224,11 @@ class Protocol(private val serverAddress: String) {
val stream = Stream(data)
val packetId = stream.readInt16()
Log.d(TAG, "📥 Received packet: $packetId")
log("📥 Received packet: $packetId")
val packetFactory = supportedPackets[packetId]
if (packetFactory == null) {
Log.w(TAG, "Unknown packet ID: $packetId")
log("⚠️ Unknown packet ID: $packetId")
return
}
@@ -232,11 +240,11 @@ class Protocol(private val serverAddress: String) {
try {
callback(packet)
} catch (e: Exception) {
Log.e(TAG, "Error in packet handler: ${e.message}")
log("Error in packet handler: ${e.message}")
}
}
} catch (e: Exception) {
Log.e(TAG, "Error parsing packet: ${e.message}")
log("Error parsing packet: ${e.message}")
}
}
@@ -247,14 +255,14 @@ class Protocol(private val serverAddress: String) {
if (!isManuallyClosed && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
reconnectAttempts++
Log.d(TAG, "🔄 Reconnecting in ${RECONNECT_INTERVAL}ms (attempt $reconnectAttempts/$MAX_RECONNECT_ATTEMPTS)")
log("🔄 Reconnecting in ${RECONNECT_INTERVAL}ms (attempt $reconnectAttempts/$MAX_RECONNECT_ATTEMPTS)")
scope.launch {
delay(RECONNECT_INTERVAL)
connect()
}
} else if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
Log.e(TAG, "❌ Max reconnect attempts reached")
log("❌ Max reconnect attempts reached")
_lastError.value = "Unable to connect to server"
}
}
@@ -277,7 +285,7 @@ class Protocol(private val serverAddress: String) {
* Disconnect from server
*/
fun disconnect() {
Log.d(TAG, "Disconnecting...")
log("Disconnecting...")
isManuallyClosed = true
handshakeJob?.cancel()
webSocket?.close(1000, "User disconnected")

View File

@@ -1,7 +1,11 @@
package com.rosetta.messenger.network
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.text.SimpleDateFormat
import java.util.*
/**
* Singleton manager for Protocol instance
@@ -15,13 +19,31 @@ object ProtocolManager {
private var protocol: Protocol? = null
// Debug logs for dev console
private val _debugLogs = MutableStateFlow<List<String>>(emptyList())
val debugLogs: StateFlow<List<String>> = _debugLogs.asStateFlow()
private val dateFormat = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
fun addLog(message: String) {
val timestamp = dateFormat.format(Date())
val logLine = "[$timestamp] $message"
Log.d(TAG, logLine)
_debugLogs.value = (_debugLogs.value + logLine).takeLast(100)
}
fun clearLogs() {
_debugLogs.value = emptyList()
}
/**
* Get or create Protocol instance
*/
fun getProtocol(): Protocol {
if (protocol == null) {
Log.d(TAG, "Creating new Protocol instance")
protocol = Protocol(SERVER_ADDRESS)
addLog("Creating new Protocol instance")
addLog("Server: $SERVER_ADDRESS")
protocol = Protocol(SERVER_ADDRESS) { msg -> addLog(msg) }
}
return protocol!!
}
@@ -42,6 +64,7 @@ object ProtocolManager {
* Connect to server
*/
fun connect() {
addLog("Connect requested")
getProtocol().connect()
}
@@ -49,7 +72,9 @@ object ProtocolManager {
* Authenticate with server
*/
fun authenticate(publicKey: String, privateHash: String) {
Log.d(TAG, "Authenticating...")
addLog("Authenticate called")
addLog("PublicKey: ${publicKey.take(30)}...")
addLog("PrivateHash: ${privateHash.take(20)}...")
getProtocol().startHandshake(publicKey, privateHash)
}