[UIManager] Outsource device specific event handlers (was: some nits) (#9448)

reviewable/pr9502/r1
zwim 2 years ago committed by GitHub
parent e051d3d703
commit 6f5c229c90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -209,7 +209,7 @@ function Device:init()
end
elseif ev.code == C.APP_CMD_PAUSE then
if not android.prop.brokenLifecycle then
UIManager:broadcastEvent(Event:new("Suspend"))
UIManager:broadcastEvent(Event:new("RequestSuspend"))
end
elseif ev.code == C.AEVENT_POWER_CONNECTED then
UIManager:broadcastEvent(Event:new("Charging"))

@ -236,6 +236,84 @@ function Cervantes:powerOff()
os.execute("halt")
end
-- This method is the same as the one in kobo/device.lua except the sleep cover part.
function Cervantes:setEventHandlers(UIManager)
-- We do not want auto suspend procedure to waste battery during
-- suspend. So let's unschedule it when suspending, and restart it after
-- resume. Done via the plugin's onSuspend/onResume handlers.
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend()
self:onPowerEvent("Suspend")
end
UIManager.event_handlers["Resume"] = function()
-- MONOTONIC doesn't tick during suspend,
-- invalidate the last battery capacity pull time so that we get up to date data immediately.
self:getPowerDevice():invalidateCapacityCache()
self:onPowerEvent("Resume")
self:_afterResume()
end
UIManager.event_handlers["PowerPress"] = function()
-- Always schedule power off.
-- Press the power button for 2+ seconds to shutdown directly from suspend.
UIManager:scheduleIn(2, UIManager.poweroff_action)
end
UIManager.event_handlers["PowerRelease"] = function()
if not self._entered_poweroff_stage then
UIManager:unschedule(UIManager.poweroff_action)
-- resume if we were suspended
if self.screen_saver_mode then
UIManager.event_handlers["Resume"]()
else
UIManager.event_handlers["Suspend"]()
end
end
end
UIManager.event_handlers["Light"] = function()
self:getPowerDevice():toggleFrontlight()
end
-- USB plug events with a power-only charger
UIManager.event_handlers["Charging"] = function()
self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
end
end
UIManager.event_handlers["NotCharging"] = function()
-- We need to put the device into suspension, other things need to be done before it.
self:usbPlugOut()
self:_afterNotCharging()
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
end
end
-- USB plug events with a data-aware host
UIManager.event_handlers["UsbPlugIn"] = function()
self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
else
-- Potentially start an USBMS session
local MassStorage = require("ui/elements/mass_storage")
MassStorage:start()
end
end
UIManager.event_handlers["UsbPlugOut"] = function()
-- We need to put the device into suspension, other things need to be done before it.
self:usbPlugOut()
self:_afterNotCharging()
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
else
-- Potentially dismiss the USBMS ConfirmBox
local MassStorage = require("ui/elements/mass_storage")
MassStorage:dismiss()
end
end
end
-------------- device probe ------------
local product_id = getProductId()

@ -1,4 +1,3 @@
local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device")
local Event = require("ui/event")
local InputContainer = require("ui/widget/container/inputcontainer")
@ -318,40 +317,24 @@ function DeviceListener:onSwapPageTurnButtons()
Device:invertButtons()
end
if Device:canReboot() then
function DeviceListener:onReboot()
UIManager:show(ConfirmBox:new{
text = _("Are you sure you want to reboot the device?"),
ok_text = _("Reboot"),
ok_callback = function()
UIManager:nextTick(UIManager.reboot_action)
end,
})
end
function DeviceListener:onRestart()
self.ui.menu:exitOrRestart(function() UIManager:restartKOReader() end)
end
if Device:canPowerOff() then
function DeviceListener:onPowerOff()
UIManager:show(ConfirmBox:new{
text = _("Are you sure you want to power off the device?"),
ok_text = _("Power off"),
ok_callback = function()
UIManager:nextTick(UIManager.poweroff_action)
end,
})
end
function DeviceListener:onRequestSuspend()
UIManager:suspend()
end
function DeviceListener:onSuspendEvent()
UIManager:suspend()
function DeviceListener:onRequestReboot()
UIManager:reboot()
end
function DeviceListener:onExit(callback)
self.ui.menu:exitOrRestart(callback)
function DeviceListener:onRequestPowerOff()
UIManager:powerOff()
end
function DeviceListener:onRestart()
self.ui.menu:exitOrRestart(function() UIManager:restartKOReader() end)
function DeviceListener:onExit(callback)
self.ui.menu:exitOrRestart(callback)
end
function DeviceListener:onFullRefresh()

@ -573,4 +573,103 @@ function Device:untar(archive, extract_to)
return os.execute(("./tar xf %q -C %q"):format(archive, extract_to))
end
-- Set device event handlers common to all devices
function Device:_setEventHandlers(UIManager)
if self:canReboot() then
UIManager.event_handlers["Reboot"] = function()
local ConfirmBox = require("ui/widget/confirmbox")
UIManager:show(ConfirmBox:new{
text = _("Are you sure you want to reboot the device?"),
ok_text = _("Reboot"),
ok_callback = function()
local Event = require("ui/event")
UIManager:broadcastEvent(Event:new("Reboot"))
UIManager:nextTick(UIManager.reboot_action)
end,
})
end
else
UIManager.event_handlers["Reboot"] = function() end
end
if self:canPowerOff() then
UIManager.event_handlers["PowerOff"] = function()
local ConfirmBox = require("ui/widget/confirmbox")
UIManager:show(ConfirmBox:new{
text = _("Are you sure you want to power off the device?"),
ok_text = _("Power off"),
ok_callback = function()
local Event = require("ui/event")
UIManager:broadcastEvent(Event:new("PowerOff"))
UIManager:nextTick(UIManager.poweroff_action)
end,
})
end
else
UIManager.event_handlers["PowerOff"] = function() end
end
self:setEventHandlers(UIManager)
end
-- Devices can add additional event handlers by overwriting this method.
function Device:setEventHandlers(UIManager)
-- These will be most probably overwritten in the device specific `setEventHandlers`
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend(false)
end
UIManager.event_handlers["Resume"] = function()
self:_afterResume(false)
end
end
-- The common operations that should be performed before suspending the device.
function Device:_beforeSuspend(inhibit)
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
UIManager:flushSettings()
UIManager:broadcastEvent(Event:new("Suspend"))
if inhibit ~= false then
-- Block input events unrelated to power management
self.input:inhibitInput(true)
-- Disable key repeat to avoid useless chatter (especially where Sleep Covers are concerned...)
self:disableKeyRepeat()
end
end
-- The common operations that should be performed after resuming the device.
function Device:_afterResume(inhibit)
if inhibit ~= false then
-- Restore key repeat
self:restoreKeyRepeat()
-- Restore full input handling
self.input:inhibitInput(false)
end
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
UIManager:broadcastEvent(Event:new("Resume"))
end
-- The common operations that should be performed when the device is plugged to a power source.
function Device:_beforeCharging()
-- Leave the kernel some time to figure it out ;o).
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
UIManager:scheduleIn(1, function() self:setupChargingLED() end)
UIManager:broadcastEvent(Event:new("Charging"))
end
-- The common operations that should be performed when the device is unplugged from a power source.
function Device:_afterNotCharging()
-- Leave the kernel some time to figure it out ;o).
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
UIManager:scheduleIn(1, function() self:setupChargingLED() end)
UIManager:broadcastEvent(Event:new("NotCharging"))
end
return Device

