Reapply "[PH] Disable cross origin paint holding if there was no user activation."

This reverts commit 011f2568aab9a77614d10ad913a18a825ea7d6bb.

Original patch description:
This patch disables paint holding if this is a cross origin navigation
and there was no user activation. This is a safety measure to prevent
sites from continually displaying mismatched URL and content.

With regular user behavior (clicks, etc), the behavior should be
unchanged since this counts as user activation.

Difference from original CL:
The difference is that we post a task to timeout paintholding, which allows embedding to differ and happen further down in the stack.

Details:
The surface eviction happens in this stack
content::DelegatedFrameHost::ResetFallbackToFirstNavigationSurface()
content::RenderWidgetHostImpl::ClearDisplayedGraphics()
content::RenderWidgetHostImpl::ForceFirstFrameAfterNavigationTimeout()
content::RenderFrameHostManager::CommitPendingIfNecessary()
content::RenderFrameHostManager::DidNavigateFrame()
content::Navigator::DidNavigate()

There is a bifurcation in ResetFallbackToFirstNavigationSurface to
decide whether to evict the delegated frame. This decision is based
on whether we have an first local surface id after navigation. On
non-Mac system, this local surface id is set in a stack similar to
the one below:

content::DelegatedFrameHost::EmbedSurface()
content::RenderWidgetHostViewAura::SynchronizeVisualProperties()
content::RenderWidgetHostViewAura::ShowWithVisibility()
content::RenderFrameHostManager::CommitPendingIfNecessary()
content::RenderFrameHostManager::DidNavigateFrame()
content::Navigator::DidNavigate()

Importantly, this happens _before_ we reset fallback, so in typical
cases we avoid eviction of the frame and simply reset its surface.

On Mac, the stack that sets the frame is below:
content::DelegatedFrameHost::EmbedSurface()
content::BrowserCompositorMac::DidNavigate()
content::RenderWidgetHostImpl::DidNavigate()
content::RenderFrameHostImpl::DidCommitNavigation()
...
content::mojom::NavigationClient_CommitNavigation_ForwardToCallback

This call happens _after_ we reset the fallback, so in typical cases
we evict the frame before embedding a new one. This is a cause for
a lot of test failures (and ultimately the reason for the revert).

Because the reset fallback path never happened synchronously with
DidNavigate, it isn't clear at this time whether this poses a problem
in non-test cases. Out of abundance of caution, I propose posting a
(non-delayed) task to remove paint holding. In practice this means
potentially having paintholding in place while the UI thread is busy.
This, however, is still a mitigation for the initial bug, albeit one
that does not have strict guarantees.

R=​creis@chromium.org
Bug: 40942531

Change-Id: Id45d1e2267147da2a6f4351cb95d3d8002d8f7ae
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5894513
Reviewed-by: Charlie Reis <creis@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Reviewed-by: Nate Fischer <ntfschr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1363640}
12 files changed
tree: 11dc601257074f47c6f9bf8e4dc23dcdcca31bde
  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. crypto/
  16. dbus/
  17. device/
  18. docs/
  19. extensions/
  20. fuchsia_web/
  21. gin/
  22. google_apis/
  23. google_update/
  24. gpu/
  25. headless/
  26. infra/
  27. ios/
  28. ipc/
  29. media/
  30. mojo/
  31. native_client_sdk/
  32. net/
  33. pdf/
  34. ppapi/
  35. printing/
  36. remoting/
  37. rlz/
  38. sandbox/
  39. services/
  40. skia/
  41. sql/
  42. storage/
  43. styleguide/
  44. testing/
  45. third_party/
  46. tools/
  47. ui/
  48. url/
  49. webkit/
  50. .clang-format
  51. .clang-tidy
  52. .clangd
  53. .git-blame-ignore-revs
  54. .gitallowed
  55. .gitattributes
  56. .gitignore
  57. .gitmodules
  58. .gn
  59. .mailmap
  60. .rustfmt.toml
  61. .vpython3
  62. .yapfignore
  63. ATL_OWNERS
  64. AUTHORS
  65. BUILD.gn
  66. CODE_OF_CONDUCT.md
  67. codereview.settings
  68. CPPLINT.cfg
  69. CRYPTO_OWNERS
  70. DEPS
  71. DIR_METADATA
  72. LICENSE
  73. LICENSE.chromium_os
  74. OWNERS
  75. PRESUBMIT.py
  76. PRESUBMIT_test.py
  77. PRESUBMIT_test_mocks.py
  78. README.md
  79. 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.