diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt index fe2a126..f0c63e3 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt @@ -52,6 +52,16 @@ class BaseService { Intent.ACTION_SHUTDOWN -> service.persistStats() Action.RELOAD -> service.reload() // Action.SWITCH_WAKE_LOCK -> runOnDefaultDispatcher { service.switchWakeLock() } + PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (SagerNet.power.isDeviceIdleMode) { + proxy?.box?.sleep() + } else { + proxy?.box?.wake() + } + } + } + Action.RESET_UPSTREAM_CONNECTIONS -> runOnDefaultDispatcher { LibcoreUtil.resetAllConnections(true) runOnMainDispatcher { @@ -323,6 +333,9 @@ class BaseService { addAction(Intent.ACTION_SHUTDOWN) addAction(Action.CLOSE) // addAction(Action.SWITCH_WAKE_LOCK) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED) + } addAction(Action.RESET_UPSTREAM_CONNECTIONS) }, "$packageName.SERVICE", null) data.closeReceiverRegistered = true diff --git a/libcore/box.go b/libcore/box.go index 3d77df1..5e2114a 100644 --- a/libcore/box.go +++ b/libcore/box.go @@ -22,6 +22,7 @@ import ( "github.com/sagernet/sing-box/common/dialer/conntrack" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/outbound" + "github.com/sagernet/sing/service/pause" ) var mainInstance *BoxInstance @@ -62,8 +63,9 @@ type BoxInstance struct { cancel context.CancelFunc state int - v2api *boxapi.SbV2rayServer - selector *outbound.Selector + v2api *boxapi.SbV2rayServer + selector *outbound.Selector + pauseManager pause.Manager ForTest bool } @@ -80,6 +82,8 @@ func NewSingBoxInstance(config string) (b *BoxInstance, err error) { // create box ctx, cancel := context.WithCancel(context.Background()) + sleepManager := pause.NewDefaultManager(ctx) + ctx = pause.ContextWithManager(ctx, sleepManager) instance, err := boxbox.New(boxbox.Options{ Options: options, Context: ctx, @@ -91,8 +95,9 @@ func NewSingBoxInstance(config string) (b *BoxInstance, err error) { } b = &BoxInstance{ - Box: instance, - cancel: cancel, + Box: instance, + cancel: cancel, + pauseManager: sleepManager, } // fuck your sing-box platformFormatter @@ -145,6 +150,15 @@ func (b *BoxInstance) Close() (err error) { return nil } +func (b *BoxInstance) Sleep() { + b.pauseManager.DevicePause() + _ = b.Box.Router().ResetNetwork() +} + +func (b *BoxInstance) Wake() { + b.pauseManager.DeviceWake() +} + func (b *BoxInstance) SetAsMain() { mainInstance = b goServeProtect(true)