diff --git a/constant/os_not_tvos.go b/constant/os_not_tvos.go new file mode 100644 index 00000000..7a41ac35 --- /dev/null +++ b/constant/os_not_tvos.go @@ -0,0 +1,5 @@ +//go:build !(ios && tvos) + +package constant + +const IsTvOS = false diff --git a/constant/os_tvos.go b/constant/os_tvos.go new file mode 100644 index 00000000..bacacf44 --- /dev/null +++ b/constant/os_tvos.go @@ -0,0 +1,5 @@ +//go:build ios && tvos + +package constant + +const IsTvOS = true diff --git a/experimental/libbox/command_server.go b/experimental/libbox/command_server.go index a5bd032e..5dd456da 100644 --- a/experimental/libbox/command_server.go +++ b/experimental/libbox/command_server.go @@ -39,14 +39,8 @@ type CommandServer struct { oomRecorder *oomkiller.Recorder grpcServer *grpc.Server listener net.Listener - endPauseTimer *time.Timer - sleepAt time.Time } -// iOS wakes the extension for every push and background task; in collected power reports -// most sleeps last under two minutes and none exceeded ten. -const closeIdleConnectionsAfterSleep = 2 * time.Minute - type CommandServerHandler interface { ServiceStop() error ServiceReload() error @@ -198,9 +192,6 @@ func (s *CommandServer) Start() error { } func (s *CommandServer) Close() { - if s.endPauseTimer != nil { - s.endPauseTimer.Stop() - } if s.grpcServer != nil { s.grpcServer.Stop() } @@ -260,31 +251,32 @@ func (s *CommandServer) NeedFindProcess() bool { return instance.Box().Router().NeedFindProcess() } +// iOS wakes the extension for every push and background task, so wake is ignored there and +// the pause ends on the screen state instead. func (s *CommandServer) Pause() { - s.sleepAt = time.Now().Round(0) recorder := s.powerManager.Recorder() if recorder != nil { recorder.RecordDeviceSleep() } - instance := s.StartedService.Instance() - if instance == nil || instance.PauseManager() == nil { + if !(C.IsAndroid || C.IsIos) || C.IsTvOS { return } - instance.PauseManager().DevicePause() - if C.IsIos { - // iOS calls wake within seconds of sleep while the device stays locked, so wake is - // ignored and the pause ends one minute after the last sleep instead. Go timers on - // darwin run on CLOCK_UPTIME_RAW, which does not advance while the device sleeps, - // so the minute counts awake time only and never expires inside a sleep. - if s.endPauseTimer == nil { - s.endPauseTimer = time.AfterFunc(time.Minute, s.endDevicePause) - } else { - s.endPauseTimer.Reset(time.Minute) - } + instance := s.StartedService.Instance() + if instance == nil || instance.Box() == nil || instance.PauseManager() == nil { + return } + instance.Box().CloseIdleConnections() + instance.PauseManager().DevicePause() } -func (s *CommandServer) endDevicePause() { +func (s *CommandServer) Wake() { + recorder := s.powerManager.Recorder() + if recorder != nil { + recorder.RecordDeviceWake() + } + if !C.IsAndroid { + return + } instance := s.StartedService.Instance() if instance == nil || instance.PauseManager() == nil { return @@ -292,21 +284,18 @@ func (s *CommandServer) endDevicePause() { instance.PauseManager().DeviceWake() } -func (s *CommandServer) Wake() { - wakeAt := time.Now().Round(0) - recorder := s.powerManager.Recorder() - if recorder != nil { - recorder.RecordDeviceWake() - } +func (s *CommandServer) WakeNow() { instance := s.StartedService.Instance() - if instance == nil || instance.Box() == nil || instance.PauseManager() == nil { + if instance == nil || instance.PauseManager() == nil { return } - if !s.sleepAt.IsZero() && wakeAt.Sub(s.sleepAt) >= closeIdleConnectionsAfterSleep { - instance.Box().CloseIdleConnections() - } - if !C.IsIos { - instance.PauseManager().DeviceWake() + instance.PauseManager().DeviceWake() +} + +func (s *CommandServer) RecordScreenState(on bool) { + recorder := s.powerManager.Recorder() + if recorder != nil { + recorder.RecordScreenState(on) } } diff --git a/service/powerreport/record.go b/service/powerreport/record.go index 4dd5f939..06c4e085 100644 --- a/service/powerreport/record.go +++ b/service/powerreport/record.go @@ -113,6 +113,8 @@ const ( eventTypeNetworkWake = "network-wake" eventTypeSleep = "ne-sleep" eventTypeWake = "ne-wake" + eventTypeScreenOn = "screen-on" + eventTypeScreenOff = "screen-off" eventTypeService = "service" ) diff --git a/service/powerreport/recorder.go b/service/powerreport/recorder.go index 06bbdaac..abe8be95 100644 --- a/service/powerreport/recorder.go +++ b/service/powerreport/recorder.go @@ -342,6 +342,14 @@ func (r *Recorder) RecordPauseEvent(event int) { } } +func (r *Recorder) RecordScreenState(on bool) { + if on { + r.recordPlatformEvent(eventTypeScreenOn) + } else { + r.recordPlatformEvent(eventTypeScreenOff) + } +} + func (r *Recorder) CountConnectionOpened() { r.connectionsOpened.Add(1) }