File: third_party_metrics_observer.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (155 lines) | stat: -rw-r--r-- 6,386 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2019 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_OBSERVERS_THIRD_PARTY_METRICS_OBSERVER_H_
#define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_THIRD_PARTY_METRICS_OBSERVER_H_

#include <map>

#include "base/containers/enum_set.h"
#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
#include "url/gurl.h"
#include "url/origin.h"

// Records metrics about third-party storage accesses to a page.
class ThirdPartyMetricsObserver
    : public page_load_metrics::PageLoadMetricsObserver {
 public:
  // TODO(crbug.com/40144431): kUnknown is mostly unused except for passing it
  // as a "dummy" type to RecordUseCounters.  After we factor out AccessType
  // from that method (see other TODOs), we should be able to remove it.
  enum class AccessType {
    kCookieRead,
    kCookieWrite,
    kLocalStorage,
    kSessionStorage,
    kFileSystem,
    kIndexedDb,
    kCacheStorage,
    kUnknown,
    kMaxValue = kUnknown
  };

  ThirdPartyMetricsObserver();

  ThirdPartyMetricsObserver(const ThirdPartyMetricsObserver&) = delete;
  ThirdPartyMetricsObserver& operator=(const ThirdPartyMetricsObserver&) =
      delete;

  ~ThirdPartyMetricsObserver() override;

  // page_load_metrics::PageLoadMetricsObserver:
  const char* GetObserverName() const override;
  ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle,
                                 const GURL& currently_committed_url) override;
  ObservePolicy OnFencedFramesStart(
      content::NavigationHandle* navigation_handle,
      const GURL& currently_committed_url) override;
  ObservePolicy FlushMetricsOnAppEnterBackground(
      const page_load_metrics::mojom::PageLoadTiming& timing) override;
  void FrameReceivedUserActivation(
      content::RenderFrameHost* render_frame_host) override;
  void OnComplete(
      const page_load_metrics::mojom::PageLoadTiming& timing) override;
  void OnLoadedResource(const page_load_metrics::ExtraRequestCompleteInfo&
                            extra_request_complete_info) 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,
                         page_load_metrics::StorageType storage_type) override;
  void OnDidFinishSubFrameNavigation(
      content::NavigationHandle* navigation_handle) override;
  void OnRenderFrameDeleted(
      content::RenderFrameHost* render_frame_host) override;
  void OnTimingUpdate(
      content::RenderFrameHost* subframe_rfh,
      const page_load_metrics::mojom::PageLoadTiming& timing) override;

 private:
  // The info about the types of activities for a third party.
  struct ThirdPartyInfo {
    ThirdPartyInfo();
    ThirdPartyInfo(const ThirdPartyInfo&);
    std::bitset<static_cast<size_t>(AccessType::kMaxValue)> access_types;
    bool activation = false;
  };

  // Returns a pointer to the ThirdPartyInfo in all_third_party_info_ for |url|
  // and |first_party_url|, adding an entry as necessary. The out parameter
  // |is_third_party| indicates whether the two inputs are third party one
  // another and may be true with a nullptr return if the map is full.
  ThirdPartyInfo* GetThirdPartyInfo(const GURL& url,
                                    const GURL& first_party_url,
                                    bool& is_third_party);

  void OnCookieOrStorageAccess(const GURL& url,
                               const GURL& first_party_url,
                               bool blocked_by_policy,
                               AccessType access_type);
  void RecordMetrics(
      const page_load_metrics::mojom::PageLoadTiming& main_frame_timing);

  // Records feature usage for teh |access_type|, and also, when present, for
  // generic access and activation for the |third_party_info|.
  void RecordUseCounters(AccessType access_type,
                         const ThirdPartyInfo* third_party_info);

  AccessType StorageTypeToAccessType(
      page_load_metrics::StorageType storage_type);

  // A map of third parties and the types of activities they have performed.
  //
  // A third party document.cookie / window.localStorage /
  // window.sessionStorage happens when the context's scheme://eTLD+1
  // differs from the main frame's. A third party resource request happens
  // when the URL request's scheme://eTLD+1 differs from the main frame's.
  // For URLs which have no registrable domain, the hostname is used
  // instead.
  std::map<GURL, ThirdPartyInfo> all_third_party_info_;

  // Timing event types used to track which ones we've already recorded timing
  // data for.
  enum class TimingEventType : uint8_t {
    kFirstContentfulPaint = 0,
    kLargestContentfulPaint = 1,

    kMaxValue = kLargestContentfulPaint,
  };
  using TimingEventTypeEnumSet =
      base::EnumSet<TimingEventType,
                    TimingEventType::kFirstContentfulPaint,
                    TimingEventType::kMaxValue>;

  // A set of RenderFrameHosts that we've recorded timing data for. The
  // RenderFrameHosts are later removed when they navigate again or are deleted.
  // Note that we use `base::flat_map` here because at most `kMaxRecordedFrames`
  // entries will be contained in the map.
  base::flat_map<content::RenderFrameHost*, TimingEventTypeEnumSet>
      recorded_frames_;

  // If the page has any blocked_by_policy cookie or DOM storage access (e.g.,
  // block third-party cookies is enabled) then we don't want to record any
  // metrics for the page.
  bool should_record_metrics_ = true;

  // True if this page loaded a third-party font.
  bool third_party_font_loaded_ = false;
};

#endif  // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_THIRD_PARTY_METRICS_OBSERVER_H_