1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.h"
6 
7 #include "base/check.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/resource_coordinator/tab_manager.h"
10 #include "components/page_load_metrics/browser/page_load_metrics_util.h"
11 #include "components/page_load_metrics/common/page_load_metrics.mojom.h"
12 #include "content/public/browser/navigation_handle.h"
13 #include "content/public/browser/restore_type.h"
14 #include "content/public/browser/web_contents.h"
15 #include "services/metrics/public/cpp/ukm_builders.h"
16 #include "services/metrics/public/cpp/ukm_recorder.h"
17 #include "ui/base/page_transition_types.h"
18 
19 namespace internal {
20 
21 const char kHistogramSessionRestoreForegroundTabFirstPaint[] =
22     "TabManager.Experimental.SessionRestore.ForegroundTab.FirstPaint";
23 const char kHistogramSessionRestoreForegroundTabFirstContentfulPaint[] =
24     "TabManager.Experimental.SessionRestore.ForegroundTab.FirstContentfulPaint";
25 const char kHistogramSessionRestoreForegroundTabFirstMeaningfulPaint[] =
26     "TabManager.Experimental.SessionRestore.ForegroundTab.FirstMeaningfulPaint";
27 
28 }  // namespace internal
29 
SessionRestorePageLoadMetricsObserver()30 SessionRestorePageLoadMetricsObserver::SessionRestorePageLoadMetricsObserver() {
31 }
32 
33 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
OnStart(content::NavigationHandle * navigation_handle,const GURL & currently_committed_url,bool started_in_foreground)34 SessionRestorePageLoadMetricsObserver::OnStart(
35     content::NavigationHandle* navigation_handle,
36     const GURL& currently_committed_url,
37     bool started_in_foreground) {
38   content::WebContents* contents = navigation_handle->GetWebContents();
39   if (!started_in_foreground ||
40       !resource_coordinator::TabManager::IsTabInSessionRestore(contents) ||
41       !resource_coordinator::TabManager::IsTabRestoredInForeground(contents)) {
42     return STOP_OBSERVING;
43   }
44 
45   // The navigation should be from the last session.
46   DCHECK(navigation_handle->GetRestoreType() ==
47              content::RestoreType::LAST_SESSION_EXITED_CLEANLY ||
48          navigation_handle->GetRestoreType() ==
49              content::RestoreType::LAST_SESSION_CRASHED);
50 
51   return CONTINUE_OBSERVING;
52 }
53 
54 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
OnCommit(content::NavigationHandle * navigation_handle,ukm::SourceId source_id)55 SessionRestorePageLoadMetricsObserver::OnCommit(
56     content::NavigationHandle* navigation_handle,
57     ukm::SourceId source_id) {
58   // Session restores use transition reload, so we only observe loads with a
59   // reload transition type.
60   DCHECK(ui::PageTransitionCoreTypeIs(navigation_handle->GetPageTransition(),
61                                       ui::PAGE_TRANSITION_RELOAD));
62   return CONTINUE_OBSERVING;
63 }
64 
OnFirstPaintInPage(const page_load_metrics::mojom::PageLoadTiming & timing)65 void SessionRestorePageLoadMetricsObserver::OnFirstPaintInPage(
66     const page_load_metrics::mojom::PageLoadTiming& timing) {
67   if (page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
68           timing.paint_timing->first_paint.value(), GetDelegate())) {
69     PAGE_LOAD_HISTOGRAM(
70         internal::kHistogramSessionRestoreForegroundTabFirstPaint,
71         timing.paint_timing->first_paint.value());
72 
73     // Only record the corresponding tab count if there are paint metrics. There
74     // is no need to record again in FCP or FMP, because FP comes first.
75     ukm::builders::
76         TabManager_Experimental_SessionRestore_ForegroundTab_PageLoad(
77             GetDelegate().GetPageUkmSourceId())
78             .SetSessionRestoreTabCount(
79                 g_browser_process->GetTabManager()->restored_tab_count())
80             .SetSystemTabCount(
81                 g_browser_process->GetTabManager()->GetTabCount())
82             .Record(ukm::UkmRecorder::Get());
83   }
84 }
85 
OnFirstContentfulPaintInPage(const page_load_metrics::mojom::PageLoadTiming & timing)86 void SessionRestorePageLoadMetricsObserver::OnFirstContentfulPaintInPage(
87     const page_load_metrics::mojom::PageLoadTiming& timing) {
88   if (page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
89           timing.paint_timing->first_contentful_paint.value(), GetDelegate())) {
90     PAGE_LOAD_HISTOGRAM(
91         internal::kHistogramSessionRestoreForegroundTabFirstContentfulPaint,
92         timing.paint_timing->first_contentful_paint.value());
93   }
94 }
95 
96 void SessionRestorePageLoadMetricsObserver::
OnFirstMeaningfulPaintInMainFrameDocument(const page_load_metrics::mojom::PageLoadTiming & timing)97     OnFirstMeaningfulPaintInMainFrameDocument(
98         const page_load_metrics::mojom::PageLoadTiming& timing) {
99   if (page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
100           timing.paint_timing->first_meaningful_paint.value(), GetDelegate())) {
101     PAGE_LOAD_HISTOGRAM(
102         internal::kHistogramSessionRestoreForegroundTabFirstMeaningfulPaint,
103         timing.paint_timing->first_meaningful_paint.value());
104   }
105 }
106