PageLoadMetrics: PageAnchorsMetricsObserver for Prerender2

If a page starts as a pre-rendered page,
PageAnchorsMetricsObserver needs to be silent til the page
is activated, and records metrics only if the event happens
after the activation.

Bug: 1317494
Change-Id: Ifac9bd2e58cf898316ed10de29388a1df0139488
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3695883
Commit-Queue: Takashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1018115}
diff --git a/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.cc
index 914706a2..2c70f7c 100644
--- a/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.cc
@@ -63,6 +63,14 @@
 }
 
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PageAnchorsMetricsObserver::OnPrerenderStart(
+    content::NavigationHandle* navigation_handle,
+    const GURL& currently_committed_url) {
+  is_in_prerendered_page_ = true;
+  return CONTINUE_OBSERVING;
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 PageAnchorsMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
@@ -73,11 +81,25 @@
 
 void PageAnchorsMetricsObserver::OnComplete(
     const page_load_metrics::mojom::PageLoadTiming&) {
+  // Do not report Ukm while prerendering.
+  if (is_in_prerendered_page_)
+    return;
+
   RecordUkm();
 }
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 PageAnchorsMetricsObserver::FlushMetricsOnAppEnterBackground(
     const page_load_metrics::mojom::PageLoadTiming&) {
+  // Do not report Ukm while prerendering.
+  if (is_in_prerendered_page_)
+    return CONTINUE_OBSERVING;
+
   RecordUkm();
   return STOP_OBSERVING;
 }
+
+void PageAnchorsMetricsObserver::DidActivatePrerenderedPage(
+    content::NavigationHandle* navigation_handle) {
+  DCHECK(is_in_prerendered_page_);
+  is_in_prerendered_page_ = false;
+}
diff --git a/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.h b/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.h
index 7d9eeac..e2edb97e 100644
--- a/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/page_anchors_metrics_observer.h
@@ -9,6 +9,12 @@
 #include "components/page_load_metrics/browser/page_load_metrics_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
+// Tracks anchor information in content::NavigationPredictor to report gathered
+// data on navigating out the page. Ideally this should be managed by
+// per outermost page manner. However we ensure that this structure is not
+// created and accessed during prerendering as we have a DCHECK in
+// content::NavigationPredictor::ReportNewAnchorElements. So, we can manage it
+// as per WebContents without polluting gathered data.
 class PageAnchorsMetricsObserver
     : public page_load_metrics::PageLoadMetricsObserver {
  public:
@@ -45,6 +51,8 @@
       delete;
 
   // page_load_metrics::PageLoadMetricsObserver:
+  ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle,
+                                 const GURL& currently_committed_url) override;
   page_load_metrics::PageLoadMetricsObserver::ObservePolicy OnFencedFramesStart(
       content::NavigationHandle* navigation_handle,
       const GURL& currently_committed_url) override;
@@ -53,10 +61,14 @@
   page_load_metrics::PageLoadMetricsObserver::ObservePolicy
   FlushMetricsOnAppEnterBackground(
       const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  void DidActivatePrerenderedPage(
+      content::NavigationHandle* navigation_handle) override;
 
  private:
   void RecordUkm();
 
+  bool is_in_prerendered_page_ = false;
+
   raw_ptr<content::WebContents> web_contents_;
 };