@ -368,6 +368,34 @@ function Kindle:readyToSuspend()
self.suspend_time = time.boottime_or_realtime_coarse()
end
function Kindle:setEventHandlers(UIManager)
UIManager.event_handlers["Suspend"] = function()
self.powerd:toggleSuspend()
end
UIManager.event_handlers["IntoSS"] = function()
self:_beforeSuspend()
self:intoScreenSaver()
end
UIManager.event_handlers["OutOfSS"] = function()
self:outofScreenSaver()
self:_afterResume()
end
UIManager.event_handlers["Charging"] = function()
self:_beforeCharging()
self:usbPlugIn()
end
UIManager.event_handlers["NotCharging"] = function()
self:usbPlugOut()
self:_afterNotCharging()
end
UIManager.event_handlers["WakeupFromSuspend"] = function()
self:wakeupFromSuspend()
end
UIManager.event_handlers["ReadyToSuspend"] = function()
self:readyToSuspend()
end
end
function Kindle:ambientBrightnessLevel()
local haslipc, lipc = pcall(require, "liblipclua")
if not haslipc or lipc == nil then return 0 end

@ -1235,6 +1235,108 @@ function Kobo:isStartupScriptUpToDate()
return md5.sumFile(current_script) == md5.sumFile(new_script)
end
function Kobo:setEventHandlers(UIManager)
-- We do not want auto suspend procedure to waste battery during
-- suspend. So let's unschedule it when suspending, and restart it after
-- resume. Done via the plugin's onSuspend/onResume handlers.
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend()
self:onPowerEvent("Suspend")
end
UIManager.event_handlers["Resume"] = function()
-- MONOTONIC doesn't tick during suspend,
-- invalidate the last battery capacity pull time so that we get up to date data immediately.
self:getPowerDevice():invalidateCapacityCache()
self:onPowerEvent("Resume")
self:_afterResume()
end
UIManager.event_handlers["PowerPress"] = function()
-- Always schedule power off.
-- Press the power button for 2+ seconds to shutdown directly from suspend.
UIManager:scheduleIn(2, UIManager.poweroff_action)
end
UIManager.event_handlers["PowerRelease"] = function()
if not self._entered_poweroff_stage then
UIManager:unschedule(UIManager.poweroff_action)
-- resume if we were suspended
if self.screen_saver_mode then
UIManager.event_handlers["Resume"]()
else
UIManager.event_handlers["Suspend"]()
end
end
end
UIManager.event_handlers["Light"] = function()
self:getPowerDevice():toggleFrontlight()
end
-- USB plug events with a power-only charger
UIManager.event_handlers["Charging"] = function()
self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
end
end
UIManager.event_handlers["NotCharging"] = function()
-- We need to put the device into suspension, other things need to be done before it.
self:usbPlugOut()
self:_afterNotCharging()
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
end
end
-- USB plug events with a data-aware host
UIManager.event_handlers["UsbPlugIn"] = function()
self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
else
-- Potentially start an USBMS session
local MassStorage = require("ui/elements/mass_storage")
MassStorage:start()
end
end
UIManager.event_handlers["UsbPlugOut"] = function()
-- We need to put the device into suspension, other things need to be done before it.
self:usbPlugOut()
self:_afterNotCharging()
if self.screen_saver_mode then
UIManager.event_handlers["Suspend"]()
else
-- Potentially dismiss the USBMS ConfirmBox
local MassStorage = require("ui/elements/mass_storage")
MassStorage:dismiss()
end
end
-- Sleep Cover handling
if G_reader_settings:isTrue("ignore_power_sleepcover") then
-- NOTE: The hardware event itself will wake the kernel up if it's in suspend (:/).
-- Let the unexpected wakeup guard handle that.
UIManager.event_handlers["SleepCoverClosed"] = nil
UIManager.event_handlers["SleepCoverOpened"] = nil
elseif G_reader_settings:isTrue("ignore_open_sleepcover") then
-- Just ignore wakeup events, and do NOT set is_cover_closed,
-- so device/generic/device will let us use the power button to wake ;).
UIManager.event_handlers["SleepCoverClosed"] = function()
UIManager.event_handlers["Suspend"]()
end
UIManager.event_handlers["SleepCoverOpened"] = function()
self.is_cover_closed = false
end
else
UIManager.event_handlers["SleepCoverClosed"] = function()
self.is_cover_closed = true
UIManager.event_handlers["Suspend"]()
end
UIManager.event_handlers["SleepCoverOpened"] = function()
self.is_cover_closed = false
UIManager.event_handlers["Resume"]()
end
end
end
-------------- device probe ------------
local codename = getCodeName()

