[a11y] Check if the queue is flushing before firing a new event

This CL adds a new variable, `g_is_flushing`, to track when an
`AXPlatformNodeDelegate`'s event queue is being flushed. The value of
`g_is_flushing` is checked in
`ViewAXPlatformNodeDelegate::FireNativeEvent()` and will cause that
function to return early before firing or queueing a new event.

Firing a new event while flushing the event queue is not a valid
behavior. However, it's currently possible for this to occur if an
event that is fired once it is flushed from the queue has a call stack
that will cause another new event to get fired. An example of this can
be seen in SavedTabGroupButton::GetAccessibleNodeData(): https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc;l=177;drc=ae99ae281ffc2fe19024f86c5c64939efc1b2e87.

This has been noticed in Linux after some adjustments made to the
`GetAccessibleNodeData()` function for a handful of Views. These
adjustments put calls to functions such as
`GetViewAccessibility().SetName()` into the `GetAccessibleNodeData()`
function. `GetAccessibleNodeData()` is called when an assistive
technology is requesting accessibility information about a View, and
is not where a View's accessibility properties change (change in
a property would cause a new event to fire).

However, when `AXPlatformNodeAuraLinux::NotifyAccessibilityEvent()` is
called, perhaps as part of flushing the queue, it calls
`GetOrCreateAtkObject()`, which then calls `GetRole()`, which then
calls the View's `GetAccessibleNodeData()`. If a function such as
`SetName()` is then called for the first time or if the value has
actually changed, it is interpreted as a change in name, not
a new name. And such, a call to fire a new event is made, and that is
how we can end up with new events firing during queue flushing.

Using `g_is_flushing` to block new events from firing will not stop
`FireNativeEvent()` from emplacing new events in the queue if
`g_is_queueing_events` is true, because while `g_is_queueing_events` is
set before posting the task to flush, the flushing itself is done at a
later point, asynchronously. `g_is_flushing` can be `false` while
`g_is_queueing_events` is `true`.

Bug: 358404368
Change-Id: I2e67c51c402fdee60204fab232edd9fcc9a8b257
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5770923
Reviewed-by: Jacques Newman <janewman@microsoft.com>
Reviewed-by: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Commit-Queue: Evelynn Kaplan <evelynn.kaplan@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1339770}
1 file changed
tree: b233782ffcdd1d3fca5943c00a8458cd379d4c68
  1. android_webview/
  2. apps/
  3. ash/
  4. base/
  5. build/
  6. build_overrides/
  7. buildtools/
  8. cc/
  9. chrome/
  10. chromecast/
  11. chromeos/
  12. codelabs/
  13. components/
  14. content/
  15. courgette/
  16. crypto/
  17. dbus/
  18. device/
  19. docs/
  20. extensions/
  21. fuchsia_web/
  22. gin/
  23. google_apis/
  24. google_update/
  25. gpu/
  26. headless/
  27. infra/
  28. ios/
  29. ipc/
  30. media/
  31. mojo/
  32. native_client_sdk/
  33. net/
  34. pdf/
  35. ppapi/
  36. printing/
  37. remoting/
  38. rlz/
  39. sandbox/
  40. services/
  41. skia/
  42. sql/
  43. storage/
  44. styleguide/
  45. testing/
  46. third_party/
  47. tools/
  48. ui/
  49. url/
  50. webkit/
  51. .clang-format
  52. .clang-tidy
  53. .clangd
  54. .eslintrc.js
  55. .git-blame-ignore-revs
  56. .gitallowed
  57. .gitattributes
  58. .gitignore
  59. .gitmodules
  60. .gn
  61. .mailmap
  62. .rustfmt.toml
  63. .vpython3
  64. .yapfignore
  65. ATL_OWNERS
  66. AUTHORS
  67. BUILD.gn
  68. CODE_OF_CONDUCT.md
  69. codereview.settings
  70. CPPLINT.cfg
  71. DEPS
  72. DIR_METADATA
  73. LICENSE
  74. LICENSE.chromium_os
  75. OWNERS
  76. PRESUBMIT.py
  77. PRESUBMIT_test.py
  78. PRESUBMIT_test_mocks.py
  79. README.md
  80. WATCHLISTS
README.md

Logo Chromium

Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all users to experience the web.

The project's web site is https://www.chromium.org.

To check out the source code locally, don't use git clone! Instead, follow the instructions on how to get the code.

Documentation in the source is rooted in docs/README.md.

Learn how to Get Around the Chromium Source Code Directory Structure.

For historical reasons, there are some small top level directories. Now the guidance is that new top level directories are for product (e.g. Chrome, Android WebView, Ash). Even if these products have multiple executables, the code should be in subdirectories of the product.

If you found a bug, please file it at https://crbug.com/new.