From 11c7b4a86664fb5867bb76ae901ed264a7096436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 22 Feb 2024 21:20:23 +0800 Subject: [PATCH] Handle Windows power events --- route/router.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/route/router.go b/route/router.go index 3f5d2f40..fa602989 100644 --- a/route/router.go +++ b/route/router.go @@ -8,6 +8,7 @@ import ( "net/url" "os" "os/user" + "runtime" "strings" "time" @@ -42,6 +43,7 @@ import ( serviceNTP "github.com/sagernet/sing/common/ntp" "github.com/sagernet/sing/common/task" "github.com/sagernet/sing/common/uot" + "github.com/sagernet/sing/common/winpowrprof" "github.com/sagernet/sing/service" "github.com/sagernet/sing/service/pause" ) @@ -85,6 +87,7 @@ type Router struct { networkMonitor tun.NetworkUpdateMonitor interfaceMonitor tun.DefaultInterfaceMonitor packageManager tun.PackageManager + powerListener winpowrprof.EventListener processSearcher process.Searcher timeService *ntp.Service pauseManager pause.Manager @@ -321,6 +324,14 @@ func NewRouter( router.interfaceMonitor = interfaceMonitor } + if runtime.GOOS == "windows" { + powerListener, err := winpowrprof.NewEventListener(router.notifyWindowsPowerEvent) + if err != nil { + return nil, E.Cause(err, "initialize power listener") + } + router.powerListener = powerListener + } + if ntpOptions.Enabled { timeService, err := ntp.NewService(ctx, router, logFactory.NewLogger("ntp"), ntpOptions) if err != nil { @@ -560,6 +571,16 @@ func (r *Router) Start() error { } } } + + if r.powerListener != nil { + monitor.Start("start power listener") + err := r.powerListener.Start() + monitor.Finish() + if err != nil { + return E.Cause(err, "start power listener") + } + } + if (needWIFIStateFromRuleSet || r.needWIFIState) && r.platformInterface != nil { monitor.Start("initialize WIFI state") r.needWIFIState = true @@ -657,6 +678,13 @@ func (r *Router) Close() error { }) monitor.Finish() } + if r.powerListener != nil { + monitor.Start("close power listener") + err = E.Append(err, r.powerListener.Close(), func(err error) error { + return E.Cause(err, "close power listener") + }) + monitor.Finish() + } if r.timeService != nil { monitor.Start("close time service") err = E.Append(err, r.timeService.Close(), func(err error) error { @@ -1189,3 +1217,19 @@ func (r *Router) updateWIFIState() { } } } + +func (r *Router) notifyWindowsPowerEvent(event int) { + switch event { + case winpowrprof.EVENT_SUSPEND: + r.pauseManager.DevicePause() + _ = r.ResetNetwork() + case winpowrprof.EVENT_RESUME: + if !r.pauseManager.IsDevicePaused() { + return + } + fallthrough + case winpowrprof.EVENT_RESUME_AUTOMATIC: + r.pauseManager.DeviceWake() + _ = r.ResetNetwork() + } +}