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