I tried so hard to avoid adding timeouts/timestamp logic for Android because it feels like a nondeterministic hack. In the end I gave up and did something similar.
I also found beforeInput doesn’t offer much solace on Android or with CJK language, because messing around with preventDefault or the DOM during composition disturbs the user.
One weird thing I never figured out is that if the user puts the selection in an empty block, GBoard wants to jump to the nearest word in a different paragraph. We do some brutal hacks to get around that :-/
I read your comment on ProseMirror forum about preventing interference from Granmarly, etc. Do you do this by reverting MutationRecords? Where is the code/docs for that?