@ -388,6 +388,16 @@ function PocketBook:getDefaultCoverPath()
return "/mnt/ext1/system/logo/offlogo/cover.bmp"
end
function PocketBook:setEventHandlers(UIManager)
-- Only fg/bg state plugin notifiers, not real power event.
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend()
end
UIManager.event_handlers["Resume"] = function()
self:_afterResume()
end
end
-- Pocketbook HW rotation modes start from landsape, CCW
local function landscape_ccw() return {
1, 0, 3, 2, -- PORTRAIT, LANDSCAPE, PORTRAIT_180, LANDSCAPE_180
@ -619,7 +629,6 @@ local PocketBook741 = PocketBook:new{
usingForcedRotation = landscape_ccw,
}
function PocketBook741._fb_init(fb, finfo, vinfo)
-- Pocketbook Color Lux reports bits_per_pixel = 8, but actually uses an RGB24 framebuffer
vinfo.bits_per_pixel = 24

@ -232,6 +232,31 @@ function Remarkable:getDefaultCoverPath()
return "/usr/share/remarkable/poweroff.png"
end
function Remarkable:setEventHandlers(UIManager)
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend()
self:onPowerEvent("Suspend")
end
UIManager.event_handlers["Resume"] = function()
self:onPowerEvent("Resume")
self:_afterResume()
end
UIManager.event_handlers["PowerPress"] = function()
UIManager:scheduleIn(2, UIManager.poweroff_action)
end
UIManager.event_handlers["PowerRelease"] = function()
if not UIManager._entered_poweroff_stage then
UIManager:unschedule(UIManager.poweroff_action)
-- resume if we were suspended
if self.screen_saver_mode then
UIManager.event_handlers["Resume"]()
else
UIManager.event_handlers["Suspend"]()
end
end
end
end
if isRm2 then
if not os.getenv("RM2FB_SHIM") then
error("reMarkable2 requires RM2FB to work (https://github.com/ddvk/remarkable2-framebuffer)")

@ -343,6 +343,25 @@ function Device:toggleFullscreen()
end
end
function Device:setEventHandlers(UIManager)
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend()
self:simulateSuspend()
end
UIManager.event_handlers["Resume"] = function()
self:simulateResume()
self:_afterResume()
end
UIManager.event_handlers["PowerRelease"] = function()
-- Resume if we were suspended
if self.screen_saver_mode then
UIManager.event_handlers["Resume"]()
else
UIManager.event_handlers["Suspend"]()
end
end
end
function Emulator:supportsScreensaver() return true end
function Emulator:simulateSuspend()

@ -188,6 +188,56 @@ function SonyPRSTUX:getDeviceModel()
return ffi.string("PRS-T2")
end
function SonyPRSTUX:setEventHandlers(UIManager)
UIManager.event_handlers["Suspend"] = function()
self:_beforeSuspend()
self:intoScreenSaver()
self:suspend()
end
UIManager.event_handlers["Resume"] = function()
self:resume()
self:outofScreenSaver()
self:_afterResume()
end
UIManager.event_handlers["PowerPress"] = function()
UIManager:scheduleIn(2, UIManager.poweroff_action)
end
UIManager.event_handlers["PowerRelease"] = function()
if not UIManager._entered_poweroff_stage then
UIManager:unschedule(UIManager.poweroff_action)
-- resume if we were suspended
if self.screen_saver_mode then
UIManager.event_handlers["Resume"]()
else
UIManager.event_handlers["Suspend"]()
end
end
end
UIManager.event_handlers["Charging"] = function()
self:_beforeCharging()
end
UIManager.event_handlers["NotCharging"] = function()
self:_afterNotCharging()
end
UIManager.event_handlers["UsbPlugIn"] = function()
if self.screen_saver_mode then
self:resume()
self:outofScreenSaver()
self:_afterResume()
end
self:usbPlugIn()
end
UIManager.event_handlers["UsbPlugOut"] = function()
self:usbPlugOut()
end
UIManager.event_handlers["__default__"] = function(input_event)
-- Same as in Kobo: we want to ignore keys during suspension
if not self.screen_saver_mode then
UIManager:sendEvent(input_event)
end
end
end
-- For Sony PRS-T2
local SonyPRSTUX_T2 = SonyPRSTUX:new{
isTouchDevice = yes,

@ -74,11 +74,11 @@ local settingsList = {
toggle_fullscreen = {category="none", event="ToggleFullscreen", title=_("Toggle Fullscreen"), device=true, condition=not Device:isAlwaysFullscreen()},
show_network_info = {category="none", event="ShowNetworkInfo", title=_("Show network info"), device=true, separator=true},
exit_screensaver = {category="none", event="ExitScreensaver", title=_("Exit screensaver"), device=true},
suspend = {category="none", event="SuspendEvent", title=_("Suspend"), device=true},
exit = {category="none", event="Exit", title=_("Exit KOReader"), device=true},
restart = {category="none", event="Restart", title=_("Restart KOReader"), device=true, condition=Device:canRestart()},
reboot = {category="none", event="Reboot", title=_("Reboot the device"), device=true, condition=Device:canReboot()},
poweroff = {category="none", event="PowerOff", title=_("Power off"), device=true, condition=Device:canPowerOff(), separator=true},
suspend = {category="none", event="RequestSuspend", title=_("Suspend"), device=true},
reboot = {category="none", event="RequestReboot", title=_("Reboot the device"), device=true, condition=Device:canReboot()},
poweroff = {category="none", event="RequestPowerOff", title=_("Power off"), device=true, condition=Device:canPowerOff(), separator=true},
exit = {category="none", event="Exit", title=_("Exit KOReader"), device=true},
toggle_hold_corners = {category="none", event="IgnoreHoldCorners", title=_("Toggle hold corners"), device=true, separator=true},
toggle_rotation = {category="none", event="SwapRotation", title=_("Toggle orientation"), device=true},
invert_rotation = {category="none", event="InvertRotation", title=_("Invert rotation"), device=true},

@ -39,7 +39,7 @@ if Device:canReboot() then
text = _("Reboot the device"),
keep_menu_open = true,
callback = function()
UIManager:broadcastEvent(Event:new("Reboot"))
UIManager:reboot()
end
}
end
@ -48,7 +48,7 @@ if Device:canPowerOff() then
text = _("Power off"),
keep_menu_open = true,
callback = function()
UIManager:broadcastEvent(Event:new("PowerOff"))
UIManager:powerOff()
end
}
end

@ -108,299 +108,8 @@ function UIManager:init()
Device:reboot()
end)
end
if Device:isPocketBook() then
-- Only fg/bg state plugin notifiers, not real power event.
self.event_handlers["Suspend"] = function()
self:_beforeSuspend()
end
self.event_handlers["Resume"] = function()
self:_afterResume()
end
end
if Device:isKobo() then
-- We do not want auto suspend procedure to waste battery during
-- suspend. So let's unschedule it when suspending, and restart it after
-- resume. Done via the plugin's onSuspend/onResume handlers.
self.event_handlers["Suspend"] = function()
self:_beforeSuspend()
Device:onPowerEvent("Suspend")
end
self.event_handlers["Resume"] = function()
Device:onPowerEvent("Resume")
self:_afterResume()
end
self.event_handlers["PowerPress"] = function()
-- Always schedule power off.
-- Press the power button for 2+ seconds to shutdown directly from suspend.
UIManager:scheduleIn(2, self.poweroff_action)
end
self.event_handlers["PowerRelease"] = function()
if not self._entered_poweroff_stage then
UIManager:unschedule(self.poweroff_action)
-- resume if we were suspended
if Device.screen_saver_mode then
self:resume()
else
self:suspend()
end
end
end
-- Sleep Cover handling
if G_reader_settings:isTrue("ignore_power_sleepcover") then
-- NOTE: The hardware event itself will wake the kernel up if it's in suspend (:/).
-- Let the unexpected wakeup guard handle that.
self.event_handlers["SleepCoverClosed"] = nil
self.event_handlers["SleepCoverOpened"] = nil
elseif G_reader_settings:isTrue("ignore_open_sleepcover") then
-- Just ignore wakeup events, and do NOT set is_cover_closed,
-- so device/generic/device will let us use the power button to wake ;).
self.event_handlers["SleepCoverClosed"] = function()
self:suspend()
end
self.event_handlers["SleepCoverOpened"] = function()
Device.is_cover_closed = false
end
else
self.event_handlers["SleepCoverClosed"] = function()
Device.is_cover_closed = true
self:suspend()
end
self.event_handlers["SleepCoverOpened"] = function()
Device.is_cover_closed = false
self:resume()
end
end
self.event_handlers["Light"] = function()
Device:getPowerDevice():toggleFrontlight()
end
-- USB plug events with a power-only charger
self.event_handlers["Charging"] = function()
self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
if Device.screen_saver_mode then
self:suspend()
end
end
self.event_handlers["NotCharging"] = function()
-- We need to put the device into suspension, other things need to be done before it.
Device:usbPlugOut()
self:_afterNotCharging()
if Device.screen_saver_mode then
self:suspend()
end
end
-- USB plug events with a data-aware host
self.event_handlers["UsbPlugIn"] = function()
self:_beforeCharging()
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
if Device.screen_saver_mode then
self:suspend()
else
-- Potentially start an USBMS session
local MassStorage = require("ui/elements/mass_storage")
MassStorage:start()
end
end
self.event_handlers["UsbPlugOut"] = function()
-- We need to put the device into suspension, other things need to be done before it.
Device:usbPlugOut()
self:_afterNotCharging()
if Device.screen_saver_mode then
self:suspend()
else
-- Potentially dismiss the USBMS ConfirmBox
local MassStorage = require("ui/elements/mass_storage")
MassStorage:dismiss()
end
end
self.event_handlers["__default__"] = function(input_event)
-- Suspension in Kobo can be interrupted by screen updates. We ignore user touch input
-- in screen_saver_mode so screen updates won't be triggered in suspend mode.
-- We should not call self:suspend() in screen_saver_mode lest we stay on forever
-- trying to reschedule suspend. Other systems take care of unintended wake-up.
if not Device.screen_saver_mode then
self:sendEvent(input_event)
end
end
elseif Device:isKindle() then
self.event_handlers["IntoSS"] = function()
self:_beforeSuspend()
Device:intoScreenSaver()
end
self.event_handlers["OutOfSS"] = function()
Device:outofScreenSaver()
self:_afterResume();
end
self.event_handlers["Charging"] = function()
self:_beforeCharging()
Device:usbPlugIn()
end
self.event_handlers["NotCharging"] = function()
Device:usbPlugOut()
self:_afterNotCharging()
end
self.event_handlers["WakeupFromSuspend"] = function()
Device:wakeupFromSuspend()
end
self.event_handlers["ReadyToSuspend"] = function()
Device:readyToSuspend()
end
elseif Device:isRemarkable() then
self.event_handlers["Suspend"] = function()
self:_beforeSuspend()
Device:onPowerEvent("Suspend")
end
self.event_handlers["Resume"] = function()
Device:onPowerEvent("Resume")
self:_afterResume()
end
self.event_handlers["PowerPress"] = function()
UIManager:scheduleIn(2, self.poweroff_action)
end
self.event_handlers["PowerRelease"] = function()
if not self._entered_poweroff_stage then
UIManager:unschedule(self.poweroff_action)
-- resume if we were suspended
if Device.screen_saver_mode then
self:resume()
else
self:suspend()
end
end
end
self.event_handlers["__default__"] = function(input_event)
-- Same as in Kobo: we want to ignore keys during suspension
if not Device.screen_saver_mode then
self:sendEvent(input_event)
end
end
elseif Device:isSonyPRSTUX() then
self.event_handlers["PowerPress"] = function()
UIManager:scheduleIn(2, self.poweroff_action)
end
self.event_handlers["PowerRelease"] = function()
if not self._entered_poweroff_stage then
UIManager:unschedule(self.poweroff_action)
-- resume if we were suspended
if Device.screen_saver_mode then
self:resume()
else
self:suspend()
end
end
end
self.event_handlers["Suspend"] = function()
self:_beforeSuspend()
Device:intoScreenSaver()
Device:suspend()
end
self.event_handlers["Resume"] = function()
Device:resume()
Device:outofScreenSaver()
self:_afterResume()
end
self.event_handlers["Charging"] = function()
self:_beforeCharging()
end
self.event_handlers["NotCharging"] = function()
self:_afterNotCharging()
end
self.event_handlers["UsbPlugIn"] = function()
if Device.screen_saver_mode then
Device:resume()
Device:outofScreenSaver()
self:_afterResume()
end
Device:usbPlugIn()
end
self.event_handlers["UsbPlugOut"] = function()
Device:usbPlugOut()
end
self.event_handlers["__default__"] = function(input_event)
-- Same as in Kobo: we want to ignore keys during suspension
if not Device.screen_saver_mode then
self:sendEvent(input_event)
end
end
elseif Device:isCervantes() then
self.event_handlers["Suspend"] = function()
self:_beforeSuspend()
Device:onPowerEvent("Suspend")
end
self.event_handlers["Resume"] = function()
Device:onPowerEvent("Resume")
self:_afterResume()
end
self.event_handlers["PowerPress"] = function()
UIManager:scheduleIn(2, self.poweroff_action)
end
self.event_handlers["PowerRelease"] = function()
if not self._entered_poweroff_stage then
UIManager:unschedule(self.poweroff_action)
-- resume if we were suspended
if Device.screen_saver_mode then
self:resume()
else
self:suspend()
end
end
end
self.event_handlers["Charging"] = function()
self:_beforeCharging()
if Device.screen_saver_mode then
self:suspend()
end
end
self.event_handlers["NotCharging"] = function()
self:_afterNotCharging()
if Device.screen_saver_mode then
self:suspend()
end
end
self.event_handlers["UsbPlugIn"] = function()
self:_beforeCharging()
if Device.screen_saver_mode then
self:suspend()
else
-- Potentially start an USBMS session
local MassStorage = require("ui/elements/mass_storage")
MassStorage:start()
end
end
self.event_handlers["UsbPlugOut"] = function()
self:_afterNotCharging()
if Device.screen_saver_mode then
self:suspend()
else
-- Potentially dismiss the USBMS ConfirmBox
local MassStorage = require("ui/elements/mass_storage")
MassStorage:dismiss()
end
end
self.event_handlers["__default__"] = function(input_event)
-- Same as in Kobo: we want to ignore keys during suspension
if not Device.screen_saver_mode then
self:sendEvent(input_event)
end
end
elseif Device:isSDL() then
self.event_handlers["Suspend"] = function()
self:_beforeSuspend()
Device:simulateSuspend()
end
self.event_handlers["Resume"] = function()
Device:simulateResume()
self:_afterResume()
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
Device:_setEventHandlers(self)
end
--[[--
@ -1764,72 +1473,35 @@ function UIManager:runForever()
return self:run()
end
-- The common operations that should be performed before suspending the device.
function UIManager:_beforeSuspend()
self:flushSettings()
self:broadcastEvent(Event:new("Suspend"))
-- Block input events unrelated to power management
Input:inhibitInput(true)
-- Disable key repeat to avoid useless chatter (especially where Sleep Covers are concerned...)
Device:disableKeyRepeat()
end
-- The common operations that should be performed after resuming the device.
function UIManager:_afterResume()
-- Restore key repeat
Device:restoreKeyRepeat()
-- Restore full input handling
Input:inhibitInput(false)
self:broadcastEvent(Event:new("Resume"))
end
-- The common operations that should be performed when the device is plugged to a power source.
function UIManager:_beforeCharging()
-- Leave the kernel some time to figure it out ;o).
self:scheduleIn(1, function() Device:setupChargingLED() end)
self:broadcastEvent(Event:new("Charging"))
end
-- The common operations that should be performed when the device is unplugged from a power source.
function UIManager:_afterNotCharging()
-- Leave the kernel some time to figure it out ;o).
self:scheduleIn(1, function() Device:setupChargingLED() end)
self:broadcastEvent(Event:new("NotCharging"))
end
--[[--
Executes all the operations of a suspension (i.e., sleep) request.
This function usually puts the device into suspension.
]]
function UIManager:suspend()
-- Should always exist, as defined in `generic/device` or overwritten with `setEventHandlers`
if self.event_handlers["Suspend"] then
self.event_handlers["Suspend"]()
elseif Device:isKindle() then
Device.powerd:toggleSuspend()
elseif Device:canSuspend() then
Device:suspend()
-- Give the other event handlers a chance to be executed.
-- `Suspend` and `Resume` events will be sent by the handler
UIManager:nextTick(self.event_handlers["Suspend"])
end
end
--[[--
Executes all the operations of a resume (i.e., wakeup) request.
function UIManager:reboot()
-- Should always exist, as defined in `generic/device` or overwritten with `setEventHandlers`
if self.event_handlers["Reboot"] then
-- Give the other event handlers a chance to be executed.
-- 'Reboot' event will be sent by the handler
UIManager:nextTick(self.event_handlers["Reboot"])
end
end
This function usually wakes up the device.
]]
function UIManager:resume()
-- MONOTONIC doesn't tick during suspend,
-- invalidate the last battery capacity pull time so that we get up to date data immediately.
Device:getPowerDevice():invalidateCapacityCache()
if self.event_handlers["Resume"] then
self.event_handlers["Resume"]()
elseif Device:isKindle() then
self.event_handlers["OutOfSS"]()
function UIManager:powerOff()
-- Should always exist, as defined in `generic/device` or overwritten with `setEventHandlers`
if self.event_handlers["PowerOff"] then
-- Give the other event handlers a chance to be executed.
-- 'PowerOff' event will be sent by the handler
UIManager:nextTick(self.event_handlers["PowerOff"])
end
end

