From a001a13ab6c7c8227d9b79486ea7ed720c4f26ad Mon Sep 17 00:00:00 2001 From: zwim <36999612+zwim@users.noreply.github.com> Date: Tue, 7 Dec 2021 19:55:55 +0100 Subject: [PATCH] ReaderRolling: avoid ANR on Android when (re)rendering. (#8501) Wrap document opening and re-renderings (which can block the app for some time) with setIgnoreInput() to avoid ANR on Android. Any setting update that could possibly cause a re-rendering should send the UpdatePos event, to ensure the re-rendering happens in ReaderRolling:onUpdatePos() where precautions are taken to avoid ANR. --- frontend/apps/reader/modules/readerrolling.lua | 8 ++++++++ frontend/apps/reader/readerui.lua | 4 ++++ frontend/device/android/device.lua | 1 + 3 files changed, 13 insertions(+) diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index e04b79110..7890657fc 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -867,16 +867,24 @@ function ReaderRolling:onUpdatePos() -- we have set above) to avoid multiple refreshes. return true end + + UIManager:discardEvents(math.huge) -- Discard any past and upcoming input events for the next hour. + Device:setIgnoreInput(true) -- Avoid ANRs on Android with unprocessed events. + -- Calling this now ensures the re-rendering is done by crengine -- so updatePos() has good info and can reposition -- the previous xpointer accurately: self.ui.document:getCurrentPos() + -- Otherwise, _readMetadata() would do that, but the positioning -- would not work as expected, for some reason (it worked -- previously because of some bad setDirty() in ConfigDialog widgets -- that were triggering a full repaint of crengine (so, the needed -- rerendering) before updatePos() is called. self:updatePos() + + Device:setIgnoreInput(false) -- Allow processing of events (on Android). + UIManager:discardEvents(true) -- Discard events, which might have occured (double tap). end function ReaderRolling:updatePos() diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 19dea5ef3..fa82976f5 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -106,6 +106,8 @@ function ReaderUI:init() -- cap screen refresh on pan to 2 refreshes per second local pan_rate = Screen.low_pan_rate and 2.0 or 30.0 + Device:setIgnoreInput(true) -- Avoid ANRs on Android with unprocessed events. + self.postInitCallback = {} self.postReaderCallback = {} -- if we are not the top level dialog ourselves, it must be given in the table @@ -457,6 +459,8 @@ function ReaderUI:init() end self.postReaderCallback = nil + Device:setIgnoreInput(false) -- Allow processing of events (on Android). + -- print("Ordered registered gestures:") -- for _, tzone in ipairs(self._ordered_touch_zones) do -- print(" "..tzone.def.id) diff --git a/frontend/device/android/device.lua b/frontend/device/android/device.lua index 6280e773d..f818a1475 100644 --- a/frontend/device/android/device.lua +++ b/frontend/device/android/device.lua @@ -311,6 +311,7 @@ function Device:performHapticFeedback(type) end function Device:setIgnoreInput(enable) + logger.dbg("android.setIgnoreInput", enable) android.setIgnoreInput(enable) end