AutoSuspend: Some more fixes & cleanups (#9263)

* AutoSuspend: Use the canSuspend devcap check instead of reinventing the wheel.
* Device & UIManager: Cleanup canSuspend devcap check related stuff to avoid boilerplate code.
  (It also now defaults to no, and is explicitly set by device implementations where supported).
* AutoSuspend: Re-engage suspend/shutdown timers when fully charged.
  This restores the existing behavior pre #9036
  (c.f., https://github.com/koreader/koreader/pull/9258#issuecomment-1167672356)
* SDL: Unbreak the fake suspend behavior so that it actually works.
  Tweak the default screensaver message to remind users that Power is bound to F2.
  (Fix #9262)
* AutoSuspend: Re-engage suspend/shutdown timers on unplug.
  This matters on Kobo, because the unexpected wakeup guard might have stopped the suspend timer.
pull/9289/head
NiLuJe 2 years ago committed by GitHub
parent 3a4af5e35e
commit c506d8b0ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -48,6 +48,7 @@ local Cervantes = Generic:new{
hasWifiManager = yes, hasWifiManager = yes,
canReboot = yes, canReboot = yes,
canPowerOff = yes, canPowerOff = yes,
canSuspend = yes,
home_dir = "/mnt/public", home_dir = "/mnt/public",
-- do we support usb mass storage? -- do we support usb mass storage?

@ -68,7 +68,7 @@ local Device = {
canToggleChargingLED = no, canToggleChargingLED = no,
canUseWAL = yes, -- requires mmap'ed I/O on the target FS canUseWAL = yes, -- requires mmap'ed I/O on the target FS
canRestart = yes, canRestart = yes,
canSuspend = yes, canSuspend = no,
canStandby = no, canStandby = no,
canPowerSaveWhileCharging = no, canPowerSaveWhileCharging = no,
total_standby_time = 0, -- total time spent in standby total_standby_time = 0, -- total time spent in standby

@ -133,6 +133,8 @@ local Kindle = Generic:new{
canModifyFBInfo = yes, canModifyFBInfo = yes,
-- NOTE: Newer devices will turn the frontlight off at 0 -- NOTE: Newer devices will turn the frontlight off at 0
canTurnFrontlightOff = yes, canTurnFrontlightOff = yes,
-- NOTE: Via powerd.toggleSuspend
canSuspend = yes,
home_dir = "/mnt/us", home_dir = "/mnt/us",
-- New devices are REAGL-aware, default to REAGL -- New devices are REAGL-aware, default to REAGL
isREAGL = yes, isREAGL = yes,

@ -72,6 +72,7 @@ local Kobo = Generic:new{
canStandby = no, -- will get updated by checkStandby() canStandby = no, -- will get updated by checkStandby()
canReboot = yes, canReboot = yes,
canPowerOff = yes, canPowerOff = yes,
canSuspend = yes,
-- most Kobos have X/Y switched for the touch screen -- most Kobos have X/Y switched for the touch screen
touch_switch_xy = true, touch_switch_xy = true,
-- most Kobos have also mirrored X coordinates -- most Kobos have also mirrored X coordinates
@ -1076,6 +1077,11 @@ function Kobo:resume()
self:setupChargingLED() self:setupChargingLED()
end end
function Kobo:usbPlugOut()
-- Reset the unexpected wakeup shenanigans, since we're no longer charging, meaning power savings are now critical again ;).
self.unexpected_wakeup_count = 0
end
function Kobo:saveSettings() function Kobo:saveSettings()
-- save frontlight state to G_reader_settings (and NickelConf if needed) -- save frontlight state to G_reader_settings (and NickelConf if needed)
self.powerd:saveSettings() self.powerd:saveSettings()

@ -37,6 +37,7 @@ local Remarkable = Generic:new{
hasOTAUpdates = yes, hasOTAUpdates = yes,
canReboot = yes, canReboot = yes,
canPowerOff = yes, canPowerOff = yes,
canSuspend = yes,
isTouchDevice = yes, isTouchDevice = yes,
hasFrontlight = no, hasFrontlight = no,
hasSystemFonts = yes, hasSystemFonts = yes,

@ -67,7 +67,7 @@ local Device = Generic:new{
hasEinkScreen = no, hasEinkScreen = no,
hasSystemFonts = yes, hasSystemFonts = yes,
canSuspend = no, canSuspend = no,
canStandby = yes, canStandby = no,
startTextInput = SDL.startTextInput, startTextInput = SDL.startTextInput,
stopTextInput = SDL.stopTextInput, stopTextInput = SDL.stopTextInput,
canOpenLink = getLinkOpener, canOpenLink = getLinkOpener,
@ -120,9 +120,12 @@ local Emulator = Device:new{
hasNaturalLightApi = yes, hasNaturalLightApi = yes,
hasWifiToggle = yes, hasWifiToggle = yes,
hasWifiManager = yes, hasWifiManager = yes,
-- Not really, Device:reboot & Device:powerOff are not implemented, so we just exit ;).
canPowerOff = yes, canPowerOff = yes,
canReboot = yes, canReboot = yes,
-- NOTE: Via simulateSuspend
canSuspend = yes, canSuspend = yes,
canStandby = no,
} }
local UbuntuTouch = Device:new{ local UbuntuTouch = Device:new{
@ -337,11 +340,13 @@ function Emulator:simulateSuspend()
local Screensaver = require("ui/screensaver") local Screensaver = require("ui/screensaver")
Screensaver:setup() Screensaver:setup()
Screensaver:show() Screensaver:show()
self.screen_saver_mode = true
end end
function Emulator:simulateResume() function Emulator:simulateResume()
local Screensaver = require("ui/screensaver") local Screensaver = require("ui/screensaver")
Screensaver:close() Screensaver:close()
self.screen_saver_mode = false
end end
-- fake network manager for the emulator -- fake network manager for the emulator

@ -17,6 +17,7 @@ local SonyPRSTUX = Generic:new{
hasWifiManager = yes, hasWifiManager = yes,
canReboot = yes, canReboot = yes,
canPowerOff = yes, canPowerOff = yes,
canSuspend = yes,
usbPluggedIn = false, usbPluggedIn = false,
home_dir = nil, home_dir = nil,
} }

@ -64,6 +64,11 @@ local Screensaver = {
default_screensaver_message = _("Sleeping"), default_screensaver_message = _("Sleeping"),
} }
-- Remind emulator users that Power is bound to F2
if Device:isEmulator() then
Screensaver.default_screensaver_message = Screensaver.default_screensaver_message .. "\n" .. _("(Press F2 to resume)")
end
function Screensaver:_getRandomImage(dir) function Screensaver:_getRandomImage(dir)
if not dir then if not dir then
return nil return nil

@ -173,6 +173,7 @@ function UIManager:init()
self.event_handlers["Light"] = function() self.event_handlers["Light"] = function()
Device:getPowerDevice():toggleFrontlight() Device:getPowerDevice():toggleFrontlight()
end end
-- USB plug events with a power-only charger
self.event_handlers["Charging"] = function() self.event_handlers["Charging"] = function()
self:_beforeCharging() self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep. -- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
@ -182,11 +183,13 @@ function UIManager:init()
end end
self.event_handlers["NotCharging"] = function() self.event_handlers["NotCharging"] = function()
-- We need to put the device into suspension, other things need to be done before it. -- We need to put the device into suspension, other things need to be done before it.
Device:usbPlugOut()
self:_afterNotCharging() self:_afterNotCharging()
if Device.screen_saver_mode then if Device.screen_saver_mode then
self:suspend() self:suspend()
end end
end end
-- USB plug events with a data-aware host
self.event_handlers["UsbPlugIn"] = function() self.event_handlers["UsbPlugIn"] = function()
self:_beforeCharging() self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep. -- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
@ -200,6 +203,7 @@ function UIManager:init()
end end
self.event_handlers["UsbPlugOut"] = function() self.event_handlers["UsbPlugOut"] = function()
-- We need to put the device into suspension, other things need to be done before it. -- We need to put the device into suspension, other things need to be done before it.
Device:usbPlugOut()
self:_afterNotCharging() self:_afterNotCharging()
if Device.screen_saver_mode then if Device.screen_saver_mode then
self:suspend() self:suspend()
@ -382,6 +386,14 @@ function UIManager:init()
Device:simulateResume() Device:simulateResume()
self:_afterResume() self:_afterResume()
end end
self.event_handlers["PowerRelease"] = function()
-- Resume if we were suspended
if Device.screen_saver_mode then
self:resume()
else
self:suspend()
end
end
end end
end end
@ -1782,11 +1794,11 @@ Executes all the operations of a suspension (i.e., sleep) request.
This function usually puts the device into suspension. This function usually puts the device into suspension.
]] ]]
function UIManager:suspend() function UIManager:suspend()
if Device:isCervantes() or Device:isKobo() or Device:isSDL() or Device:isRemarkable() or Device:isSonyPRSTUX() then if self.event_handlers["Suspend"] then
self.event_handlers["Suspend"]() self.event_handlers["Suspend"]()
elseif Device:isKindle() then elseif Device:isKindle() then
Device.powerd:toggleSuspend() Device.powerd:toggleSuspend()
elseif Device.isPocketBook() and Device.canSuspend() then elseif Device:canSuspend() then
Device:suspend() Device:suspend()
end end
end end
@ -1801,7 +1813,7 @@ function UIManager:resume()
-- invalidate the last battery capacity pull time so that we get up to date data immediately. -- invalidate the last battery capacity pull time so that we get up to date data immediately.
Device:getPowerDevice():invalidateCapacityCache() Device:getPowerDevice():invalidateCapacityCache()
if Device:isCervantes() or Device:isKobo() or Device:isSDL() or Device:isRemarkable() or Device:isSonyPRSTUX() then if self.event_handlers["Resume"] then
self.event_handlers["Resume"]() self.event_handlers["Resume"]()
elseif Device:isKindle() then elseif Device:isKindle() then
self.event_handlers["OutOfSS"]() self.event_handlers["OutOfSS"]()

@ -1,12 +1,7 @@
local Device = require("device") local Device = require("device")
if not Device:isCervantes() and -- If a device can power off or go into standby, it can also suspend ;).
not Device:isKindle() and if not Device:canSuspend() then
not Device:isKobo() and
not Device:isRemarkable() and
not Device:isSDL() and
not Device:isSonyPRSTUX() and
not Device:isPocketBook() then
return { disabled = true, } return { disabled = true, }
end end
@ -46,6 +41,7 @@ function AutoSuspend:_enabledStandby()
end end
function AutoSuspend:_enabled() function AutoSuspend:_enabled()
-- NOTE: Plugin is only enabled if Device:canSuspend(), so we can elide the check here
return self.auto_suspend_timeout_seconds > 0 return self.auto_suspend_timeout_seconds > 0
end end
@ -64,10 +60,11 @@ function AutoSuspend:_schedule(shutdown_only)
-- On devices with an auxiliary battery, we only care about the auxiliary battery being charged... -- On devices with an auxiliary battery, we only care about the auxiliary battery being charged...
local powerd = Device:getPowerDevice() local powerd = Device:getPowerDevice()
if Device:hasAuxBattery() and powerd:isAuxBatteryConnected() then if Device:hasAuxBattery() and powerd:isAuxBatteryConnected() then
is_charging = powerd:isAuxCharging() is_charging = powerd:isAuxCharging() and not powerd:isAuxCharged()
else else
is_charging = powerd:isCharging() is_charging = powerd:isCharging() and not powerd:isCharged()
end end
-- We *do* want to make sure we attempt to go into suspend/shutdown again while *fully* charged, though.
if PluginShare.pause_auto_suspend or is_charging then if PluginShare.pause_auto_suspend or is_charging then
suspend_delay_seconds = self.auto_suspend_timeout_seconds suspend_delay_seconds = self.auto_suspend_timeout_seconds
shutdown_delay_seconds = self.autoshutdown_timeout_seconds shutdown_delay_seconds = self.autoshutdown_timeout_seconds
@ -134,8 +131,6 @@ function AutoSuspend:init()
-- Disabled, until the user opts in. -- Disabled, until the user opts in.
self.auto_standby_timeout_seconds = G_reader_settings:readSetting("auto_standby_timeout_seconds", -1) self.auto_standby_timeout_seconds = G_reader_settings:readSetting("auto_standby_timeout_seconds", -1)
if Device:isPocketBook() and not Device:canSuspend() then return end
-- We only want those to exist as *instance* members -- We only want those to exist as *instance* members
self.is_standby_scheduled = false self.is_standby_scheduled = false
self.going_to_suspend = false self.going_to_suspend = false
@ -178,7 +173,6 @@ end
-- NOTE: event_hook takes care of overloading this to unregister the hook, too. -- NOTE: event_hook takes care of overloading this to unregister the hook, too.
function AutoSuspend:onCloseWidget() function AutoSuspend:onCloseWidget()
logger.dbg("AutoSuspend: onCloseWidget") logger.dbg("AutoSuspend: onCloseWidget")
if Device:isPocketBook() and not Device:canSuspend() then return end
self:_unschedule() self:_unschedule()
self.task = nil self.task = nil
@ -346,10 +340,21 @@ end
function AutoSuspend:onUnexpectedWakeupLimit() function AutoSuspend:onUnexpectedWakeupLimit()
logger.dbg("AutoSuspend: onUnexpectedWakeupLimit") logger.dbg("AutoSuspend: onUnexpectedWakeupLimit")
-- Should be unnecessary, because we should *always* follow onSuspend, which already does this...
-- Better safe than sorry, though ;).
self:_unschedule()
-- Only re-engage the *shutdown* schedule to avoid doing the same dance indefinitely. -- Only re-engage the *shutdown* schedule to avoid doing the same dance indefinitely.
self:_restart() self:_restart()
end end
function AutoSuspend:onNotCharging()
logger.dbg("AutoSuspend: onNotCharging")
-- Make sure both the suspend & shutdown timers are re-engaged on unplug,
-- in case we hit an UnexpectedWakeupLimit during the charge cycle...
self:_unschedule()
self:_start()
end
-- time_scale: -- time_scale:
-- 2 ... display day:hour -- 2 ... display day:hour
-- 1 ... display hour:min -- 1 ... display hour:min
@ -464,6 +469,7 @@ function AutoSuspend:pickTimeoutValue(touchmenu_instance, title, info, setting,
end end
function AutoSuspend:addToMainMenu(menu_items) function AutoSuspend:addToMainMenu(menu_items)
-- Device:canSuspend() check elided because it's a plugin requirement
menu_items.autosuspend = { menu_items.autosuspend = {
sorting_hint = "device", sorting_hint = "device",
checked_func = function() checked_func = function()
@ -489,7 +495,7 @@ function AutoSuspend:addToMainMenu(menu_items)
{60, 24*3600}, 1) {60, 24*3600}, 1)
end, end,
} }
if Device:canPowerOff() or Device:isEmulator() then if Device:canPowerOff() then
menu_items.autoshutdown = { menu_items.autoshutdown = {
sorting_hint = "device", sorting_hint = "device",
checked_func = function() checked_func = function()

Loading…
Cancel
Save