| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // 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 page_load_metrics { |
| |
| // Get bucketed value of viewport initial scale from given MobileFriendliness |
| // metrics. |
| int GetBucketedViewportInitialScale(const blink::MobileFriendliness& mf); |
| |
| // Get bucketed value of hardcoded viewport width from given MobileFriendliness |
| // metrics. |
| int GetBucketedViewportHardcodedWidth(const blink::MobileFriendliness& mf); |
| |
| // 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; |
| |
| // How many LayoutBlock instances were created. |
| uint64_t all_layout_block_count = 0; |
| |
| // How many LayoutNG-based LayoutBlock instances were created. |
| uint64_t ng_layout_block_count = 0; |
| |
| // How many times LayoutObject::UpdateLayout() is called. |
| uint64_t all_layout_call_count = 0; |
| |
| // How many times LayoutNG-based LayoutObject::UpdateLayout() is called. |
| uint64_t ng_layout_call_count = 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); |
| |
| // Gets/Sets the delegate. The delegate must outlive the observer and is |
| // normally set when the observer is first registered for the page load. The |
| // delegate can only be set once. |
| const PageLoadMetricsObserverDelegate& GetDelegate() const; |
| void SetDelegate(PageLoadMetricsObserverDelegate*); |
| |
| // PageLoadMetricsObserverInterface implementation: |
| const char* GetObserverName() const override; |
| ObservePolicy OnStart(content::NavigationHandle* navigation_handle, |
| const GURL& currently_committed_url, |
| bool started_in_foreground) override; |
| ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle, |
| const GURL& currently_committed_url) 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; |
| void OnTimingUpdate(content::RenderFrameHost* subframe_rfh, |
| const mojom::PageLoadTiming& timing) override {} |
| void OnSoftNavigationCountUpdated() override {} |
| void OnMobileFriendlinessUpdate( |
| const blink::MobileFriendliness& mobile_friendliness) override {} |
| void OnInputTimingUpdate( |
| content::RenderFrameHost* subframe_rfh, |
| const mojom::InputTiming& input_timing_delta) override {} |
| void OnPageInputTimingUpdate(uint64_t num_input_events) 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 OnFirstLayout(const mojom::PageLoadTiming& timing) override {} |
| void OnParseStart(const mojom::PageLoadTiming& timing) override {} |
| void OnParseStop(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 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 OnLoadingBehaviorObserved(content::RenderFrameHost* rfh, |
| int behavior_flags) override {} |
| void OnFeaturesUsageObserved( |
| content::RenderFrameHost* rfh, |
| const std::vector<blink::UseCounterFeature>& features) override {} |
| void SetUpSharedMemoryForSmoothness( |
| const base::ReadOnlySharedMemoryRegion& shared_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 {} |
| 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(int frame_tree_node_id) override {} |
| void OnCookiesRead(const GURL& url, |
| const GURL& first_party_url, |
| const net::CookieList& cookie_list, |
| bool blocked_by_policy) override {} |
| void OnCookieChange(const GURL& url, |
| const GURL& first_party_url, |
| const net::CanonicalCookie& cookie, |
| bool blocked_by_policy) override {} |
| void OnStorageAccessed(const GURL& url, |
| const GURL& first_party_url, |
| bool blocked_by_policy, |
| StorageType access_type) override {} |
| void OnPrefetchLikely() override {} |
| void DidActivatePortal(base::TimeTicks activation_time) override {} |
| void DidActivatePrerenderedPage( |
| content::NavigationHandle* navigation_handle) override {} |
| void OnV8MemoryChanged( |
| const std::vector<MemoryUpdate>& memory_updates) override {} |
| |
| private: |
| raw_ptr<PageLoadMetricsObserverDelegate> delegate_ = nullptr; |
| }; |
| |
| } // namespace page_load_metrics |
| |
| #endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_ |