[Kindle] More accurate on/off FL detection/toggle (#5989)

* Kindle FL shenanigans

Either fix #5986, or break a whole crapload of weird corner-cases.
Possibly the insane AutoFrontLight checks.

* Make fl step 0 usable on devices where 0 doesn't turn the light off.

By fudging an extra step on our own side.

* Also, add some debug logging around wmctrl to try to figure out what's
happening there...
reviewable/pr6004/r2
NiLuJe 4 years ago committed by GitHub
parent 55d7109042
commit 0b898624ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

@ -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",
}

@ -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

@ -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

@ -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()

Loading…
Cancel
Save