2017-06-23 17:04:11 +00:00
|
|
|
local Device = require("device")
|
|
|
|
|
2020-10-17 10:59:24 +00:00
|
|
|
if not Device:isCervantes() and
|
|
|
|
not Device:isKobo() and
|
|
|
|
not Device:isRemarkable() and
|
|
|
|
not Device:isSDL() and
|
|
|
|
not Device:isSonyPRSTUX() and
|
|
|
|
not Device:isPocketBook() then
|
2018-10-31 22:48:36 +00:00
|
|
|
return { disabled = true, }
|
|
|
|
end
|
2017-06-23 17:04:11 +00:00
|
|
|
|
|
|
|
local DataStorage = require("datastorage")
|
|
|
|
local LuaSettings = require("luasettings")
|
2017-06-27 04:39:23 +00:00
|
|
|
local PluginShare = require("pluginshare")
|
2017-06-23 17:04:11 +00:00
|
|
|
local UIManager = require("ui/uimanager")
|
|
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
|
|
|
local logger = require("logger")
|
|
|
|
local _ = require("gettext")
|
2019-09-12 12:15:08 +00:00
|
|
|
local T = require("ffi/util").template
|
2017-06-23 17:04:11 +00:00
|
|
|
|
2019-09-12 12:15:08 +00:00
|
|
|
local default_autoshutdown_timeout_seconds = 3*24*60*60
|
|
|
|
|
|
|
|
local AutoSuspend = WidgetContainer:new{
|
|
|
|
name = "autosuspend",
|
|
|
|
is_doc_only = false,
|
2019-09-14 13:52:53 +00:00
|
|
|
autoshutdown_timeout_seconds = G_reader_settings:readSetting("autoshutdown_timeout_seconds") or default_autoshutdown_timeout_seconds,
|
2017-06-23 17:04:11 +00:00
|
|
|
settings = LuaSettings:open(DataStorage:getSettingsDir() .. "/koboautosuspend.lua"),
|
|
|
|
last_action_sec = os.time(),
|
2020-10-17 10:59:24 +00:00
|
|
|
standby_prevented = false,
|
2017-06-23 17:04:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function AutoSuspend:_readTimeoutSecFrom(settings)
|
|
|
|
local sec = settings:readSetting("auto_suspend_timeout_seconds")
|
|
|
|
if type(sec) == "number" then
|
|
|
|
return sec
|
|
|
|
end
|
|
|
|
return -1
|
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:_readTimeoutSec()
|
|
|
|
local candidates = { self.settings, G_reader_settings }
|
|
|
|
for _, candidate in ipairs(candidates) do
|
|
|
|
local sec = self:_readTimeoutSecFrom(candidate)
|
|
|
|
if sec ~= -1 then
|
|
|
|
return sec
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- default setting is 60 minutes
|
|
|
|
return 60 * 60
|
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:_enabled()
|
|
|
|
return self.auto_suspend_sec > 0
|
|
|
|
end
|
|
|
|
|
2019-09-12 12:15:08 +00:00
|
|
|
function AutoSuspend:_enabledShutdown()
|
2019-09-14 13:52:53 +00:00
|
|
|
return Device:canPowerOff() and self.autoshutdown_timeout_seconds > 0
|
2019-09-12 12:15:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:_schedule()
|
2017-06-23 17:04:11 +00:00
|
|
|
if not self:_enabled() then
|
|
|
|
logger.dbg("AutoSuspend:_schedule is disabled")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2019-09-12 12:15:08 +00:00
|
|
|
local delay_suspend, delay_shutdown
|
2017-06-27 04:39:23 +00:00
|
|
|
|
2020-10-17 10:59:24 +00:00
|
|
|
if PluginShare.pause_auto_suspend or Device.standby_prevented or Device.powerd:isCharging() then
|
2019-09-12 12:15:08 +00:00
|
|
|
delay_suspend = self.auto_suspend_sec
|
2019-09-14 13:52:53 +00:00
|
|
|
delay_shutdown = self.autoshutdown_timeout_seconds
|
2017-06-27 04:39:23 +00:00
|
|
|
else
|
2020-10-18 18:38:17 +00:00
|
|
|
local now_ts = os.time()
|
|
|
|
delay_suspend = self.last_action_sec + self.auto_suspend_sec - now_ts
|
|
|
|
delay_shutdown = self.last_action_sec + self.autoshutdown_timeout_seconds - now_ts
|
2017-06-27 04:39:23 +00:00
|
|
|
end
|
|
|
|
|
2020-10-17 10:59:24 +00:00
|
|
|
-- Try to shutdown first, as we may have been woken up from suspend just for the sole purpose of doing that.
|
|
|
|
if delay_shutdown <= 0 then
|
2019-09-12 12:15:08 +00:00
|
|
|
logger.dbg("AutoSuspend: initiating shutdown")
|
|
|
|
UIManager:poweroff_action()
|
2020-10-17 10:59:24 +00:00
|
|
|
elseif delay_suspend <= 0 then
|
|
|
|
logger.dbg("AutoSuspend: will suspend the device")
|
|
|
|
UIManager:suspend()
|
2017-06-23 17:04:11 +00:00
|
|
|
else
|
2019-09-12 12:15:08 +00:00
|
|
|
if self:_enabled() then
|
2020-10-18 18:38:17 +00:00
|
|
|
logger.dbg("AutoSuspend: schedule suspend in", delay_suspend)
|
2019-09-12 12:15:08 +00:00
|
|
|
UIManager:scheduleIn(delay_suspend, self._schedule, self)
|
|
|
|
end
|
|
|
|
if self:_enabledShutdown() then
|
2020-10-18 18:38:17 +00:00
|
|
|
logger.dbg("AutoSuspend: schedule shutdown in", delay_shutdown)
|
2019-09-12 12:15:08 +00:00
|
|
|
UIManager:scheduleIn(delay_shutdown, self._schedule, self)
|
|
|
|
end
|
2017-06-23 17:04:11 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-09-12 12:15:08 +00:00
|
|
|
function AutoSuspend:_unschedule()
|
|
|
|
logger.dbg("AutoSuspend: unschedule")
|
|
|
|
UIManager:unschedule(self._schedule)
|
2017-06-23 17:04:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:_start()
|
2019-09-12 12:15:08 +00:00
|
|
|
if self:_enabled() or self:_enabledShutdown() then
|
2020-10-18 18:38:17 +00:00
|
|
|
local now_ts = os.time()
|
|
|
|
logger.dbg("AutoSuspend: start at", now_ts)
|
|
|
|
self.last_action_sec = now_ts
|
2019-09-12 12:15:08 +00:00
|
|
|
self:_schedule()
|
2017-06-23 17:04:11 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:init()
|
2020-10-17 10:59:24 +00:00
|
|
|
if Device:isPocketBook() and not Device:canSuspend() then return end
|
2017-06-23 17:04:11 +00:00
|
|
|
UIManager.event_hook:registerWidget("InputEvent", self)
|
|
|
|
self.auto_suspend_sec = self:_readTimeoutSec()
|
2019-09-12 12:15:08 +00:00
|
|
|
self:_unschedule()
|
2017-06-23 17:04:11 +00:00
|
|
|
self:_start()
|
2019-09-12 12:15:08 +00:00
|
|
|
-- self.ui is nil in the testsuite
|
|
|
|
if not self.ui or not self.ui.menu then return end
|
|
|
|
self.ui.menu:registerToMainMenu(self)
|
2017-06-23 17:04:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:onInputEvent()
|
|
|
|
logger.dbg("AutoSuspend: onInputEvent")
|
|
|
|
self.last_action_sec = os.time()
|
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:onSuspend()
|
|
|
|
logger.dbg("AutoSuspend: onSuspend")
|
2019-09-12 12:15:08 +00:00
|
|
|
-- We do not want auto suspend procedure to waste battery during suspend. So let's unschedule it
|
|
|
|
-- when suspending and restart it after resume.
|
|
|
|
self:_unschedule()
|
|
|
|
if self:_enabledShutdown() and Device.wakeup_mgr then
|
2019-09-14 13:52:53 +00:00
|
|
|
Device.wakeup_mgr:addTask(self.autoshutdown_timeout_seconds, UIManager.poweroff_action)
|
2019-09-12 12:15:08 +00:00
|
|
|
end
|
2017-06-23 17:04:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:onResume()
|
|
|
|
logger.dbg("AutoSuspend: onResume")
|
2019-10-17 21:31:30 +00:00
|
|
|
if self:_enabledShutdown() and Device.wakeup_mgr then
|
|
|
|
Device.wakeup_mgr:removeTask(nil, nil, UIManager.poweroff_action)
|
|
|
|
end
|
2017-06-23 17:04:11 +00:00
|
|
|
self:_start()
|
|
|
|
end
|
|
|
|
|
2020-10-17 10:59:24 +00:00
|
|
|
function AutoSuspend:onAllowStandby()
|
|
|
|
self.standby_prevented = false
|
|
|
|
end
|
|
|
|
|
|
|
|
function AutoSuspend:onPreventStandby()
|
|
|
|
self.standby_prevented = true
|
|
|
|
end
|
|
|
|
|
2019-09-12 12:15:08 +00:00
|
|
|
function AutoSuspend:addToMainMenu(menu_items)
|
2019-03-27 15:46:22 +00:00
|
|
|
menu_items.autosuspend = {
|
2020-10-09 05:40:23 +00:00
|
|
|
sorting_hint = "device",
|
2019-03-27 15:46:22 +00:00
|
|
|
text = _("Autosuspend timeout"),
|
|
|
|
callback = function()
|
|
|
|
local InfoMessage = require("ui/widget/infomessage")
|
|
|
|
local Screen = Device.screen
|
|
|
|
local SpinWidget = require("ui/widget/spinwidget")
|
|
|
|
local curr_items = G_reader_settings:readSetting("auto_suspend_timeout_seconds") or 60*60
|
|
|
|
local autosuspend_spin = SpinWidget:new {
|
2020-06-12 23:56:36 +00:00
|
|
|
width = math.floor(Screen:getWidth() * 0.6),
|
2019-03-27 15:46:22 +00:00
|
|
|
value = curr_items / 60,
|
|
|
|
value_min = 5,
|
|
|
|
value_max = 240,
|
|
|
|
value_hold_step = 15,
|
|
|
|
ok_text = _("Set timeout"),
|
|
|
|
title_text = _("Timeout in minutes"),
|
|
|
|
callback = function(autosuspend_spin)
|
2019-09-12 12:15:08 +00:00
|
|
|
local autosuspend_timeout_seconds = autosuspend_spin.value * 60
|
|
|
|
self.auto_suspend_sec = autosuspend_timeout_seconds
|
|
|
|
G_reader_settings:saveSetting("auto_suspend_timeout_seconds", autosuspend_timeout_seconds)
|
2019-03-27 15:46:22 +00:00
|
|
|
UIManager:show(InfoMessage:new{
|
2019-09-12 12:15:08 +00:00
|
|
|
text = T(_("The system will automatically suspend after %1 minutes of inactivity."),
|
|
|
|
string.format("%.2f", autosuspend_timeout_seconds/60)),
|
|
|
|
timeout = 3,
|
2019-03-27 15:46:22 +00:00
|
|
|
})
|
2019-09-12 12:15:08 +00:00
|
|
|
self:_unschedule()
|
|
|
|
self:_start()
|
|
|
|
end
|
|
|
|
}
|
|
|
|
UIManager:show(autosuspend_spin)
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
if not (Device:canPowerOff() or Device:isEmulator()) then return end
|
|
|
|
menu_items.autoshutdown = {
|
2020-10-17 10:59:24 +00:00
|
|
|
sorting_hint = "device",
|
2019-09-12 12:15:08 +00:00
|
|
|
text = _("Autoshutdown timeout"),
|
|
|
|
callback = function()
|
|
|
|
local InfoMessage = require("ui/widget/infomessage")
|
|
|
|
local Screen = Device.screen
|
|
|
|
local SpinWidget = require("ui/widget/spinwidget")
|
2019-09-14 13:52:53 +00:00
|
|
|
local curr_items = self.autoshutdown_timeout_seconds
|
2019-09-12 12:15:08 +00:00
|
|
|
local autosuspend_spin = SpinWidget:new {
|
2020-06-12 23:56:36 +00:00
|
|
|
width = math.floor(Screen:getWidth() * 0.6),
|
2019-09-12 12:15:08 +00:00
|
|
|
value = curr_items / 60 / 60,
|
|
|
|
-- About a minute, good for testing and battery life fanatics.
|
|
|
|
-- Just high enough to avoid an instant shutdown death scenario.
|
|
|
|
value_min = 0.017,
|
|
|
|
-- More than three weeks seems a bit excessive if you want to enable authoshutdown,
|
|
|
|
-- even if the battery can last up to three months.
|
|
|
|
value_max = 28*24,
|
|
|
|
value_hold_step = 24,
|
|
|
|
precision = "%.2f",
|
|
|
|
ok_text = _("Set timeout"),
|
|
|
|
title_text = _("Timeout in hours"),
|
|
|
|
callback = function(autosuspend_spin)
|
|
|
|
local autoshutdown_timeout_seconds = math.floor(autosuspend_spin.value * 60*60)
|
|
|
|
self.autoshutdown_timeout_seconds = autoshutdown_timeout_seconds
|
|
|
|
G_reader_settings:saveSetting("autoshutdown_timeout_seconds", autoshutdown_timeout_seconds)
|
|
|
|
UIManager:show(InfoMessage:new{
|
|
|
|
text = T(_("The system will automatically shut down after %1 hours of inactivity."),
|
|
|
|
string.format("%.2f", autoshutdown_timeout_seconds/60/60)),
|
|
|
|
timeout = 3,
|
|
|
|
})
|
|
|
|
self:_unschedule()
|
|
|
|
self:_start()
|
2019-03-27 15:46:22 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
UIManager:show(autosuspend_spin)
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-09-12 12:15:08 +00:00
|
|
|
return AutoSuspend
|