Add android stats channel
This commit is contained in:
@@ -49,6 +49,7 @@ class MainActivity : FlutterFragmentActivity(), ServiceConnection.Callback {
|
|||||||
flutterEngine.plugins.add(EventHandler())
|
flutterEngine.plugins.add(EventHandler())
|
||||||
flutterEngine.plugins.add(LogHandler())
|
flutterEngine.plugins.add(LogHandler())
|
||||||
flutterEngine.plugins.add(GroupsChannel(lifecycleScope))
|
flutterEngine.plugins.add(GroupsChannel(lifecycleScope))
|
||||||
|
flutterEngine.plugins.add(StatsChannel(lifecycleScope))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reconnect() {
|
fun reconnect() {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -149,8 +149,17 @@ class PlatformSingboxService with InfraLogger implements SingboxService {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<SingboxStats> watchStats() {
|
Stream<SingboxStats> watchStats() {
|
||||||
// TODO: implement watchStats
|
const channel = EventChannel("com.hiddify.app/stats", JSONMethodCodec());
|
||||||
return const Stream.empty();
|
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
|
@override
|
||||||
|
|||||||
Reference in New Issue
Block a user