| // Copyright 2015 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_ |
| #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/time/time.h" |
| #include "components/page_load_metrics/browser/page_load_metrics_observer_delegate.h" |
| #include "components/page_load_metrics/browser/page_load_metrics_observer_interface.h" |
| #include "components/page_load_metrics/common/page_load_timing.h" |
| #include "content/public/browser/global_routing_id.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "net/base/host_port_pair.h" |
| #include "net/base/ip_endpoint.h" |
| #include "net/base/net_errors.h" |
| #include "net/cookies/canonical_cookie.h" |
| #include "services/network/public/mojom/fetch_api.mojom.h" |
| #include "third_party/blink/public/common/input/web_input_event.h" |
| #include "third_party/blink/public/common/use_counter/use_counter_feature.h" |
| #include "url/gurl.h" |
| |
| namespace blink { |
| struct JavaScriptFrameworkDetectionResult; |
| } // namespace blink |
| |
| namespace page_load_metrics { |
| |
| // Information related to whether an associated action, such as a navigation or |
| // an abort, was initiated by a user. Clicking a link or tapping on a UI |
| // element are examples of user initiation actions. |
| struct UserInitiatedInfo { |
| static UserInitiatedInfo NotUserInitiated() { |
| return UserInitiatedInfo(false, false, false); |
| } |
| |
| static UserInitiatedInfo BrowserInitiated() { |
| return UserInitiatedInfo(true, false, false); |
| } |
| |
| static UserInitiatedInfo RenderInitiated(bool user_gesture, |
| bool user_input_event) { |
| return UserInitiatedInfo(false, user_gesture, user_input_event); |
| } |
| |
| // Whether the associated action was initiated from the browser process, as |
| // opposed to from the render process. We generally assume that all actions |
| // initiated from the browser process are user initiated. |
| bool browser_initiated; |
| |
| // Whether the associated action was initiated by a user, according to user |
| // gesture tracking in content and Blink, as reported by NavigationHandle. |
| // This is based on the heuristic the popup blocker uses. |
| bool user_gesture; |
| |
| // Whether an input even directly led to the navigation, according to |
| // input start time tracking in the renderer, as reported by NavigationHandle. |
| // Note that this metric is still experimental and may not be fully |
| // implemented. All known issues are blocking crbug.com/889220. Currently |
| // all known gaps affect browser-side navigations. |
| bool user_input_event; |
| |
| private: |
| UserInitiatedInfo(bool browser_initiated, |
| bool user_gesture, |
| bool user_input_event) |
| : browser_initiated(browser_initiated), |
| user_gesture(user_gesture), |
| user_input_event(user_input_event) {} |
| }; |
| |
| // Information about how the page rendered during the browsing session. |
| // Derived from the FrameRenderDataUpdate that is sent via UpdateTiming IPC. |
| struct PageRenderData { |
| PageRenderData() = default; |
| |
| // How much visible elements on the page shifted (bit.ly/lsm-explainer). |
| float layout_shift_score = 0; |
| |
| // How much visible elements on the page shifted (bit.ly/lsm-explainer), |
| // before user input or document scroll. This field's meaning is context- |
| // dependent (see comments on page_render_data_ and main_frame_render_data_ |
| // in PageLoadMetricsUpdateDispatcher). |
| float layout_shift_score_before_input_or_scroll = 0; |
| }; |
| |
| // Information related to layout shift normalization for different strategies. |
| struct NormalizedCLSData { |
| // Maximum CLS of session windows. The gap between two consecutive shifts is |
| // not bigger than 1000ms and the maximum window size is 5000ms. |
| float session_windows_gap1000ms_max5000ms_max_cls = 0.0; |
| |
| // If true, will not report the data in UKM. |
| bool data_tainted = false; |
| }; |
| |
| // Base class for PageLoadMetrics observers. All instances of this class are |
| // owned by the PageLoadTracker tracking a page load. The page would be a |
| // primary page, Prerendering page, FencedFrames page, or pages for new other |
| // features based on MPArch. |
| class PageLoadMetricsObserver : public PageLoadMetricsObserverInterface { |
| public: |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class LargestContentState { |
| kReported = 0, |
| kLargestImageLoading = 1, |
| kNotFound = 2, |
| kFoundButNotReported = 3, |
| kMaxValue = kFoundButNotReported, |
| }; |
| |
| PageLoadMetricsObserver(); |
| ~PageLoadMetricsObserver() override; |
| |
| static bool IsStandardWebPageMimeType(const std::string& mime_type); |
| |
| // PageLoadMetricsObserverInterface implementation: |
| const PageLoadMetricsObserverDelegate& GetDelegate() const override; |
| void SetDelegate(PageLoadMetricsObserverDelegate*) override; |
| const char* GetObserverName() const override; |
| ObservePolicy OnStart(content::NavigationHandle* navigation_handle, |
| const GURL& currently_committed_url, |
| bool started_in_foreground) override; |
| ObservePolicy OnPreviewStart(content::NavigationHandle* navigation_handle, |
| const GURL& currently_committed_url) override; |
| ObservePolicy OnNavigationHandleTimingUpdated( |
| content::NavigationHandle* navigation_handle) override; |
| ObservePolicy OnRedirect( |
| content::NavigationHandle* navigation_handle) override; |
| ObservePolicy OnCommit(content::NavigationHandle* navigation_handle) override; |
| void OnDidInternalNavigationAbort( |
| content::NavigationHandle* navigation_handle) override {} |
| void ReadyToCommitNextNavigation( |
| content::NavigationHandle* navigation_handle) override {} |
| void OnDidFinishSubFrameNavigation( |
| content::NavigationHandle* navigation_handle) override {} |
| void OnCommitSameDocumentNavigation( |
| content::NavigationHandle* navigation_handle) override {} |
| ObservePolicy OnHidden(const mojom::PageLoadTiming& timing) override; |
| ObservePolicy OnShown() override; |
| ObservePolicy OnEnterBackForwardCache( |
| const mojom::PageLoadTiming& timing) override; |
| void OnRestoreFromBackForwardCache( |
| const mojom::PageLoadTiming& timing, |
| content::NavigationHandle* navigation_handle) override {} |
| ObservePolicy ShouldObserveMimeType( |
| const std::string& mime_type) const override; |
| ObservePolicy ShouldObserveScheme(const GURL& url) const override; |
| void OnTimingUpdate(content::RenderFrameHost* subframe_rfh, |
| const mojom::PageLoadTiming& timing) override {} |
| void OnSoftNavigationUpdated(const mojom::SoftNavigationMetrics&) override {} |
| void OnInputTimingUpdate( |
| content::RenderFrameHost* subframe_rfh, |
| const mojom::InputTiming& input_timing_delta) override {} |
| void OnPageInputTimingUpdate(uint64_t num_interactions) override {} |
| void OnPageRenderDataUpdate(const mojom::FrameRenderDataUpdate& render_data, |
| bool is_main_frame) override {} |
| void OnSubFrameRenderDataUpdate( |
| content::RenderFrameHost* subframe_rfh, |
| const mojom::FrameRenderDataUpdate& render_data) override {} |
| void OnCpuTimingUpdate(content::RenderFrameHost* subframe_rfh, |
| const mojom::CpuTiming& timing) override {} |
| void OnUserInput(const blink::WebInputEvent& event, |
| const mojom::PageLoadTiming& timing) override {} |
| void OnDomContentLoadedEventStart( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnLoadEventStart(const mojom::PageLoadTiming& timing) override {} |
| void OnParseStart(const mojom::PageLoadTiming& timing) override {} |
| void OnParseStop(const mojom::PageLoadTiming& timing) override {} |
| void OnConnectStart(const mojom::PageLoadTiming& timing) override {} |
| void OnConnectEnd(const mojom::PageLoadTiming& timing) override {} |
| void OnDomainLookupStart(const mojom::PageLoadTiming& timing) override {} |
| void OnDomainLookupEnd(const mojom::PageLoadTiming& timing) override {} |
| void OnFirstPaintInPage(const mojom::PageLoadTiming& timing) override {} |
| void OnFirstImagePaintInPage(const mojom::PageLoadTiming& timing) override {} |
| void OnFirstContentfulPaintInPage( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnMonotonicFirstPaintInPage( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnMonotonicFirstContentfulPaintInPage( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnFirstPaintAfterBackForwardCacheRestoreInPage( |
| const mojom::BackForwardCacheTiming& timing, |
| size_t index) override {} |
| void OnFirstInputAfterBackForwardCacheRestoreInPage( |
| const mojom::BackForwardCacheTiming& timing, |
| size_t index) override {} |
| void OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage( |
| const mojom::BackForwardCacheTiming& timing, |
| size_t index) override {} |
| void OnFirstMeaningfulPaintInMainFrameDocument( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnFirstInputInPage(const mojom::PageLoadTiming& timing) override {} |
| void OnUserTimingMarkFullyLoaded( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnUserTimingMarkFullyVisible( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnUserTimingMarkInteractive( |
| const mojom::PageLoadTiming& timing) override {} |
| void OnLoadingBehaviorObserved(content::RenderFrameHost* rfh, |
| int behavior_flags) override {} |
| void OnJavaScriptFrameworksObserved( |
| content::RenderFrameHost* rfh, |
| const blink::JavaScriptFrameworkDetectionResult&) override {} |
| void OnFeaturesUsageObserved( |
| content::RenderFrameHost* rfh, |
| const std::vector<blink::UseCounterFeature>& features) override {} |
| void SetUpSharedMemoryForDroppedFrames( |
| const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) override {} |
| void OnResourceDataUseObserved( |
| content::RenderFrameHost* rfh, |
| const std::vector<mojom::ResourceDataUpdatePtr>& resources) override {} |
| void MediaStartedPlaying( |
| const content::WebContentsObserver::MediaPlayerInfo& video_type, |
| content::RenderFrameHost* render_frame_host) override {} |
| void OnMainFrameIntersectionRectChanged( |
| content::RenderFrameHost* rfh, |
| const gfx::Rect& main_frame_intersection_rect) override {} |
| void OnMainFrameViewportRectChanged( |
| const gfx::Rect& main_frame_viewport_rect) override {} |
| void OnMainFrameAdRectsChanged( |
| const base::flat_map<int, gfx::Rect>& main_frame_ad_rects) override {} |
| ObservePolicy FlushMetricsOnAppEnterBackground( |
| const mojom::PageLoadTiming& timing) override; |
| void OnComplete(const mojom::PageLoadTiming& timing) override {} |
| void OnFailedProvisionalLoad( |
| const FailedProvisionalLoadInfo& failed_provisional_load_info) override {} |
| void OnLoadedResource( |
| const ExtraRequestCompleteInfo& extra_request_complete_info) override {} |
| void FrameReceivedUserActivation( |
| content::RenderFrameHost* render_frame_host) override {} |
| void FrameDisplayStateChanged(content::RenderFrameHost* render_frame_host, |
| bool is_display_none) override {} |
| void FrameSizeChanged(content::RenderFrameHost* render_frame_host, |
| const gfx::Size& frame_size) override {} |
| void OnRenderFrameDeleted( |
| content::RenderFrameHost* render_frame_host) override {} |
| void OnSubFrameDeleted(content::FrameTreeNodeId frame_tree_node_id) override { |
| } |
| void OnCookiesRead( |
| const GURL& url, |
| const GURL& first_party_url, |
| bool blocked_by_policy, |
| bool is_ad_tagged, |
| const net::CookieSettingOverrides& cookie_setting_overrides, |
| bool is_partitioned_access) override {} |
| void OnCookieChange( |
| const GURL& url, |
| const GURL& first_party_url, |
| const net::CanonicalCookie& cookie, |
| bool blocked_by_policy, |
| bool is_ad_tagged, |
| const net::CookieSettingOverrides& cookie_setting_overrides, |
| bool is_partitioned_access) override {} |
| void OnStorageAccessed(const GURL& url, |
| const GURL& first_party_url, |
| bool blocked_by_policy, |
| StorageType access_type) override {} |
| void OnPrefetchLikely() override {} |
| void DidActivatePrerenderedPage( |
| content::NavigationHandle* navigation_handle) override {} |
| void DidActivatePreviewedPage(base::TimeTicks activation_time) override {} |
| void OnV8MemoryChanged( |
| const std::vector<MemoryUpdate>& memory_updates) override {} |
| void OnSharedStorageWorkletHostCreated() override {} |
| void OnSharedStorageSelectURLCalled() override {} |
| void OnCustomUserTimingMarkObserved( |
| const std::vector<mojom::CustomUserTimingMarkPtr>& timings) override {} |
| void OnAdAuctionComplete(bool is_server_auction, |
| bool is_on_device_auction, |
| content::AuctionResult result) override {} |
| void OnPrimaryPageRenderProcessGone() override {} |
| |
| private: |
| raw_ptr<PageLoadMetricsObserverDelegate> delegate_ = nullptr; |
| }; |
| |
| } // namespace page_load_metrics |
| |
| #endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_ |