Skip to content

Commit

Permalink
Add android stats channel
Browse files Browse the repository at this point in the history
  • Loading branch information
problematicconsumer committed Dec 14, 2023
1 parent 5ba0784 commit b9f1e83
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class MainActivity : FlutterFragmentActivity(), ServiceConnection.Callback {
flutterEngine.plugins.add(EventHandler())
flutterEngine.plugins.add(LogHandler())
flutterEngine.plugins.add(GroupsChannel(lifecycleScope))
flutterEngine.plugins.add(StatsChannel(lifecycleScope))
}

fun reconnect() {
Expand Down
64 changes: 64 additions & 0 deletions android/app/src/main/kotlin/com/hiddify/hiddify/StatsChannel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.hiddify.hiddify

import android.util.Log
import com.hiddify.hiddify.utils.CommandClient
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.JSONMethodCodec
import io.nekohasekai.libbox.StatusMessage
import kotlinx.coroutines.CoroutineScope

class StatsChannel(private val scope: CoroutineScope) : FlutterPlugin, CommandClient.Handler{
companion object {
const val TAG = "A/StatsChannel"
const val STATS_CHANNEL = "com.hiddify.app/stats"
}

private val commandClient =
CommandClient(scope, CommandClient.ConnectionType.Status, this)

private var statsChannel: EventChannel? = null
private var statsEvent: EventChannel.EventSink? = null

override fun updateStatus(status: StatusMessage) {
MainActivity.instance.runOnUiThread {
val map = listOf(
Pair("connections-in", status.connectionsIn),
Pair("connections-out", status.connectionsOut),
Pair("uplink", status.uplink),
Pair("downlink", status.downlink),
Pair("uplink-total", status.uplinkTotal),
Pair("downlink-total", status.downlinkTotal)
).associate { it.first to it.second }
statsEvent?.success(map)
}
}

override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
statsChannel = EventChannel(
flutterPluginBinding.binaryMessenger,
STATS_CHANNEL,
JSONMethodCodec.INSTANCE
)

statsChannel!!.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
statsEvent = events
Log.d(TAG, "connecting stats command client")
commandClient.connect()
}

override fun onCancel(arguments: Any?) {
statsEvent = null
Log.d(TAG, "disconnecting stats command client")
commandClient.disconnect()
}
})
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
statsEvent = null
commandClient.disconnect()
statsChannel?.setStreamHandler(null)
}
}
13 changes: 11 additions & 2 deletions lib/singbox/service/platform_singbox_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,17 @@ class PlatformSingboxService with InfraLogger implements SingboxService {

@override
Stream<SingboxStats> watchStats() {
// TODO: implement watchStats
return const Stream.empty();
const channel = EventChannel("com.hiddify.app/stats", JSONMethodCodec());
loggy.debug("watching stats");
return channel.receiveBroadcastStream().map(
(event) {
if (event case Map<String, dynamic> _) {
return SingboxStats.fromJson(event);
}
loggy.error("[stats client] unexpected type, msg: $event");
throw "invalid type";
},
);
}

@override
Expand Down

0 comments on commit b9f1e83

Please sign in to comment.