mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
AutoSuspend: Make sure we send a LeaveStandby event ASAP (#9173)
Even in corner cases where we're woken up without user input (e.g., rtc alarm). (Followup to #9124)
This commit is contained in:
@@ -145,12 +145,10 @@ function ReaderCoptListener:onResume()
|
||||
end
|
||||
|
||||
self:headerRefresh()
|
||||
self:rescheduleHeaderRefreshIfNeeded()
|
||||
end
|
||||
|
||||
function ReaderCoptListener:onLeaveStandby()
|
||||
self:headerRefresh()
|
||||
self:rescheduleHeaderRefreshIfNeeded()
|
||||
end
|
||||
|
||||
function ReaderCoptListener:onOutOfScreenSaver()
|
||||
@@ -160,7 +158,6 @@ function ReaderCoptListener:onOutOfScreenSaver()
|
||||
|
||||
self._delayed_screensaver = nil
|
||||
self:headerRefresh()
|
||||
self:rescheduleHeaderRefreshIfNeeded()
|
||||
end
|
||||
|
||||
-- Unschedule on these events
|
||||
|
||||
@@ -766,8 +766,9 @@ end
|
||||
|
||||
function ReaderFooter:unscheduleFooterAutoRefresh()
|
||||
if not self.autoRefreshFooter then return end -- not yet set up
|
||||
-- Slightly different wording than in rescheduleFooterAutoRefreshIfNeeded because it might not actually be scheduled at all
|
||||
logger.dbg("ReaderFooter: unschedule autoRefreshFooter")
|
||||
UIManager:unschedule(self.autoRefreshFooter)
|
||||
logger.dbg("ReaderFooter.autoRefreshFooter unscheduled")
|
||||
end
|
||||
|
||||
function ReaderFooter:rescheduleFooterAutoRefreshIfNeeded()
|
||||
@@ -808,12 +809,12 @@ function ReaderFooter:rescheduleFooterAutoRefreshIfNeeded()
|
||||
if schedule then
|
||||
UIManager:scheduleIn(61 - tonumber(os.date("%S")), self.autoRefreshFooter)
|
||||
if not unscheduled then
|
||||
logger.dbg("ReaderFooter.autoRefreshFooter scheduled")
|
||||
logger.dbg("ReaderFooter: scheduled autoRefreshFooter")
|
||||
else
|
||||
logger.dbg("ReaderFooter.autoRefreshFooter rescheduled")
|
||||
logger.dbg("ReaderFooter: rescheduled autoRefreshFooter")
|
||||
end
|
||||
elseif unscheduled then
|
||||
logger.dbg("ReaderFooter.autoRefreshFooter unscheduled")
|
||||
logger.dbg("ReaderFooter: unscheduled autoRefreshFooter")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1659,6 +1659,12 @@ function UIManager:handleInput()
|
||||
-- this function emits (plugin), or within waitEvent() right after (hardware).
|
||||
-- Anywhere else breaks preventStandby/allowStandby invariants used by background jobs while UI is left running.
|
||||
self:_standbyTransition()
|
||||
if self.PM_INPUT_TIMEOUT then
|
||||
-- If the PM state transition requires an early return from input polling, honor that.
|
||||
-- c.f., UIManager:setPMInputTimeout (and AutoSuspend:AllowStandbyHandler).
|
||||
deadline = now + time.s(self.PM_INPUT_TIMEOUT)
|
||||
self.PM_INPUT_TIMEOUT = nil
|
||||
end
|
||||
|
||||
-- wait for next batch of events
|
||||
local input_events = Input:waitEvent(now, deadline)
|
||||
@@ -1841,6 +1847,12 @@ function UIManager:_standbyTransition()
|
||||
self._prev_prevent_standby_count = self._prevent_standby_count
|
||||
end
|
||||
|
||||
-- Used by a PM transition event handler to request an early return from input polling (value in s).
|
||||
-- NOTE: We can't re-use setInputTimeout to avoid interactions with ZMQ...
|
||||
function UIManager:setPMInputTimeout(timeout)
|
||||
self.PM_INPUT_TIMEOUT = timeout
|
||||
end
|
||||
|
||||
--- Broadcasts a `FlushSettings` Event to *all* widgets.
|
||||
function UIManager:flushSettings()
|
||||
self:broadcastEvent(Event:new("FlushSettings"))
|
||||
|
||||
@@ -204,12 +204,6 @@ function AutoSuspend:_unschedule_standby()
|
||||
end
|
||||
|
||||
-- Make sure we don't trigger a ghost LeaveStandby event...
|
||||
if self.wrapped_leave_standby_task then
|
||||
logger.dbg("AutoSuspend: unschedule leave standby task wrapper")
|
||||
UIManager:unschedule(self.wrapped_leave_standby_task)
|
||||
self.wrapped_leave_standby_task = nil
|
||||
end
|
||||
|
||||
if self.leave_standby_task then
|
||||
logger.dbg("AutoSuspend: unschedule leave standby task")
|
||||
UIManager:unschedule(self.leave_standby_task)
|
||||
@@ -338,8 +332,6 @@ end
|
||||
|
||||
function AutoSuspend:onLeaveStandby()
|
||||
logger.dbg("AutoSuspend: onLeaveStandby")
|
||||
-- If the Event got through, tickAfterNext did its thing, clear the reference to the initial nextTick wrapper...
|
||||
self.wrapped_leave_standby_task = nil
|
||||
-- Unschedule suspend and shutdown, as the realtime clock has ticked
|
||||
self:_unschedule()
|
||||
-- Reschedule suspend and shutdown (we'll recompute the delay based on the last user input, *not* the current time).
|
||||
@@ -599,8 +591,21 @@ function AutoSuspend:AllowStandbyHandler()
|
||||
-- to make sure UIManager will consume the input events that woke us up first
|
||||
-- (in case we were woken up by user input, as opposed to an rtc wake alarm)!
|
||||
-- (This ensures we'll use an up to date last_action_time, and that it only ever gets updated from *user* input).
|
||||
-- NOTE: UIManager consumes scheduled tasks before input events, which is why we can't use nextTick.
|
||||
self.wrapped_leave_standby_task = UIManager:tickAfterNext(self.leave_standby_task)
|
||||
-- NOTE: While UIManager consumes scheduled tasks before input events, we do *NOT* have to rely on tickAfterNext,
|
||||
-- solely because of where we run inside an UI frame (via UIManager:_standbyTransition):
|
||||
-- we're neither a scheduled task nor an input event, we run *between* scheduled tasks and input polling.
|
||||
-- That means we go straight to input polling when returning, *without* a trip through the task queue
|
||||
-- (c.f., UIManager:_checkTasks in UIManager:handleInput).
|
||||
UIManager:nextTick(self.leave_standby_task)
|
||||
|
||||
-- Since we go straight to input polling, and that our time spent in standby won't have affected the already computed
|
||||
-- input polling deadline (because MONOTONIC doesn't tick during standby/suspend),
|
||||
-- tweak said deadline to make sure poll will return immediately, so we get a chance to run through the task queue ASAP.
|
||||
-- This ensures we get a LeaveStandby event in a timely fashion,
|
||||
-- even when there isn't actually any user input happening (e.g., woken up by the rtc alarm).
|
||||
-- This shouldn't prevent us from actually consuming any pending input events first,
|
||||
-- because if we were woken up by user input, those events should already be in the evdev queue...
|
||||
UIManager:setPMInputTimeout(0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user