Slightly less crappy Nightmode (#4871)

Companion PR to https://github.com/koreader/koreader-base/pull/884
* Basically flags devices known to be stable when using PxP inversion.
* Plus, random fix for #4870 ;).
* A few FrontLight tweaks & cleanups on Kobo:
  * Moved the Kobo-specific startup status insanity to Kobo-specific init
  * Made turnOff/turnOn frontlight do a smooth ramp down/up
  * On Kobo, use turnOff/turnOn for suspend/resume, to get that smooth toggle
  * On Kobo, for NaturalLight w/ a mixer, only set warmth for setWarmth, and only set Brightness for setBrightness, otherwise, it tried to set both with not in-sync values, which made the FL widget jittery.
pull/4888/head
NiLuJe 5 years ago committed by GitHub
parent 8466af2c5b
commit 4005bf69aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1 +1 @@
Subproject commit ed048193eca6ebf85d3364edd0cd7a5bb5c1c4f1 Subproject commit 19e38d0be9191dfdbf4ba0d225e635b98f3ec4fd

@ -257,7 +257,7 @@ function FileManagerMenu:setUpdateItemTable()
} }
if Device:isKobo() then if Device:isKobo() then
table.insert(self.menu_items.developer_options.sub_item_table, { table.insert(self.menu_items.developer_options.sub_item_table, {
text = _("Disable forced 8-bit color space"), text = _("Disable forced 8-bit pixel depth"),
checked_func = function() checked_func = function()
return G_reader_settings:isTrue("dev_startup_no_fbdepth") return G_reader_settings:isTrue("dev_startup_no_fbdepth")
end, end,

@ -38,7 +38,7 @@ function ReaderFrontLight:init()
end end
function ReaderFrontLight:onAdjust(arg, ges) function ReaderFrontLight:onAdjust(arg, ges)
if not Device.hasFrontlight() then return true end if not Device:hasFrontlight() then return true end
local powerd = Device:getPowerDevice() local powerd = Device:getPowerDevice()
logger.dbg("frontlight intensity", powerd:frontlightIntensity()) logger.dbg("frontlight intensity", powerd:frontlightIntensity())
local step = math.ceil(#self.steps * ges.distance / self.gestureScale) local step = math.ceil(#self.steps * ges.distance / self.gestureScale)
@ -65,7 +65,7 @@ function ReaderFrontLight:onAdjust(arg, ges)
end end
function ReaderFrontLight:onShowIntensity() function ReaderFrontLight:onShowIntensity()
if not Device.hasFrontlight() then return true end if not Device:hasFrontlight() then return true end
local powerd = Device:getPowerDevice() local powerd = Device:getPowerDevice()
local new_text local new_text
if powerd:isFrontlightOff() then if powerd:isFrontlightOff() then

@ -844,7 +844,7 @@ function ReaderGesture:gestureAction(action, ges)
elseif action == "toc" then elseif action == "toc" then
self.ui:handleEvent(Event:new("ShowToc")) self.ui:handleEvent(Event:new("ShowToc"))
elseif action == "night_mode" then elseif action == "night_mode" then
local night_mode = G_reader_settings:readSetting("night_mode") or false local night_mode = G_reader_settings:isTrue("night_mode")
Screen:toggleNightMode() Screen:toggleNightMode()
UIManager:setDirty("all", "full") UIManager:setDirty("all", "full")
G_reader_settings:saveSetting("night_mode", not night_mode) G_reader_settings:saveSetting("night_mode", not night_mode)

@ -63,8 +63,8 @@ function CervantesPowerD:init()
self.initial_is_fl_on = true self.initial_is_fl_on = true
self.autowarmth_job_running = false self.autowarmth_job_running = false
if self.device.hasFrontlight() then if self.device:hasFrontlight() then
if self.device.hasNaturalLight() then if self.device:hasNaturalLight() then
local nl_config = G_reader_settings:readSetting("natural_light_config") local nl_config = G_reader_settings:readSetting("natural_light_config")
if nl_config then if nl_config then
for key,val in pairs(nl_config) do for key,val in pairs(nl_config) do
@ -86,7 +86,7 @@ function CervantesPowerD:init()
end end
function CervantesPowerD:saveSettings() function CervantesPowerD:saveSettings()
if self.device.hasFrontlight() then if self.device:hasFrontlight() then
-- Store BasePowerD values into settings (and not our hw_intensity, so -- Store BasePowerD values into settings (and not our hw_intensity, so
-- that if frontlight was toggled off, we save and restore the previous -- that if frontlight was toggled off, we save and restore the previous
-- untoggled intensity and toggle state at next startup) -- untoggled intensity and toggle state at next startup)
@ -121,10 +121,6 @@ function CervantesPowerD:isFrontlightOnHW()
return self.hw_intensity > 0 return self.hw_intensity > 0
end end
function CervantesPowerD:turnOffFrontlightHW()
self:_setIntensity(0) -- will call setIntensityHW(0)
end
function CervantesPowerD:setIntensityHW(intensity) function CervantesPowerD:setIntensityHW(intensity)
if self.fl == nil then return end if self.fl == nil then return end
if self.fl_warmth == nil then if self.fl_warmth == nil then

@ -31,6 +31,7 @@ local Device = {
hasClipboard = yes, -- generic internal clipboard on all devices hasClipboard = yes, -- generic internal clipboard on all devices
hasEinkScreen = yes, hasEinkScreen = yes,
canHWDither = no, canHWDither = no,
canHWInvert = no,
hasColorScreen = no, hasColorScreen = no,
hasBGRFrameBuffer = no, hasBGRFrameBuffer = no,
canToggleGSensor = no, canToggleGSensor = no,

@ -17,24 +17,9 @@ function BasePowerD:new(o)
self.__index = self self.__index = self
assert(o.fl_min < o.fl_max) assert(o.fl_min < o.fl_max)
if o.init then o:init() end if o.init then o:init() end
if o.device and o.device.hasFrontlight() then if o.device and o.device:hasFrontlight() then
o.fl_intensity = o:frontlightIntensityHW() o.fl_intensity = o:frontlightIntensityHW()
o:_decideFrontlightState() o:_decideFrontlightState()
-- Note added by @Frenzie 2017-10-08
-- I believe this should be `if isKobo()`, or better yet that the entire
-- block should be moved to `KoboPowerD:init()` because afaik that is the
-- only platform where the system doesn't provide trustworthy frontlight
-- information. But to be absolutely sure that I don't break anything (and I
-- don't want to spend any time on this atm) I'm temporarily excluding only
-- Android where this behavior is known to be problematic.
-- See discussion in https://github.com/koreader/koreader/issues/3118#issuecomment-334995879
if not o.device:isAndroid() then
if o:isFrontlightOn() then
o:turnOnFrontlightHW()
else
o:turnOffFrontlightHW()
end
end
end end
return o return o
end end
@ -63,7 +48,7 @@ end
function BasePowerD:_decideFrontlightState() function BasePowerD:_decideFrontlightState()
assert(self ~= nil) assert(self ~= nil)
assert(self.device.hasFrontlight()) assert(self.device:hasFrontlight())
self.is_fl_on = self:isFrontlightOnHW() self.is_fl_on = self:isFrontlightOnHW()
end end
@ -73,14 +58,14 @@ end
function BasePowerD:frontlightIntensity() function BasePowerD:frontlightIntensity()
assert(self ~= nil) assert(self ~= nil)
if not self.device.hasFrontlight() then return 0 end if not self.device:hasFrontlight() then return 0 end
if self:isFrontlightOff() then return 0 end if self:isFrontlightOff() then return 0 end
return self.fl_intensity return self.fl_intensity
end end
function BasePowerD:toggleFrontlight() function BasePowerD:toggleFrontlight()
assert(self ~= nil) assert(self ~= nil)
if not self.device.hasFrontlight() then return false end if not self.device:hasFrontlight() then return false end
if self:isFrontlightOn() then if self:isFrontlightOn() then
return self:turnOffFrontlight() return self:turnOffFrontlight()
else else
@ -90,20 +75,20 @@ end
function BasePowerD:turnOffFrontlight() function BasePowerD:turnOffFrontlight()
assert(self ~= nil) assert(self ~= nil)
if not self.device.hasFrontlight() then return end if not self.device:hasFrontlight() then return end
if self:isFrontlightOff() then return false end if self:isFrontlightOff() then return false end
self.is_fl_on = false
self:turnOffFrontlightHW() self:turnOffFrontlightHW()
self.is_fl_on = false
return true return true
end end
function BasePowerD:turnOnFrontlight() function BasePowerD:turnOnFrontlight()
assert(self ~= nil) assert(self ~= nil)
if not self.device.hasFrontlight() then return end if not self.device:hasFrontlight() then return end
if self:isFrontlightOn() then return false end if self:isFrontlightOn() then return false end
if self.fl_intensity == self.fl_min then return false end if self.fl_intensity == self.fl_min then return false end
self.is_fl_on = true
self:turnOnFrontlightHW() self:turnOnFrontlightHW()
self.is_fl_on = true
return true return true
end end
@ -135,7 +120,7 @@ function BasePowerD:normalizeIntensity(intensity)
end end
function BasePowerD:setIntensity(intensity) function BasePowerD:setIntensity(intensity)
if not self.device.hasFrontlight() then return false end if not self.device:hasFrontlight() then return false end
if intensity == self:frontlightIntensity() then return false end if intensity == self:frontlightIntensity() then return false end
self.fl_intensity = self:normalizeIntensity(intensity) self.fl_intensity = self:normalizeIntensity(intensity)
self:_decideFrontlightState() self:_decideFrontlightState()

@ -75,6 +75,8 @@ local Kindle = Generic:new{
-- NOTE: We can cheat by adding a platform-specific entry here, because the only code that will check for this is here. -- NOTE: We can cheat by adding a platform-specific entry here, because the only code that will check for this is here.
isSpecialOffers = isSpecialOffers(), isSpecialOffers = isSpecialOffers(),
hasOTAUpdates = yes, hasOTAUpdates = yes,
-- NOTE: HW inversion is generally safe on mxcfb Kindles
canHWInvert = yes,
} }
function Kindle:initNetworkManager(NetworkMgr) function Kindle:initNetworkManager(NetworkMgr)
@ -206,6 +208,7 @@ local Kindle2 = Kindle:new{
hasKeyboard = yes, hasKeyboard = yes,
hasKeys = yes, hasKeys = yes,
hasDPad = yes, hasDPad = yes,
canHWInvert = no,
} }
local KindleDXG = Kindle:new{ local KindleDXG = Kindle:new{
@ -213,6 +216,7 @@ local KindleDXG = Kindle:new{
hasKeyboard = yes, hasKeyboard = yes,
hasKeys = yes, hasKeys = yes,
hasDPad = yes, hasDPad = yes,
canHWInvert = no,
} }
local Kindle3 = Kindle:new{ local Kindle3 = Kindle:new{
@ -220,12 +224,14 @@ local Kindle3 = Kindle:new{
hasKeyboard = yes, hasKeyboard = yes,
hasKeys = yes, hasKeys = yes,
hasDPad = yes, hasDPad = yes,
canHWInvert = no,
} }
local Kindle4 = Kindle:new{ local Kindle4 = Kindle:new{
model = "Kindle4", model = "Kindle4",
hasKeys = yes, hasKeys = yes,
hasDPad = yes, hasDPad = yes,
canHWInvert = no,
} }
local KindleTouch = Kindle:new{ local KindleTouch = Kindle:new{

@ -15,7 +15,7 @@ function KindlePowerD:init()
end end
function KindlePowerD:frontlightIntensityHW() function KindlePowerD:frontlightIntensityHW()
if not self.device.hasFrontlight() then return 0 end if not self.device:hasFrontlight() then return 0 end
-- Kindle stock software does not use intensity file directly, so we need to read from its -- Kindle stock software does not use intensity file directly, so we need to read from its
-- lipc property first. -- lipc property first.
if self.lipc_handle ~= nil then if self.lipc_handle ~= nil then
@ -73,7 +73,7 @@ function KindlePowerD:_readFLIntensity()
end end
function KindlePowerD:afterResume() function KindlePowerD:afterResume()
if not self.device.hasFrontlight() then if not self.device:hasFrontlight() then
return return
end end
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")

@ -38,6 +38,8 @@ local Kobo = Generic:new{
internal_storage_mount_point = "/mnt/onboard/", internal_storage_mount_point = "/mnt/onboard/",
-- currently only the Aura One and Forma have coloured frontlights -- currently only the Aura One and Forma have coloured frontlights
hasNaturalLight = no, hasNaturalLight = no,
-- HW inversion is generally safe on Kobo, except on a few baords/kernels
canHWInvert = yes,
} }
-- TODO: hasKeys for some devices? -- TODO: hasKeys for some devices?
@ -114,6 +116,8 @@ local KoboPhoenix = Kobo:new{
display_dpi = 212, display_dpi = 212,
-- the bezel covers 12 pixels at the bottom: -- the bezel covers 12 pixels at the bottom:
viewport = Geom:new{x=0, y=0, w=758, h=1012}, viewport = Geom:new{x=0, y=0, w=758, h=1012},
-- NOTE: May have a buggy kernel, according to the nightmode hack...
canHWInvert = no,
} }
-- Kobo Aura H2O2: -- Kobo Aura H2O2:

@ -112,12 +112,12 @@ function KoboPowerD:init()
self.initial_is_fl_on = true self.initial_is_fl_on = true
self.autowarmth_job_running = false self.autowarmth_job_running = false
if self.device.hasFrontlight() then if self.device:hasFrontlight() then
-- If this device has natural light (currently only KA1 & Forma) -- If this device has natural light (currently only KA1 & Forma)
-- Use the SysFS interface, and ioctl otherwise. -- Use the SysFS interface, and ioctl otherwise.
-- NOTE: On the Forma, nickel still appears to prefer using ntx_io to handle the FL, -- NOTE: On the Forma, nickel still appears to prefer using ntx_io to handle the FL,
-- but it does use sysfs for the NL... -- but it does use sysfs for the NL...
if self.device.hasNaturalLight() then if self.device:hasNaturalLight() then
local nl_config = G_reader_settings:readSetting("natural_light_config") local nl_config = G_reader_settings:readSetting("natural_light_config")
if nl_config then if nl_config then
for key,val in pairs(nl_config) do for key,val in pairs(nl_config) do
@ -138,11 +138,20 @@ function KoboPowerD:init()
self:_syncKoboLightOnStart() self:_syncKoboLightOnStart()
end end
end end
-- See discussion in https://github.com/koreader/koreader/issues/3118#issuecomment-334995879
-- for the reasoning behind this bit of insanity.
if self:isFrontlightOnHW() then
-- Use setIntensity to ensure it sets fl_intensity, and because we don't want the ramping behavior of turnOn
self:setIntensity(self:frontlightIntensityHW())
else
-- Use setIntensityHW so as *NOT* to set fl_intensity, so toggle will still work.
self:setIntensityHW(0)
end
end end
end end
function KoboPowerD:saveSettings() function KoboPowerD:saveSettings()
if self.device.hasFrontlight() then if self.device:hasFrontlight() then
-- Store BasePowerD values into settings (and not our hw_intensity, so -- Store BasePowerD values into settings (and not our hw_intensity, so
-- that if frontlight was toggled off, we save and restore the previous -- that if frontlight was toggled off, we save and restore the previous
-- untoggled intensity and toggle state at next startup) -- untoggled intensity and toggle state at next startup)
@ -201,10 +210,6 @@ function KoboPowerD:isFrontlightOnHW()
return self.hw_intensity > 0 return self.hw_intensity > 0
end end
function KoboPowerD:turnOffFrontlightHW()
self:_setIntensity(0) -- will call setIntensityHW(0)
end
function KoboPowerD:setIntensityHW(intensity) function KoboPowerD:setIntensityHW(intensity)
if self.fl == nil then return end if self.fl == nil then return end
if self.fl_warmth == nil then if self.fl_warmth == nil then
@ -271,25 +276,52 @@ function KoboPowerD:isChargingHW()
return self:read_str_file(self.is_charging_file) == "Charging\n" return self:read_str_file(self.is_charging_file) == "Charging\n"
end end
function KoboPowerD:turnOffFrontlightHW()
if self:isFrontlightOff() then
return
end
local util = require("ffi/util")
util.runInSubProcess(function()
for i = 1,5 do
self:_setIntensity(math.floor(self.fl_intensity - ((self.fl_intensity / 5) * i)))
-- NOTE: We generally don't need to sleep when using sysfs as a backend...
if not self.device:hasNaturalLight() then
if (i < 5) then
util.usleep(35 * 1000)
end
end
end
end, false, true)
end
function KoboPowerD:turnOnFrontlightHW()
if self:isFrontlightOn() then
return
end
local util = require("ffi/util")
util.runInSubProcess(function()
for i = 1,5 do
self:_setIntensity(math.ceil(self.fl_min + ((self.fl_intensity / 5) * i)))
if not self.device:hasNaturalLight() then
if (i < 5) then
util.usleep(35 * 1000)
end
end
end
end, false, true)
end
-- Turn off front light before suspend. -- Turn off front light before suspend.
function KoboPowerD:beforeSuspend() function KoboPowerD:beforeSuspend()
if self.fl == nil then return end if self.fl == nil then return end
-- just turn off frontlight without remembering its state -- Turn off the frontlight
self.fl:setBrightness(0) self:turnOffFrontlight()
end end
-- Restore front light state after resume. -- Restore front light state after resume.
function KoboPowerD:afterResume() function KoboPowerD:afterResume()
if self.fl == nil then return end if self.fl == nil then return end
-- just re-set it to self.hw_intensity that we haven't change on Suspend -- Turn the frontlight back on
if self.fl_warmth == nil then self:turnOnFrontlight()
self.fl:setBrightness(self.hw_intensity)
else
if self.auto_warmth then
self:calculateAutoWarmth()
end
self.fl:setNaturalBrightness(self.hw_intensity, self.fl_warmth)
end
end end
return KoboPowerD return KoboPowerD

@ -22,7 +22,7 @@ function PocketBookPowerD:init()
end end
function PocketBookPowerD:frontlightIntensityHW() function PocketBookPowerD:frontlightIntensityHW()
if not self.device.hasFrontlight() then return 0 end if not self.device:hasFrontlight() then return 0 end
return inkview.GetFrontlightState() return inkview.GetFrontlightState()
end end

@ -14,7 +14,7 @@ function SonyPRSTUX_PowerD:init()
end end
function SonyPRSTUX_PowerD:frontlightIntensityHW() function SonyPRSTUX_PowerD:frontlightIntensityHW()
if not self.device.hasFrontlight() then return 0 end if not self.device:hasFrontlight() then return 0 end
end end
function SonyPRSTUX_PowerD:setIntensityHW(intensity) function SonyPRSTUX_PowerD:setIntensityHW(intensity)

@ -33,7 +33,7 @@ function SysfsLight:new(o)
end end
function SysfsLight:setBrightness(brightness) function SysfsLight:setBrightness(brightness)
self:setNaturalBrightness(brightness, self.current_warmth) self:setNaturalBrightness(brightness, nil)
end end
dbg:guard(SysfsLight, 'setBrightness', dbg:guard(SysfsLight, 'setBrightness',
@ -43,7 +43,7 @@ dbg:guard(SysfsLight, 'setBrightness',
end) end)
function SysfsLight:setWarmth(warmth) function SysfsLight:setWarmth(warmth)
self:setNaturalBrightness(self.current_brightness, warmth) self:setNaturalBrightness(nil, warmth)
end end
dbg:guard(SysfsLight, 'setWarmth', dbg:guard(SysfsLight, 'setWarmth',
@ -53,10 +53,14 @@ dbg:guard(SysfsLight, 'setWarmth',
end) end)
function SysfsLight:setNaturalBrightness(brightness, warmth) function SysfsLight:setNaturalBrightness(brightness, warmth)
local set_brightness = true
local set_warmth = true
if not brightness then if not brightness then
set_brightness = false
brightness = self.current_brightness brightness = self.current_brightness
end end
if not warmth then if not warmth then
set_warmth = false
warmth = self.current_warmth warmth = self.current_warmth
end end
@ -64,12 +68,16 @@ function SysfsLight:setNaturalBrightness(brightness, warmth)
if self.frontlight_mixer then if self.frontlight_mixer then
-- Honor the device's scale, which may not be [0...100] (f.g., it's [0...10] on the Forma) ;). -- Honor the device's scale, which may not be [0...100] (f.g., it's [0...10] on the Forma) ;).
warmth = math.floor(warmth / self.nl_max) warmth = math.floor(warmth / self.nl_max)
self:_write_value(self.frontlight_white, brightness) if set_brightness then
self:_write_value(self.frontlight_white, brightness)
end
-- And it may be inverted... (cold is nl_max, warm is nl_min) -- And it may be inverted... (cold is nl_max, warm is nl_min)
if self.nl_inverted then if set_warmth then
self:_write_value(self.frontlight_mixer, self.nl_max - warmth) if self.nl_inverted then
else self:_write_value(self.frontlight_mixer, self.nl_max - warmth)
self:_write_value(self.frontlight_mixer, warmth) else
self:_write_value(self.frontlight_mixer, warmth)
end
end end
else else
local red = 0 local red = 0

@ -114,15 +114,18 @@ if Device:isKobo() then
end, end,
callback = function() callback = function()
G_reader_settings:flipNilOrFalse("ignore_power_sleepcover") G_reader_settings:flipNilOrFalse("ignore_power_sleepcover")
UIManager:show(InfoMessage:new{
text = _("This will take effect on next restart."),
})
end end
} }
end end
common_settings.night_mode = { common_settings.night_mode = {
text = _("Night mode"), text = _("Night mode"),
checked_func = function() return G_reader_settings:readSetting("night_mode") end, checked_func = function() return G_reader_settings:isTrue("night_mode") end,
callback = function() callback = function()
local night_mode = G_reader_settings:readSetting("night_mode") or false local night_mode = G_reader_settings:isTrue("night_mode")
Screen:toggleNightMode() Screen:toggleNightMode()
UIManager:setDirty(nil, "full") UIManager:setDirty(nil, "full")
G_reader_settings:saveSetting("night_mode", not night_mode) G_reader_settings:saveSetting("night_mode", not night_mode)

@ -53,9 +53,9 @@ local InputText = InputContainer:new{
} }
-- only use PhysicalKeyboard if the device does not have touch screen -- only use PhysicalKeyboard if the device does not have touch screen
if Device.isTouchDevice() or Device.hasDPad() then if Device:isTouchDevice() or Device:hasDPad() then
Keyboard = require("ui/widget/virtualkeyboard") Keyboard = require("ui/widget/virtualkeyboard")
if Device.isTouchDevice() then if Device:isTouchDevice() then
function InputText:initEventListener() function InputText:initEventListener()
self.ges_events = { self.ges_events = {
TapTextBox = { TapTextBox = {
@ -150,7 +150,7 @@ if Device.isTouchDevice() or Device.hasDPad() then
end end
end end
if Device.hasDPad() then if Device:hasDPad() then
if not InputText.initEventListener then if not InputText.initEventListener then
function InputText:initEventListener() end function InputText:initEventListener() end
end end

@ -63,7 +63,7 @@ CanvasContext:init(Device)
if G_reader_settings:has("color_rendering") then if G_reader_settings:has("color_rendering") then
CanvasContext:setColorRenderingEnabled(G_reader_settings:isTrue("color_rendering")) CanvasContext:setColorRenderingEnabled(G_reader_settings:isTrue("color_rendering"))
else else
CanvasContext:setColorRenderingEnabled(Device.screen.isColorScreen()) CanvasContext:setColorRenderingEnabled(Device.screen:isColorScreen())
end end
-- option parsing: -- option parsing:
@ -170,7 +170,7 @@ elseif not QuickStart:isShown() then
last_file = QuickStart:getQuickStart() last_file = QuickStart:getQuickStart()
end end
-- night mode -- night mode
if G_reader_settings:readSetting("night_mode") then if G_reader_settings:isTrue("night_mode") then
Device.screen:toggleNightMode() Device.screen:toggleNightMode()
end end
@ -181,7 +181,7 @@ end
-- Inform once about color rendering on newly supported devices -- Inform once about color rendering on newly supported devices
-- (there are some android devices that may not have a color screen, -- (there are some android devices that may not have a color screen,
-- and we are not (yet?) able to guess that fact) -- and we are not (yet?) able to guess that fact)
if Device.hasColorScreen() and not G_reader_settings:has("color_rendering") then if Device:hasColorScreen() and not G_reader_settings:has("color_rendering") then
-- enable it to prevent further display of this message -- enable it to prevent further display of this message
G_reader_settings:saveSetting("color_rendering", true) G_reader_settings:saveSetting("color_rendering", true)
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")

@ -109,6 +109,7 @@ describe("AutoFrontlight widget tests", function()
end) end)
it("should turn on frontlight at the begining", function() it("should turn on frontlight at the begining", function()
Device:getPowerDevice():turnOffFrontlight()
Device.brightness = 0 Device.brightness = 0
AutoFrontlight = class:new() AutoFrontlight = class:new()
MockTime:increase(2) MockTime:increase(2)
@ -117,6 +118,7 @@ describe("AutoFrontlight widget tests", function()
end) end)
it("should turn off frontlight at the begining", function() it("should turn off frontlight at the begining", function()
Device:getPowerDevice():turnOnFrontlight()
Device.brightness = 3 Device.brightness = 3
AutoFrontlight = class:new() AutoFrontlight = class:new()
MockTime:increase(2) MockTime:increase(2)
@ -125,6 +127,7 @@ describe("AutoFrontlight widget tests", function()
end) end)
it("should handle configuration update", function() it("should handle configuration update", function()
Device:getPowerDevice():turnOffFrontlight()
Device.brightness = 0 Device.brightness = 0
AutoFrontlight = class:new() AutoFrontlight = class:new()
MockTime:increase(2) MockTime:increase(2)

@ -1,174 +1,195 @@
describe("Frontlight function in PowerD", function() describe("Frontlight function in PowerD", function()
local PowerD local Device, PowerD
local param, test_when_on, test_when_off local param, test_when_on, test_when_off
setup(function() setup(function()
require("commonrequire") require("commonrequire")
package.unloadAll()
require("document/canvascontext"):init(require("device"))
PowerD = require("device/generic/powerd"):new{ PowerD = require("device/generic/powerd"):new{
frontlight = 0, frontlight = 2,
} }
param = { param = {
fl_min = 1, fl_min = 1,
fl_max = 5, fl_max = 5,
device = { fl_intensity = 2,
hasFrontlight = function() return true end, device = nil,
-- TODO @Frenzie remove this once possibly turning on frontlight is_fl_on = true,
-- on init is Kobo-only; see device/generic/powerd 2017-10-08
isAndroid = function() return false end,
},
} }
end)
before_each(function() PowerD.frontlightIntensityHW = function(self)
stub(PowerD, "init") return self.frontlight
stub(PowerD, "frontlightIntensityHW") end
stub(PowerD, "setIntensityHW")
PowerD.setIntensityHW = function(self, intensity) PowerD.setIntensityHW = function(self, intensity)
self.frontlight = intensity self.frontlight = intensity
end end
end)
teardown(function()
package.unloadAll()
require("document/canvascontext"):init(require("device"))
end)
before_each(function()
Device = require("device")
Device.isKobo = function() return true end
Device.model = "Kobo_dahlia"
Device.hasFrontlight = function() return true end
param.device = Device
Device.powerd = PowerD:new{
param
}
stub(PowerD, "init")
spy.on(PowerD, "frontlightIntensityHW")
spy.on(PowerD, "setIntensityHW") spy.on(PowerD, "setIntensityHW")
spy.on(PowerD, "turnOnFrontlightHW") spy.on(PowerD, "turnOnFrontlightHW")
spy.on(PowerD, "turnOffFrontlightHW") spy.on(PowerD, "turnOffFrontlightHW")
end) end)
it("should read frontlight intensity during initialization", function() it("should read frontlight intensity during initialization", function()
PowerD.frontlightIntensityHW.returns(2)
local p = PowerD:new(param) local p = PowerD:new(param)
assert.are.equal(2, p:frontlightIntensityHW())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.init).is_called(1) assert.stub(p.init).is_called(1)
assert.stub(p.frontlightIntensityHW).is_called(1) assert.spy(p.frontlightIntensityHW).is_called(2)
end) end)
test_when_off = function(fl_min) test_when_off = function(fl_min)
param.fl_min = fl_min param.fl_min = fl_min
PowerD.frontlightIntensityHW.returns(fl_min) param.fl_intensity = 0
local p = PowerD:new(param) local p = PowerD:new(param)
assert.are.equal(0, p:frontlightIntensity()) p:setIntensity(0)
assert.are.equal(param.fl_min, p:frontlightIntensityHW())
assert.are.equal(0, p:frontlightIntensity()) -- returns 0 when off
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.init).is_called(1) assert.stub(p.init).is_called(1)
assert.stub(p.setIntensityHW).is_called(1) assert.spy(p.setIntensityHW).is_called(1)
assert.are.equal(param.fl_min, p.frontlight) assert.are.equal(param.fl_min, p.frontlight)
assert.stub(p.frontlightIntensityHW).is_called(1) assert.spy(p.frontlightIntensityHW).is_called(2)
assert.spy(p.turnOnFrontlightHW).is_called(0) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(0)
-- The intensity is param.fl_min, turnOnFrontlight() should take no effect. -- The intensity is param.fl_min, turnOnFrontlight() should take no effect.
assert.is.falsy(p:turnOnFrontlight()) assert.is.falsy(p:turnOnFrontlight())
assert.are.equal(0, p:frontlightIntensity()) assert.are.equal(0, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.setIntensityHW).is_called(1) assert.spy(p.setIntensityHW).is_called(1)
assert.spy(p.turnOnFrontlightHW).is_called(0) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(0)
-- Same as the above one, toggleFrontlight() should also take no effect. -- Same as the above one, toggleFrontlight() should also take no effect.
assert.is.falsy(p:toggleFrontlight()) assert.is.falsy(p:toggleFrontlight())
assert.are.equal(0, p:frontlightIntensity()) assert.are.equal(0, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.setIntensityHW).is_called(1) assert.spy(p.setIntensityHW).is_called(1)
assert.spy(p.turnOnFrontlightHW).is_called(0) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(0)
assert.is.truthy(p:setIntensity(2)) assert.is.truthy(p:setIntensity(2))
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(2) assert.spy(p.setIntensityHW).is_called(2)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(0) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(0)
assert.is.falsy(p:turnOnFrontlight()) assert.is.falsy(p:turnOnFrontlight())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(2) assert.spy(p.setIntensityHW).is_called(2)
assert.spy(p.turnOnFrontlightHW).is_called(0) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(0)
assert.is.truthy(p:turnOffFrontlight()) assert.is.truthy(p:turnOffFrontlight())
assert.are.equal(0, p:frontlightIntensity()) assert.are.equal(0, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.setIntensityHW).is_called(3) assert.spy(p.setIntensityHW).is_called(3)
assert.are.equal(param.fl_min, p.frontlight) assert.are.equal(param.fl_min, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(0) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(2) assert.spy(p.turnOffFrontlightHW).is_called(1)
assert.is.truthy(p:turnOnFrontlight()) assert.is.truthy(p:turnOnFrontlight())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(4) assert.spy(p.setIntensityHW).is_called(4)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(1) assert.spy(p.turnOnFrontlightHW).is_called(1)
assert.spy(p.turnOffFrontlightHW).is_called(2) assert.spy(p.turnOffFrontlightHW).is_called(1)
assert.is.truthy(p:toggleFrontlight()) assert.is.truthy(p:toggleFrontlight())
assert.are.equal(0, p:frontlightIntensity()) assert.are.equal(0, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.setIntensityHW).is_called(5) assert.spy(p.setIntensityHW).is_called(5)
assert.are.equal(param.fl_min, p.frontlight) assert.are.equal(param.fl_min, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(1) assert.spy(p.turnOnFrontlightHW).is_called(1)
assert.spy(p.turnOffFrontlightHW).is_called(3) assert.spy(p.turnOffFrontlightHW).is_called(2)
assert.is.truthy(p:toggleFrontlight()) assert.is.truthy(p:toggleFrontlight())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(6) assert.spy(p.setIntensityHW).is_called(6)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(2) assert.spy(p.turnOnFrontlightHW).is_called(2)
assert.spy(p.turnOffFrontlightHW).is_called(3) assert.spy(p.turnOffFrontlightHW).is_called(2)
end end
test_when_on = function(fl_min) test_when_on = function(fl_min)
assert(fl_min < 2) assert(fl_min < 2)
param.fl_min = fl_min param.fl_min = fl_min
PowerD.frontlightIntensityHW.returns(2) param.fl_intensity = 2
local p = PowerD:new(param) local p = PowerD:new(param)
p:setIntensity(2)
assert.are.equal(2, p:frontlightIntensityHW())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.init).is_called(1) assert.stub(p.init).is_called(1)
assert.stub(p.setIntensityHW).is_called(1) --assert.spy(p.setIntensityHW).is_called(1)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(1) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(0) assert.spy(p.turnOffFrontlightHW).is_called(0)
assert.is.falsy(p:setIntensity(2)) assert.is.falsy(p:setIntensity(2))
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(1) --assert.spy(p.setIntensityHW).is_called(1)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(1) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(0) assert.spy(p.turnOffFrontlightHW).is_called(0)
assert.is.falsy(p:turnOnFrontlight()) assert.is.falsy(p:turnOnFrontlight())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(1) --assert.spy(p.setIntensityHW).is_called(1)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(1) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(0) assert.spy(p.turnOffFrontlightHW).is_called(0)
assert.is.truthy(p:turnOffFrontlight()) assert.is.truthy(p:turnOffFrontlight())
assert.are.equal(0, p:frontlightIntensity()) assert.are.equal(0, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.setIntensityHW).is_called(2) --assert.spy(p.setIntensityHW).is_called(2)
assert.are.equal(param.fl_min, p.frontlight) assert.are.equal(param.fl_min, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(1) assert.spy(p.turnOnFrontlightHW).is_called(0)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(1)
assert.is.truthy(p:toggleFrontlight()) assert.is.truthy(p:toggleFrontlight())
assert.are.equal(2, p:frontlightIntensity()) assert.are.equal(2, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOn()) assert.is.truthy(p:isFrontlightOn())
assert.stub(p.setIntensityHW).is_called(3) --assert.spy(p.setIntensityHW).is_called(3)
assert.are.equal(2, p.frontlight) assert.are.equal(2, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(2) assert.spy(p.turnOnFrontlightHW).is_called(1)
assert.spy(p.turnOffFrontlightHW).is_called(1) assert.spy(p.turnOffFrontlightHW).is_called(1)
assert.is.truthy(p:toggleFrontlight()) assert.is.truthy(p:toggleFrontlight())
assert.are.equal(0, p:frontlightIntensity()) assert.are.equal(0, p:frontlightIntensity())
assert.is.truthy(p:isFrontlightOff()) assert.is.truthy(p:isFrontlightOff())
assert.stub(p.setIntensityHW).is_called(4) --assert.spy(p.setIntensityHW).is_called(4)
assert.are.equal(param.fl_min, p.frontlight) assert.are.equal(param.fl_min, p.frontlight)
assert.spy(p.turnOnFrontlightHW).is_called(2) assert.spy(p.turnOnFrontlightHW).is_called(1)
assert.spy(p.turnOffFrontlightHW).is_called(2) assert.spy(p.turnOffFrontlightHW).is_called(2)
end end

Loading…
Cancel
Save