@ -2,6 +2,7 @@ describe("device module", function()
-- luacheck: push ignore
local mock_fb, mock_input
local iopen = io.open
local ipopen = io.popen
local osgetenv = os.getenv
local ffi, C
@ -43,6 +44,7 @@ describe("device module", function()
os.getenv = osgetenv
io.open = iopen
io.popen = ipopen
end)
describe("kobo", function()
@ -163,36 +165,6 @@ describe("device module", function()
-- reset eventAdjustHook
kobo_dev.input.eventAdjustHook = function() end
end)
it("should flush book settings before suspend", function()
local sample_pdf = "spec/front/unit/data/tall.pdf"
local ReaderUI = require("apps/reader/readerui")
local Device = require("device")
NickelConf.frontLightLevel.get.returns(1)
NickelConf.frontLightState.get.returns(0)
local UIManager = require("ui/uimanager")
stub(Device, "suspend")
stub(Device.powerd, "beforeSuspend")
stub(Device, "isKobo")
Device.isKobo.returns(true)
UIManager:init()
ReaderUI:doShowReader(sample_pdf)
local readerui = ReaderUI._getRunningInstance()
stub(readerui, "onFlushSettings")
UIManager.event_handlers["PowerPress"]()
UIManager.event_handlers["PowerRelease"]()
assert.stub(readerui.onFlushSettings).was_called()
Device.suspend:revert()
Device.powerd.beforeSuspend:revert()
Device.isKobo:revert()
readerui.onFlushSettings:revert()
readerui:onClose()
end)
end)
describe("kindle", function()
@ -300,5 +272,169 @@ describe("device module", function()
UIManager.onRotation:revert()
end)
end)
describe("Flush book Settings for", function()
it("Kobo", function()
os.getenv.invokes(function(key)
if key == "PRODUCT" then
return "trilogy"
else
return osgetenv(key)
end
end)
local sample_pdf = "spec/front/unit/data/tall.pdf"
local ReaderUI = require("apps/reader/readerui")
local device_to_test = require("device/kobo/device")
local Device = require("device")
Device.setEventHandlers = device_to_test.setEventHandlers
local UIManager = require("ui/uimanager")
stub(Device, "suspend")
stub(Device.powerd, "beforeSuspend")
stub(Device, "isKobo")
Device.isKobo.returns(true)
UIManager:init()
ReaderUI:doShowReader(sample_pdf)
local readerui = ReaderUI._getRunningInstance()
stub(readerui, "onFlushSettings")
UIManager.event_handlers["PowerPress"]()
UIManager.event_handlers["PowerRelease"]()
assert.stub(readerui.onFlushSettings).was_called()
Device.suspend:revert()
Device.powerd.beforeSuspend:revert()
Device.isKobo:revert()
readerui.onFlushSettings:revert()
Device.screen_saver_mode = false
readerui:onClose()
end)
it("Cervantes", function()
io.popen = function(filename, mode)
if filename:find("/usr/bin/ntxinfo") then
return {
read = function()
return 68 -- Cervantes4
end,
close = function() end
}
else
return ipopen(filename, mode)
end
end
local sample_pdf = "spec/front/unit/data/tall.pdf"
local ReaderUI = require("apps/reader/readerui")
local Device = require("device")
local device_to_test = require("device/cervantes/device")
Device.setEventHandlers = device_to_test.setEventHandlers
local UIManager = require("ui/uimanager")
stub(Device, "suspend")
stub(Device.powerd, "beforeSuspend")
stub(Device, "isCervantes")
Device.isCervantes.returns(true)
UIManager:init()
ReaderUI:doShowReader(sample_pdf)
local readerui = ReaderUI._getRunningInstance()
stub(readerui, "onFlushSettings")
UIManager.event_handlers["PowerPress"]()
UIManager.event_handlers["PowerRelease"]()
assert.stub(readerui.onFlushSettings).was_called()
Device.suspend:revert()
Device.powerd.beforeSuspend:revert()
Device.isCervantes:revert()
Device.screen_saver_mode = false
readerui.onFlushSettings:revert()
readerui:onClose()
end)
it("SDL", function()
local sample_pdf = "spec/front/unit/data/tall.pdf"
local ReaderUI = require("apps/reader/readerui")
local Device = require("device")
local device_to_test = require("device/sdl/device")
Device.setEventHandlers = device_to_test.setEventHandlers
local UIManager = require("ui/uimanager")
stub(Device, "suspend")
stub(Device.powerd, "beforeSuspend")
stub(Device, "isSDL")
Device.isSDL.returns(true)
UIManager:init()
ReaderUI:doShowReader(sample_pdf)
local readerui = ReaderUI._getRunningInstance()
stub(readerui, "onFlushSettings")
UIManager.event_handlers["PowerPress"]()
UIManager.event_handlers["PowerRelease"]()
assert.stub(readerui.onFlushSettings).was_called()
Device.suspend:revert()
Device.powerd.beforeSuspend:revert()
Device.isSDL:revert()
Device.screen_saver_mode = false
readerui.onFlushSettings:revert()
readerui:onClose()
end)
it("Remarkable", function()
io.open = function(filename, mode)
if filename == "/usr/bin/xochitl" then
return {
read = function()
return true
end,
close = function() end
}
elseif filename == "/sys/devices/soc0/machine" then
return {
read = function()
return "reMarkable", "generic"
end,
close = function() end
}
else
return iopen(filename, mode)
end
end
local sample_pdf = "spec/front/unit/data/tall.pdf"
local ReaderUI = require("apps/reader/readerui")
local Device = require("device")
local device_to_test = require("device/remarkable/device")
Device.setEventHandlers = device_to_test.setEventHandlers
local UIManager = require("ui/uimanager")
stub(Device, "suspend")
stub(Device.powerd, "beforeSuspend")
stub(Device, "isRemarkable")
Device.isRemarkable.returns(true)
UIManager:init()
ReaderUI:doShowReader(sample_pdf)
local readerui = ReaderUI._getRunningInstance()
stub(readerui, "onFlushSettings")
UIManager.event_handlers["PowerPress"]()
UIManager.event_handlers["PowerRelease"]()
assert.stub(readerui.onFlushSettings).was_called()
Device.suspend:revert()
Device.powerd.beforeSuspend:revert()
Device.isRemarkable:revert()
Device.screen_saver_mode = false
readerui.onFlushSettings:revert()
readerui:onClose()
end)
end)
-- luacheck: pop
end)

Loading…
Cancel
Save