diff --git a/frontend/device/generic/powerd.lua b/frontend/device/generic/powerd.lua index 294f42b64..66b030f78 100644 --- a/frontend/device/generic/powerd.lua +++ b/frontend/device/generic/powerd.lua @@ -33,7 +33,7 @@ function BasePowerD:isChargingHW() return false end function BasePowerD:frontlightIntensityHW() return 0 end function BasePowerD:isFrontlightOnHW() return self.fl_intensity > self.fl_min end function BasePowerD:turnOffFrontlightHW() self:_setIntensity(self.fl_min) end -function BasePowerD:turnOnFrontlightHW() self:_setIntensity(self.fl_intensity) end +function BasePowerD:turnOnFrontlightHW() self:_setIntensity(self.fl_intensity) end --- @fixme: what if fl_intensity == fl_min (c.f., kindle)? -- Anything needs to be done before do a real hardware suspend. Such as turn off -- front light. function BasePowerD:beforeSuspend() end @@ -86,7 +86,7 @@ function BasePowerD:turnOnFrontlight() assert(self ~= nil) if not self.device:hasFrontlight() then return 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 --- @fixme what the hell? self:turnOnFrontlightHW() self.is_fl_on = true return true diff --git a/frontend/device/kindle/device.lua b/frontend/device/kindle/device.lua index 09af86a69..95d6a71d9 100644 --- a/frontend/device/kindle/device.lua +++ b/frontend/device/kindle/device.lua @@ -86,6 +86,8 @@ local Kindle = Generic:new{ hasOTAUpdates = yes, -- NOTE: HW inversion is generally safe on mxcfb Kindles canHWInvert = yes, + -- NOTE: Newer devices will turn the frontlight off at 0 + canTurnFrontlightOff = yes, } function Kindle:initNetworkManager(NetworkMgr) @@ -279,6 +281,7 @@ local KindlePaperWhite = Kindle:new{ model = "KindlePaperWhite", isTouchDevice = yes, hasFrontlight = yes, + canTurnFrontlightOff = no, display_dpi = 212, touch_dev = "/dev/input/event0", } @@ -287,6 +290,7 @@ local KindlePaperWhite2 = Kindle:new{ model = "KindlePaperWhite2", isTouchDevice = yes, hasFrontlight = yes, + canTurnFrontlightOff = no, display_dpi = 212, touch_dev = "/dev/input/event1", } @@ -301,6 +305,7 @@ local KindleVoyage = Kindle:new{ model = "KindleVoyage", isTouchDevice = yes, hasFrontlight = yes, + canTurnFrontlightOff = no, hasKeys = yes, display_dpi = 300, touch_dev = "/dev/input/event1", @@ -310,6 +315,7 @@ local KindlePaperWhite3 = Kindle:new{ model = "KindlePaperWhite3", isTouchDevice = yes, hasFrontlight = yes, + canTurnFrontlightOff = no, display_dpi = 300, touch_dev = "/dev/input/event1", } diff --git a/frontend/device/kindle/powerd.lua b/frontend/device/kindle/powerd.lua index 144f4bb20..e40d1771a 100644 --- a/frontend/device/kindle/powerd.lua +++ b/frontend/device/kindle/powerd.lua @@ -12,14 +12,58 @@ function KindlePowerD:init() if haslipc and lipc then self.lipc_handle = lipc.init("com.github.koreader.kindlepowerd") end + + -- On devices where lipc step 0 is *not* off, we add a synthetic fl level where 0 *is* off, + -- which allows us to keep being able to use said step 0 as the first "on" step. + if not self.device:canTurnFrontlightOff() then + self.fl_max = self.fl_max + 1 + end +end + +-- If we start with the light off (fl_intensity is fl_min), ensure a toggle will set it to the lowest "on" step, +-- and that we update fl_intensity (by using setIntensity and not _setIntensity). +function KindlePowerD:turnOnFrontlightHW() + self:setIntensity(self.fl_intensity == self.fl_min and self.fl_min + 1 or self.fl_intensity) +end +-- Which means we need to get rid of the insane fl_intensity == fl_min shortcut in turnOnFrontlight, too... +-- That dates back to #2941, and I have no idea what it's supposed to help with. +function BasePowerD:turnOnFrontlight() + if not self.device:hasFrontlight() then return end + if self:isFrontlightOn() then return false end + self:turnOnFrontlightHW() + self.is_fl_on = true + return true end function KindlePowerD:frontlightIntensityHW() 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 - -- lipc property first. + -- Kindle stock software does not use intensity file directly, so go through lipc to keep us in sync. if self.lipc_handle ~= nil then - return self.lipc_handle:get_int_property("com.lab126.powerd", "flIntensity") + -- Handle the step 0 switcheroo on ! canTurnFrontlightOff devices... + if self.device:canTurnFrontlightOff() then + return self.lipc_handle:get_int_property("com.lab126.powerd", "flIntensity") + else + local lipc_fl_intensity = self.lipc_handle:get_int_property("com.lab126.powerd", "flIntensity") + -- NOTE: If lipc returns 0, compare against what the kernel says, + -- to avoid breaking on/off detection on devices where lipc 0 doesn't actually turn it off (<= PW3), + -- c.f., #5986 + if lipc_fl_intensity == self.fl_min then + local sysfs_fl_intensity = self:_readFLIntensity() + if sysfs_fl_intensity ~= self.fl_min then + -- Return something potentially slightly off (as we can't be sure of the sysfs -> lipc mapping), + -- but, more importantly, something that's not fl_min (0), so we properly detect the light as on, + -- and update fl_intensity accordingly. + -- That's only tripped if it was set to fl_min from the stock UI, + -- as we ourselves *do* really turn it off when we do that. + return self.fl_min + 1 + else + return self.fl_min + end + else + -- We've added a synthetic step... + return lipc_fl_intensity + 1 + end + end else -- NOTE: This fallback is of dubious use, as it will NOT match our expected [fl_min..fl_max] range, -- each model has a specific curve. @@ -28,6 +72,16 @@ function KindlePowerD:frontlightIntensityHW() end function KindlePowerD:setIntensityHW(intensity) + -- Handle the synthetic step switcheroo on ! canTurnFrontlightOff devices... + local turn_it_off = false + if not self.device:canTurnFrontlightOff() then + if intensity > 0 then + intensity = intensity - 1 + else + -- And if we *really* requested 0, turn it off manually. + turn_it_off = true + end + end -- NOTE: This means we *require* a working lipc handle to set the FL: -- it knows what the UI values should map to for the specific hardware much better than us. if self.lipc_handle ~= nil then @@ -35,9 +89,9 @@ function KindlePowerD:setIntensityHW(intensity) self.lipc_handle:set_int_property( "com.lab126.powerd", "flIntensity", intensity) end - if intensity == 0 then + if turn_it_off then -- NOTE: when intensity is 0, we want to *really* kill the light, so do it manually - -- (asking lipc to set it to 0 would in fact set it to 1 on most Kindles). + -- (asking lipc to set it to 0 would in fact set it to > 0 on ! canTurnFrontlightOff Kindles). -- We do *both* to make the fl restore on resume less jarring on devices where lipc 0 != off. os.execute("echo -n ".. intensity .." > " .. self.fl_intensity_file) end diff --git a/platform/kindle/koreader.sh b/platform/kindle/koreader.sh index 45bf4d05e..438116dd6 100755 --- a/platform/kindle/koreader.sh +++ b/platform/kindle/koreader.sh @@ -127,9 +127,9 @@ ko_update_check() { # and run that one (c.f., #4602)... # This is most likely a side-effect of the weird fuse overlay being used for /mnt/us (vs. the real vfat on /mnt/base-us), # which we cannot use because it's been mounted noexec for a few years now... - cp -pf ./tar /var/tmp/gnutar + cp -pf "${KOREADER_DIR}/tar" /var/tmp/gnutar # shellcheck disable=SC2016 - /var/tmp/gnutar --no-same-permissions --no-same-owner --checkpoint="${CPOINTS}" --checkpoint-action=exec='./fbink -q -y -6 -P $(($TAR_CHECKPOINT/$CPOINTS))' -C "/mnt/us" -xf "${NEWUPDATE}" + /var/tmp/gnutar --no-same-permissions --no-same-owner --checkpoint="${CPOINTS}" --checkpoint-action=exec='/var/tmp/fbink -q -y -6 -P $(($TAR_CHECKPOINT/$CPOINTS))' -C "/mnt/us" -xf "${NEWUPDATE}" fail=$? # And remove our temporary tar binary... rm -f /var/tmp/gnutar @@ -241,8 +241,9 @@ if [ "${STOP_FRAMEWORK}" = "no" ] && [ "${INIT_TYPE}" = "upstart" ]; then # Less drastically, we'll also be "minimizing" (actually, resizing) the title bar manually (c.f., https://www.mobileread.com/forums/showpost.php?p=2449275&postcount=5). # NOTE: Hiding it "works", but has a nasty side-effect of triggering ligl timeouts in some circumstances (c.f., https://github.com/koreader/koreader/pull/5943#issuecomment-598514376) logmsg "Hiding the title bar . . ." - TITLEBAR_GEOMETRY="$(./wmctrl -l -G | grep "titleBar" | awk '{print $2,$3,$4,$5,$6}' OFS=',')" - ./wmctrl -r titleBar -e "${TITLEBAR_GEOMETRY%,*},1" + TITLEBAR_GEOMETRY="$(${KOREADER_DIR}/wmctrl -l -G | grep "titleBar" | awk '{print $2,$3,$4,$5,$6}' OFS=',')" + ${KOREADER_DIR}/wmctrl -r titleBar -e "${TITLEBAR_GEOMETRY%,*},1" + logmsg "Title bar geometry: '${TITLEBAR_GEOMETRY}' -> '$(${KOREADER_DIR}/wmctrl -l -G | grep "titleBar" | awk '{print $2,$3,$4,$5,$6}' OFS=',')'" USED_WMCTRL="yes" if [ "${FROM_KUAL}" = "yes" ]; then logmsg "Stopping awesome . . ." @@ -361,7 +362,8 @@ if [ "${STOP_FRAMEWORK}" = "no" ] && [ "${INIT_TYPE}" = "upstart" ]; then fi if [ "${USED_WMCTRL}" = "yes" ]; then logmsg "Restoring the title bar . . ." - ./wmctrl -r titleBar -e "${TITLEBAR_GEOMETRY}" + ${KOREADER_DIR}/wmctrl -r titleBar -e "${TITLEBAR_GEOMETRY}" + logmsg "Title bar geometry restored to '$(${KOREADER_DIR}/wmctrl -l -G | grep "titleBar" | awk '{print $2,$3,$4,$5,$6}' OFS=',')' (ought to be: '${TITLEBAR_GEOMETRY}')" fi fi diff --git a/spec/unit/device_spec.lua b/spec/unit/device_spec.lua index 42c4080f4..64d44a2ec 100644 --- a/spec/unit/device_spec.lua +++ b/spec/unit/device_spec.lua @@ -212,7 +212,8 @@ describe("device module", function() assert.is.same(kindle_dev.input.event_map[104], "LPgBack") assert.is.same(kindle_dev.input.event_map[109], "LPgFwd") assert.is.same(kindle_dev.powerd.fl_min, 0) - assert.is.same(kindle_dev.powerd.fl_max, 24) + -- NOTE: fl_max + 1 since #5989 + assert.is.same(kindle_dev.powerd.fl_max, 25) end) it("should toggle frontlight", function()