From 9c8e55b3e5842b5db340f8cfefa18b306bcac5e7 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Tue, 1 Aug 2023 23:53:10 +0200 Subject: [PATCH] Kobo: Yet another attempt at working around the hangs on the latest NXP boards (#10771) * Notification: Drop the fencing from #10083; it never actually helped, and had subtle side-effects we could do without. * VirtualKeyBoard: Flash on close, otherwise, some of the fast refresh glitches may be burned into the working buffer until a flash. Making sure we flash ourselves prevent it from sticking around on the page ;). * util: Move `writeToSysfs` to base (i.e., `ffi/util`), as we need it there (and it actually makes more sense there anyway ;p). * Bump base for https://github.com/koreader/koreader-base/pull/1645, which is where the actual workaround (hopefully) lives. Re #8414, #9806, #10558 --- base | 2 +- frontend/device/kindle/powerd.lua | 8 +++--- frontend/device/kobo/device.lua | 34 ++++++++++++++------------ frontend/device/sysfs_light.lua | 14 +++++------ frontend/ui/data/onetime_migration.lua | 14 ++++++++++- frontend/ui/widget/inputtext.lua | 7 ++++-- frontend/ui/widget/notification.lua | 5 +--- frontend/ui/widget/virtualkeyboard.lua | 2 +- frontend/util.lua | 24 ------------------ 9 files changed, 51 insertions(+), 59 deletions(-) diff --git a/base b/base index e539f080e..afbabf2f2 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit e539f080e5a3d2ec1dc76e0a7290a1558e3fb2d7 +Subproject commit afbabf2f2b317c4bd20dd2a7b72193a76f049201 diff --git a/frontend/device/kindle/powerd.lua b/frontend/device/kindle/powerd.lua index 1348d9ee3..0a2acf3c3 100644 --- a/frontend/device/kindle/powerd.lua +++ b/frontend/device/kindle/powerd.lua @@ -2,7 +2,7 @@ local BasePowerD = require("device/generic/powerd") local UIManager local WakeupMgr = require("device/wakeupmgr") local logger = require("logger") -local util = require("util") +local ffiUtil = require("ffi/util") -- liblipclua, see require below local KindlePowerD = BasePowerD:new{ @@ -100,12 +100,12 @@ function KindlePowerD:setIntensityHW(intensity) -- 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 > 0 on ! canTurnFrontlightOff Kindles). -- We do *both* to make the fl restore on resume less jarring on devices where lipc 0 != off. - util.writeToSysfs(intensity, self.fl_intensity_file) + ffiUtil.writeToSysfs(intensity, self.fl_intensity_file) -- And in case there are two LED groups... -- This should never happen as all warmth devices so far canTurnFrontlightOff if self.warmth_intensity_file then - util.writeToSysfs(intensity, self.warmth_intensity_file) + ffiUtil.writeToSysfs(intensity, self.warmth_intensity_file) end end end @@ -175,7 +175,7 @@ end function KindlePowerD:onToggleHallSensor() local stat = self:isHallSensorEnabled() - util.writeToSysfs(stat and 0 or 1, self.hall_file) + ffiUtil.writeToSysfs(stat and 0 or 1, self.hall_file) end function KindlePowerD:_readFLIntensity() diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 13aaf07a5..c9bc2d22a 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -376,9 +376,13 @@ local KoboStorm = Kobo:extend{ }, -- NOTE: The Libra apparently suffers from a mysterious issue where completely innocuous WAIT_FOR_UPDATE_COMPLETE ioctls -- will mysteriously fail with a timeout (5s)... - -- This obviously leads to *terrible* user experience, so, until more is understood about the issue, - -- bypass this ioctl on this device. - -- c.f., https://github.com/koreader/koreader/issues/7340 + -- This obviously leads to *terrible* user experience, + -- so we've tried a few things over the years to attempt to deal with it. + -- c.f., https://github.com/koreader/koreader/issues/7340 for the genesis of all that. + -- NOTE: On a possibly related note, on NXP devices (even earlier ones), Nickel will *always* wait for markers in pairs: + -- the "expected" marker to wait for, and the *previous* one right before that. + -- Of course, that first wait will mostly always return early, because that refresh is usually much older and already dealt with. + -- This weird quirk was dropped on sunxi & MTK, FWIW. hasReliableMxcWaitFor = no, } @@ -495,7 +499,7 @@ local KoboGoldfinch = Kobo:extend{ }, battery_sysfs = "/sys/class/power_supply/battery", power_dev = "/dev/input/by-path/platform-bd71828-pwrkey-event", - -- Board is eerily similar to the Libra 2, which, unfortunately, means it's also buggy as hell... + -- Board is eerily similar to the Libra 2, so, it inherits the same quirks... -- c.f., https://github.com/koreader/koreader/issues/9552#issuecomment-1293000313 hasReliableMxcWaitFor = no, } @@ -611,7 +615,7 @@ function Kobo:init() -- No getter, so, keep track of our own state self.hw_night_mode = toggle -- Flip the global invert_fb flag - util.writeToSysfs(toggle and "night_mode 4" or "night_mode 0", "/proc/hwtcon/cmd") + ffiUtil.writeToSysfs(toggle and "night_mode 4" or "night_mode 0", "/proc/hwtcon/cmd") end function self.screen:getHWNightmode() @@ -1109,7 +1113,7 @@ function Kobo:standby(max_duration) logger.dbg("Kobo standby: asking to enter standby . . .") local standby_time = time.boottime_or_realtime_coarse() - local ret = util.writeToSysfs("standby", "/sys/power/state") + local ret = ffiUtil.writeToSysfs("standby", "/sys/power/state") self.last_standby_time = time.boottime_or_realtime_coarse() - standby_time self.total_standby_time = self.total_standby_time + self.last_standby_time @@ -1185,7 +1189,7 @@ function Kobo:suspend() -- NOTE: Sets gSleep_Mode_Suspend to 1. Used as a flag throughout the -- kernel to suspend/resume various subsystems -- c.f., state_extended_store @ kernel/power/main.c - local ret = util.writeToSysfs("1", "/sys/power/state-extended") + local ret = ffiUtil.writeToSysfs("1", "/sys/power/state-extended") if ret then logger.dbg("Kobo suspend: successfully asked the kernel to put subsystems to sleep") else @@ -1219,7 +1223,7 @@ function Kobo:suspend() logger.dbg("Kobo suspend: asking for a suspend to RAM . . .") local suspend_time = time.boottime_or_realtime_coarse() - ret = util.writeToSysfs("mem", "/sys/power/state") + ret = ffiUtil.writeToSysfs("mem", "/sys/power/state") -- NOTE: At this point, we *should* be in suspend to RAM, as such, -- execution should only resume on wakeup... @@ -1234,7 +1238,7 @@ function Kobo:suspend() else logger.warn("Kobo suspend: the kernel refused to enter suspend!") -- Reset state-extended back to 0 since we are giving up. - util.writeToSysfs("0", "/sys/power/state-extended") + ffiUtil.writeToSysfs("0", "/sys/power/state-extended") if G_reader_settings:isTrue("pm_debug_entry_failure") then self:toggleChargingLED(true) end @@ -1283,7 +1287,7 @@ function Kobo:resume() -- kernel to suspend/resume various subsystems -- cf. kernel/power/main.c @ L#207 -- Among other things, this sets up the wakeup pins (e.g., resume on input). - local ret = util.writeToSysfs("0", "/sys/power/state-extended") + local ret = ffiUtil.writeToSysfs("0", "/sys/power/state-extended") if ret then logger.dbg("Kobo resume: successfully asked the kernel to resume subsystems") else @@ -1299,7 +1303,7 @@ function Kobo:resume() -- c.f., neo_ctl @ drivers/input/touchscreen/zforce_i2c.c, -- basically, a is wakeup (for activate), d is sleep (for deactivate), and we don't care about s (set res), -- and l (led signal level, actually a NOP on NTX kernels). - util.writeToSysfs("a", self.hasIRGridSysfsKnob) + ffiUtil.writeToSysfs("a", self.hasIRGridSysfsKnob) end -- A full suspend may have toggled the LED off. @@ -1373,7 +1377,7 @@ function Kobo:_NTXChargingLEDToggle(toggle) end function Kobo:_LinuxChargingLEDToggle(toggle) - util.writeToSysfs(toggle and "1" or "0", self.charging_led_sysfs_knob) + ffiUtil.writeToSysfs(toggle and "1" or "0", self.charging_led_sysfs_knob) end function Kobo:toggleChargingLED(toggle) @@ -1421,16 +1425,16 @@ function Kobo:enableCPUCores(amount) up = "1" end - util.writeToSysfs(up, path) + ffiUtil.writeToSysfs(up, path) end end function Kobo:performanceCPUGovernor() - util.writeToSysfs("performance", self.cpu_governor_knob) + ffiUtil.writeToSysfs("performance", self.cpu_governor_knob) end function Kobo:defaultCPUGovernor() - util.writeToSysfs(self.default_cpu_governor, self.cpu_governor_knob) + ffiUtil.writeToSysfs(self.default_cpu_governor, self.cpu_governor_knob) end function Kobo:isStartupScriptUpToDate() diff --git a/frontend/device/sysfs_light.lua b/frontend/device/sysfs_light.lua index c0bec9eac..4f205ac93 100644 --- a/frontend/device/sysfs_light.lua +++ b/frontend/device/sysfs_light.lua @@ -3,7 +3,7 @@ -- red and green light LEDs. local dbg = require("dbg") -local util = require("util") +local ffiUtil = require("ffi/util") local SysfsLight = { frontlight_white = nil, @@ -73,15 +73,15 @@ function SysfsLight:setNaturalBrightness(brightness, warmth) if self.frontlight_ioctl then self.frontlight_ioctl:setBrightness(brightness) else - util.writeToSysfs(brightness, self.frontlight_white) + ffiUtil.writeToSysfs(brightness, self.frontlight_white) end end -- The mixer might be using inverted values... (cold is nl_max, warm is nl_min) if set_warmth then if self.nl_inverted then - util.writeToSysfs(self.nl_max - warmth, self.frontlight_mixer) + ffiUtil.writeToSysfs(self.nl_max - warmth, self.frontlight_mixer) else - util.writeToSysfs(warmth, self.frontlight_mixer) + ffiUtil.writeToSysfs(warmth, self.frontlight_mixer) end end else @@ -124,11 +124,11 @@ function SysfsLight:_set_light_value(sysfs_directory, value) if not sysfs_directory then return end -- bl_power is '31' when the light is turned on, '0' otherwise. if (value > 0) then - util.writeToSysfs(31, sysfs_directory .. "/bl_power") + ffiUtil.writeToSysfs(31, sysfs_directory .. "/bl_power") else - util.writeToSysfs(0, sysfs_directory .. "/bl_power") + ffiUtil.writeToSysfs(0, sysfs_directory .. "/bl_power") end - util.writeToSysfs(value, sysfs_directory .. "/brightness") + ffiUtil.writeToSysfs(value, sysfs_directory .. "/brightness") end return SysfsLight diff --git a/frontend/ui/data/onetime_migration.lua b/frontend/ui/data/onetime_migration.lua index dc7dc3702..76761fe1d 100644 --- a/frontend/ui/data/onetime_migration.lua +++ b/frontend/ui/data/onetime_migration.lua @@ -8,7 +8,7 @@ local logger = require("logger") local _ = require("gettext") -- Date at which the last migration snippet was added -local CURRENT_MIGRATION_DATE = 20230710 +local CURRENT_MIGRATION_DATE = 20230731 -- Retrieve the date of the previous migration, if any local last_migration_date = G_reader_settings:readSetting("last_migration_date", 0) @@ -585,5 +585,17 @@ if last_migration_date < 20230710 then end end +-- 20230731, aka., "let's kill all those stupid and weird mxcfb workarounds" +if last_migration_date < 20230731 then + logger.info("Performing one-time migration for 20230731") + + local Device = require("device") + if Device:isKobo() then + if not Device:hasReliableMxcWaitFor() then + G_reader_settings:delSetting("followed_link_marker") + end + end +end + -- We're done, store the current migration date G_reader_settings:saveSetting("last_migration_date", CURRENT_MIGRATION_DATE) diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua index faa3555b5..42499a913 100644 --- a/frontend/ui/widget/inputtext.lua +++ b/frontend/ui/widget/inputtext.lua @@ -683,9 +683,12 @@ function InputText:onShowKeyboard(ignore_first_hold_release) end function InputText:onCloseKeyboard() - UIManager:close(self.keyboard) Device:stopTextInput() - self.is_keyboard_hidden = true + + if not self.is_keyboard_hidden then + UIManager:close(self.keyboard) + self.is_keyboard_hidden = true + end end function InputText:onCloseWidget() diff --git a/frontend/ui/widget/notification.lua b/frontend/ui/widget/notification.lua index 0ada71b9a..9ecf8141f 100644 --- a/frontend/ui/widget/notification.lua +++ b/frontend/ui/widget/notification.lua @@ -203,11 +203,8 @@ function Notification:onCloseWidget() end function Notification:onShow() - -- NOTE: We use the elusive "[ui]" mode solely for the sake of NTX boards flagged as unreliable, - -- in the hope that this will save them from an EPDC race that might make them horribly crash. - -- c.f., https://github.com/koreader/koreader/issues/9806#issuecomment-1416827447 UIManager:setDirty(self, function() - return "[ui]", self.frame.dimen + return "ui", self.frame.dimen end) if self.timeout then UIManager:scheduleIn(self.timeout, function() UIManager:close(self) end) diff --git a/frontend/ui/widget/virtualkeyboard.lua b/frontend/ui/widget/virtualkeyboard.lua index 4c87313cd..84771c89e 100644 --- a/frontend/ui/widget/virtualkeyboard.lua +++ b/frontend/ui/widget/virtualkeyboard.lua @@ -933,7 +933,7 @@ function VirtualKeyboard:onShow() end function VirtualKeyboard:onCloseWidget() - self:_refresh(false) + self:_refresh(true) end function VirtualKeyboard:initLayer(layer) diff --git a/frontend/util.lua b/frontend/util.lua index 01241a084..a405ce97d 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -5,13 +5,9 @@ This module contains miscellaneous helper functions for the KOReader frontend. local BaseUtil = require("ffi/util") local Utf8Proc = require("ffi/utf8proc") local lfs = require("libs/libkoreader-lfs") -local logger = require("logger") local _ = require("gettext") local C_ = _.pgettext local T = BaseUtil.template -local ffi = require("ffi") -local C = ffi.C -require("ffi/posix_h") local lshift = bit.lshift local rshift = bit.rshift @@ -833,26 +829,6 @@ function util.removeFile(file) end end -function util.writeToSysfs(val, file) - -- NOTE: We do things by hand via ffi, because io.write uses fwrite, - -- which isn't a great fit for procfs/sysfs (e.g., we lose failure cases like EBUSY, - -- as it only reports failures to write to the *stream*, not to the disk/file!). - local fd = C.open(file, bit.bor(C.O_WRONLY, C.O_CLOEXEC)) -- procfs/sysfs, we shouldn't need O_TRUNC - if fd == -1 then - logger.err("Cannot open file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno()))) - return - end - val = tostring(val) - local bytes = #val - local nw = C.write(fd, val, bytes) - if nw == -1 then - logger.err("Cannot write `" .. val .. "` to file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno()))) - end - C.close(fd) - -- NOTE: Allows the caller to possibly handle short writes (not that these should ever happen here). - return nw == bytes -end - -- Gets total, used and available bytes for the mountpoint that holds a given directory. -- @string path of the directory -- @treturn table with total, used and available bytes