Prerender: Make prerender activation synchronous

To avoid prerendering from being cancelled during prerender activation,
this CL makes the prerender activation sequence (BeginNavigationImpl to
DidFinishNavigation) synchronous.

This CL takes 2 approaches:

1) remove asynchronous operations during activation.

   This CL removes PostTask from CachedNavigationURLLoader.

2) moves asynchronous operations during activation to the beginning of
   navigation start where it is still feasible to fall back to regular
   navigation.

   This CL runs CommitDeferringConditionRunner at the beginning of
   navigation start instead of before commit.

With these changes, prerender activation can synchronously finish after
all CommitDeferringConditions run.

> Activation flow

- NavigationRequest::BeginNavigation() looks up a reservable
  PrerenderHost in PrerenderHostRegistry. If the host is found,
  BeginNavigation() starts running CommitDeferringConditions. These
  conditions may defer navigation, that is, these can be asynchronous,
  but it's ok because the navigation request doesn't interact with the
  host at this point and can easily fall back to regular navigation.
  After all the conditions run,
  OnCommitDeferringConditionChecksComplete() is called.
- In OnCommitDeferringConditionChecksComplete(),
  - if the host is still reservable, the navigation request reserves the
    host and proceeds with the activation. The rest of the activation
    sequence synchronously finishes, so it is expected that no one
    requests cancellation during the period. The commit deferring
    conditions don't run again before commit.
  - if the host is no longer reservable for some reasons (e.g.,
    prerendering is cancelled), the navigation request gives up the
    activation and starts regular navigation. The commit deferring
    conditions runs again before commit as usual.

> Design

- Some of changes in this CL could also applicable to restoration from
  BackForwardCache (e.g., making CachedNavigationURLLoader synchronous),
  but this CL doesn't do that to avoid blocking Prerender by unexpected
  breakages in BackForwardCache.
- This CL changes the timing to register CommitDeferringConditions with
  MockCommitDeferringConditionInstaller. Before this CL, the installer
  used WebContentsObserver::DidStartNavigation() to inject conditions.
  After this CL, this timing is too late because the conditions run in
  BeginNavigation() that is earlier than DidStartNavigation(). After
  this CL, the installer injects conditions when
  CommitDeferringConditionRunner::RegisterDeferringCondition() is
  called before starting the runner.
- For prerendered page activation, WebContentsObserver calls for
  navigation (i.e., DidStartNavigation, ReadyToCommitNavigation, and
  DidFinishNavigation) are expected to synchronously run. This CL adds
  TaskChecker to ensure they run in the same task. The checker is used
  in WebContentsObserverConsistencyChecker.
- See also the discussion on navigation-dev[1]. We also had discussed
  other approach: restarting navigation when prerendering is cancelled
  during activation. However, we did not adopt this approach because
  it turned out that both creating a new NavigationRequest and
  resetting the current NavigationRequest for restart navigation are
  difficult (see the design docs [2, 3]).

[1]https://groups.google.com/a/chromium.org/g/navigation-dev/c/MWAiXKIiXP0/m/ZB8xXAAmAAAJ
[2]https://docs.google.com/document/d/1B2ljj53rMHKCOCyWV3ekpul8CR4BsIxOZdaK4kXV8pM/edit?usp=sharing
[3]https://docs.google.com/document/d/1kaZd_MbDWxaRUycEmpw4hq9-QpFpr2znuez2WmYRUM8/edit?usp=sharing

Change-Id: Iead6736814d0ef5b3c28c96e7ee9421b061808f8
Bug: 1195751
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2992411
Commit-Queue: Hiroki Nakagawa <[email protected]>
Reviewed-by: Matt Falkenhagen <[email protected]>
Reviewed-by: David Bokan <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Cr-Commit-Position: refs/heads/master@{#900746}
27 files changed
tree: f49bf72ca1138541264b1772835745f6f9068fb6
  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. cloud_print/
  13. codelabs/
  14. components/
  15. content/
  16. courgette/
  17. crypto/
  18. dbus/
  19. device/
  20. docs/
  21. extensions/
  22. fuchsia/
  23. gin/
  24. google_apis/
  25. google_update/
  26. gpu/
  27. headless/
  28. infra/
  29. ios/
  30. ipc/
  31. jingle/
  32. media/
  33. mojo/
  34. native_client_sdk/
  35. net/
  36. pdf/
  37. ppapi/
  38. printing/
  39. remoting/
  40. rlz/
  41. sandbox/
  42. services/
  43. skia/
  44. sql/
  45. storage/
  46. styleguide/
  47. testing/
  48. third_party/
  49. tools/
  50. ui/
  51. url/
  52. weblayer/
  53. .clang-format
  54. .clang-tidy
  55. .eslintrc.js
  56. .git-blame-ignore-revs
  57. .gitattributes
  58. .gitignore
  59. .gn
  60. .mailmap
  61. .vpython
  62. .vpython3
  63. .yapfignore
  64. AUTHORS
  65. BUILD.gn
  66. CODE_OF_CONDUCT.md
  67. codereview.settings
  68. DEPS
  69. DIR_METADATA
  70. ENG_REVIEW_OWNERS
  71. LICENSE
  72. LICENSE.chromium_os
  73. OWNERS
  74. PRESUBMIT.py
  75. PRESUBMIT_test.py
  76. PRESUBMIT_test_mocks.py
  77. README.md
  78. 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.