page_node_impl.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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. #ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PAGE_NODE_IMPL_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PAGE_NODE_IMPL_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/containers/flat_set.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/time/time.h"
  12. #include "base/types/pass_key.h"
  13. #include "components/performance_manager/graph/node_attached_data.h"
  14. #include "components/performance_manager/graph/node_base.h"
  15. #include "components/performance_manager/public/freezing/freezing.h"
  16. #include "components/performance_manager/public/graph/page_node.h"
  17. #include "components/performance_manager/public/web_contents_proxy.h"
  18. #include "third_party/abseil-cpp/absl/types/optional.h"
  19. #include "url/gurl.h"
  20. namespace performance_manager {
  21. class FrameNodeImpl;
  22. class FrozenFrameAggregatorAccess;
  23. class PageAggregatorAccess;
  24. class PageLoadTrackerAccess;
  25. class SiteDataAccess;
  26. class PageNodeImpl
  27. : public PublicNodeImpl<PageNodeImpl, PageNode>,
  28. public TypedNodeBase<PageNodeImpl, PageNode, PageNodeObserver> {
  29. public:
  30. using PassKey = base::PassKey<PageNodeImpl>;
  31. using FrozenFrameDataStorage =
  32. InternalNodeAttachedDataStorage<sizeof(uintptr_t) + 8>;
  33. using PageAggregatorDataStorage =
  34. InternalNodeAttachedDataStorage<sizeof(uintptr_t) + 12>;
  35. static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kPage; }
  36. PageNodeImpl(const WebContentsProxy& contents_proxy,
  37. const std::string& browser_context_id,
  38. const GURL& visible_url,
  39. bool is_visible,
  40. bool is_audible,
  41. base::TimeTicks visibility_change_time,
  42. PageState page_state);
  43. PageNodeImpl(const PageNodeImpl&) = delete;
  44. PageNodeImpl& operator=(const PageNodeImpl&) = delete;
  45. ~PageNodeImpl() override;
  46. // Returns the web contents associated with this page node. It is valid to
  47. // call this function on any thread but the weak pointer must only be
  48. // dereferenced on the UI thread.
  49. const WebContentsProxy& contents_proxy() const;
  50. void SetType(PageType type);
  51. void SetIsVisible(bool is_visible);
  52. void SetIsAudible(bool is_audible);
  53. void SetLoadingState(LoadingState loading_state);
  54. void SetUkmSourceId(ukm::SourceId ukm_source_id);
  55. void OnFaviconUpdated();
  56. void OnTitleUpdated();
  57. void OnMainFrameNavigationCommitted(bool same_document,
  58. base::TimeTicks navigation_committed_time,
  59. int64_t navigation_id,
  60. const GURL& url,
  61. const std::string& contents_mime_type);
  62. // Returns 0 if no navigation has happened, otherwise returns the time since
  63. // the last navigation commit.
  64. base::TimeDelta TimeSinceLastNavigation() const;
  65. // Returns the time since the last visibility change, it should always have a
  66. // value since we set the visibility property when we create a
  67. // page node.
  68. base::TimeDelta TimeSinceLastVisibilityChange() const;
  69. // Returns the current main frame node (if there is one), otherwise returns
  70. // any of the potentially multiple main frames that currently exist. If there
  71. // are no main frames at the moment, returns nullptr.
  72. FrameNodeImpl* GetMainFrameNodeImpl() const;
  73. // Accessors.
  74. const std::string& browser_context_id() const;
  75. FrameNodeImpl* opener_frame_node() const;
  76. FrameNodeImpl* embedder_frame_node() const;
  77. EmbeddingType embedding_type() const;
  78. PageType type() const;
  79. bool is_visible() const;
  80. bool is_audible() const;
  81. LoadingState loading_state() const;
  82. ukm::SourceId ukm_source_id() const;
  83. LifecycleState lifecycle_state() const;
  84. bool is_holding_weblock() const;
  85. bool is_holding_indexeddb_lock() const;
  86. const base::flat_set<FrameNodeImpl*>& main_frame_nodes() const;
  87. base::TimeTicks usage_estimate_time() const;
  88. uint64_t private_footprint_kb_estimate() const;
  89. const GURL& main_frame_url() const;
  90. int64_t navigation_id() const;
  91. const std::string& contents_mime_type() const;
  92. bool had_form_interaction() const;
  93. const absl::optional<freezing::FreezingVote>& freezing_vote() const;
  94. PageState page_state() const;
  95. // Invoked to set/clear the opener of this page.
  96. void SetOpenerFrameNode(FrameNodeImpl* opener);
  97. void ClearOpenerFrameNode();
  98. // Invoked to set/clear the embedder of this page.
  99. void SetEmbedderFrameNodeAndEmbeddingType(FrameNodeImpl* embedder,
  100. EmbeddingType embedder_type);
  101. void ClearEmbedderFrameNodeAndEmbeddingType();
  102. void set_usage_estimate_time(base::TimeTicks usage_estimate_time);
  103. void set_private_footprint_kb_estimate(
  104. uint64_t private_footprint_kb_estimate);
  105. void set_has_nonempty_beforeunload(bool has_nonempty_beforeunload);
  106. void set_freezing_vote(absl::optional<freezing::FreezingVote> freezing_vote);
  107. void set_page_state(PageState page_state);
  108. void SetLifecycleStateForTesting(LifecycleState lifecycle_state) {
  109. SetLifecycleState(lifecycle_state);
  110. }
  111. void SetIsHoldingWebLockForTesting(bool is_holding_weblock) {
  112. SetIsHoldingWebLock(is_holding_weblock);
  113. }
  114. void SetIsHoldingIndexedDBLockForTesting(bool is_holding_weblock) {
  115. SetIsHoldingIndexedDBLock(is_holding_weblock);
  116. }
  117. void SetHadFormInteractionForTesting(bool had_form_interaction) {
  118. SetHadFormInteraction(had_form_interaction);
  119. }
  120. base::WeakPtr<PageNodeImpl> GetWeakPtrOnUIThread() {
  121. // TODO(siggi): Validate thread context.
  122. return weak_this_;
  123. }
  124. base::WeakPtr<PageNodeImpl> GetWeakPtr() {
  125. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  126. return weak_factory_.GetWeakPtr();
  127. }
  128. // Accessors to some of the NodeAttachedData:
  129. std::unique_ptr<NodeAttachedData>& GetSiteData(
  130. base::PassKey<SiteDataAccess>) {
  131. return site_data_;
  132. }
  133. std::unique_ptr<NodeAttachedData>& GetPageLoadTrackerData(
  134. base::PassKey<PageLoadTrackerAccess>) {
  135. return page_load_tracker_data_;
  136. }
  137. FrozenFrameDataStorage& GetFrozenFrameData(
  138. base::PassKey<FrozenFrameAggregatorAccess>) {
  139. return frozen_frame_data_;
  140. }
  141. PageAggregatorDataStorage& GetPageAggregatorData(
  142. base::PassKey<PageAggregatorAccess>) {
  143. return page_aggregator_data_;
  144. }
  145. // Functions meant to be called by a FrameNodeImpl:
  146. void AddFrame(base::PassKey<FrameNodeImpl>, FrameNodeImpl* frame_node);
  147. void RemoveFrame(base::PassKey<FrameNodeImpl>, FrameNodeImpl* frame_node);
  148. // Function meant to be called by FrozenFrameAggregatorAccess.
  149. void SetLifecycleState(base::PassKey<FrozenFrameAggregatorAccess>,
  150. LifecycleState lifecycle_state) {
  151. SetLifecycleState(lifecycle_state);
  152. }
  153. // Functions meant to be called by PageAggregatorAccess:
  154. void SetIsHoldingWebLock(base::PassKey<PageAggregatorAccess>,
  155. bool is_holding_weblock) {
  156. SetIsHoldingWebLock(is_holding_weblock);
  157. }
  158. void SetIsHoldingIndexedDBLock(base::PassKey<PageAggregatorAccess>,
  159. bool is_holding_indexeddb_lock) {
  160. SetIsHoldingIndexedDBLock(is_holding_indexeddb_lock);
  161. }
  162. void SetHadFormInteraction(base::PassKey<PageAggregatorAccess>,
  163. bool had_form_interaction) {
  164. SetHadFormInteraction(had_form_interaction);
  165. }
  166. private:
  167. friend class PageNodeImplDescriber;
  168. // PageNode implementation.
  169. PageState GetPageState() const override;
  170. const std::string& GetBrowserContextID() const override;
  171. const FrameNode* GetOpenerFrameNode() const override;
  172. const FrameNode* GetEmbedderFrameNode() const override;
  173. EmbeddingType GetEmbeddingType() const override;
  174. PageType GetType() const override;
  175. bool IsVisible() const override;
  176. base::TimeDelta GetTimeSinceLastVisibilityChange() const override;
  177. bool IsAudible() const override;
  178. LoadingState GetLoadingState() const override;
  179. ukm::SourceId GetUkmSourceID() const override;
  180. LifecycleState GetLifecycleState() const override;
  181. bool IsHoldingWebLock() const override;
  182. bool IsHoldingIndexedDBLock() const override;
  183. int64_t GetNavigationID() const override;
  184. const std::string& GetContentsMimeType() const override;
  185. base::TimeDelta GetTimeSinceLastNavigation() const override;
  186. const FrameNode* GetMainFrameNode() const override;
  187. bool VisitMainFrameNodes(const FrameNodeVisitor& visitor) const override;
  188. const base::flat_set<const FrameNode*> GetMainFrameNodes() const override;
  189. const GURL& GetMainFrameUrl() const override;
  190. bool HadFormInteraction() const override;
  191. const WebContentsProxy& GetContentsProxy() const override;
  192. const absl::optional<freezing::FreezingVote>& GetFreezingVote()
  193. const override;
  194. // NodeBase:
  195. void OnJoiningGraph() override;
  196. void OnBeforeLeavingGraph() override;
  197. void RemoveNodeAttachedData() override;
  198. void SetLifecycleState(LifecycleState lifecycle_state);
  199. void SetIsHoldingWebLock(bool is_holding_weblock);
  200. void SetIsHoldingIndexedDBLock(bool is_holding_indexeddb_lock);
  201. void SetHadFormInteraction(bool had_form_interaction);
  202. // The WebContentsProxy associated with this page.
  203. const WebContentsProxy contents_proxy_;
  204. // The main frame nodes of this page. There can be more than one main frame
  205. // in a page, among other reasons because during main frame navigation, the
  206. // pending navigation will coexist with the existing main frame until it's
  207. // committed.
  208. base::flat_set<FrameNodeImpl*> main_frame_nodes_
  209. GUARDED_BY_CONTEXT(sequence_checker_);
  210. // The total count of frames that tally up to this page.
  211. size_t frame_node_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
  212. // The last time at which the page visibility changed.
  213. base::TimeTicks visibility_change_time_ GUARDED_BY_CONTEXT(sequence_checker_);
  214. // The last time at which a main frame navigation was committed.
  215. base::TimeTicks navigation_committed_time_
  216. GUARDED_BY_CONTEXT(sequence_checker_);
  217. // The time the most recent resource usage estimate applies to.
  218. base::TimeTicks usage_estimate_time_ GUARDED_BY_CONTEXT(sequence_checker_);
  219. // The most current memory footprint estimate.
  220. uint64_t private_footprint_kb_estimate_
  221. GUARDED_BY_CONTEXT(sequence_checker_) = 0;
  222. // Indicates whether or not this page has a non-empty beforeunload handler.
  223. // This is an aggregation of the same value on each frame in the page's frame
  224. // tree. The aggregation is made at the moment all frames associated with a
  225. // page have transition to frozen.
  226. bool has_nonempty_beforeunload_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  227. // The URL the main frame last committed, or the initial URL a page was
  228. // initialized with. The latter case is distinguished by a zero navigation ID.
  229. ObservedProperty::
  230. NotifiesOnlyOnChanges<GURL, &PageNodeObserver::OnMainFrameUrlChanged>
  231. main_frame_url_ GUARDED_BY_CONTEXT(sequence_checker_);
  232. // The unique ID of the navigation handle the main frame last committed, or
  233. // zero if the page has never committed a navigation.
  234. int64_t navigation_id_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
  235. // The MIME type of the content associated with the last committed navigation
  236. // event for the main frame of this page or an empty string if the page has
  237. // never committed a navigation
  238. std::string contents_mime_type_ GUARDED_BY_CONTEXT(sequence_checker_);
  239. // The unique ID of the browser context that this page belongs to.
  240. const std::string browser_context_id_;
  241. // The opener of this page, if there is one.
  242. raw_ptr<FrameNodeImpl> opener_frame_node_
  243. GUARDED_BY_CONTEXT(sequence_checker_) = nullptr;
  244. // The embedder of this page, if there is one.
  245. raw_ptr<FrameNodeImpl> embedder_frame_node_
  246. GUARDED_BY_CONTEXT(sequence_checker_) = nullptr;
  247. // The way in which this page was embedded, if it was embedded.
  248. EmbeddingType embedding_type_ GUARDED_BY_CONTEXT(sequence_checker_) =
  249. EmbeddingType::kInvalid;
  250. // The type of the page.
  251. ObservedProperty::NotifiesOnlyOnChanges<PageType,
  252. &PageNodeObserver::OnTypeChanged>
  253. type_ GUARDED_BY_CONTEXT(sequence_checker_){PageType::kUnknown};
  254. // Whether or not the page is visible. Driven by browser instrumentation.
  255. // Initialized on construction.
  256. ObservedProperty::NotifiesOnlyOnChanges<bool,
  257. &PageNodeObserver::OnIsVisibleChanged>
  258. is_visible_ GUARDED_BY_CONTEXT(sequence_checker_){false};
  259. // Whether or not the page is audible. Driven by browser instrumentation.
  260. // Initialized on construction.
  261. ObservedProperty::NotifiesOnlyOnChanges<bool,
  262. &PageNodeObserver::OnIsAudibleChanged>
  263. is_audible_ GUARDED_BY_CONTEXT(sequence_checker_){false};
  264. // The loading state. This is driven by instrumentation in the browser
  265. // process.
  266. ObservedProperty::NotifiesOnlyOnChangesWithPreviousValue<
  267. LoadingState,
  268. LoadingState,
  269. &PageNodeObserver::OnLoadingStateChanged>
  270. loading_state_ GUARDED_BY_CONTEXT(sequence_checker_){
  271. LoadingState::kLoadingNotStarted};
  272. // The UKM source ID associated with the URL of the main frame of this page.
  273. ObservedProperty::NotifiesOnlyOnChanges<
  274. ukm::SourceId,
  275. &PageNodeObserver::OnUkmSourceIdChanged>
  276. ukm_source_id_ GUARDED_BY_CONTEXT(sequence_checker_){
  277. ukm::kInvalidSourceId};
  278. // The lifecycle state of this page. This is aggregated from the lifecycle
  279. // state of each frame in the frame tree.
  280. ObservedProperty::NotifiesOnlyOnChanges<
  281. LifecycleState,
  282. &PageNodeObserver::OnPageLifecycleStateChanged>
  283. lifecycle_state_ GUARDED_BY_CONTEXT(sequence_checker_){
  284. LifecycleState::kRunning};
  285. // Indicates if at least one frame of the page is currently holding a WebLock.
  286. ObservedProperty::NotifiesOnlyOnChanges<
  287. bool,
  288. &PageNodeObserver::OnPageIsHoldingWebLockChanged>
  289. is_holding_weblock_ GUARDED_BY_CONTEXT(sequence_checker_){false};
  290. // Indicates if at least one frame of the page is currently holding an
  291. // IndexedDB lock.
  292. ObservedProperty::NotifiesOnlyOnChanges<
  293. bool,
  294. &PageNodeObserver::OnPageIsHoldingIndexedDBLockChanged>
  295. is_holding_indexeddb_lock_ GUARDED_BY_CONTEXT(sequence_checker_){false};
  296. // Indicates if at least one frame of the page has received some form
  297. // interactions.
  298. ObservedProperty::NotifiesOnlyOnChanges<
  299. bool,
  300. &PageNodeObserver::OnHadFormInteractionChanged>
  301. had_form_interaction_ GUARDED_BY_CONTEXT(sequence_checker_){false};
  302. // The freezing vote associated with this page, see the comment of to
  303. // Page::GetFreezingVote for a description of the different values this can
  304. // take.
  305. ObservedProperty::NotifiesOnlyOnChangesWithPreviousValue<
  306. absl::optional<freezing::FreezingVote>,
  307. absl::optional<freezing::FreezingVote>,
  308. &PageNodeObserver::OnFreezingVoteChanged>
  309. freezing_vote_ GUARDED_BY_CONTEXT(sequence_checker_);
  310. // The state of this page.
  311. ObservedProperty::NotifiesOnlyOnChangesWithPreviousValue<
  312. PageState,
  313. PageState,
  314. &PageNodeObserver::OnPageStateChanged>
  315. page_state_ GUARDED_BY_CONTEXT(sequence_checker_){PageState::kActive};
  316. // Storage for PageLoadTracker user data.
  317. std::unique_ptr<NodeAttachedData> page_load_tracker_data_
  318. GUARDED_BY_CONTEXT(sequence_checker_);
  319. // Storage for SiteDataNodeData user data.
  320. std::unique_ptr<NodeAttachedData> site_data_
  321. GUARDED_BY_CONTEXT(sequence_checker_);
  322. // Inline storage for FrozenFrameAggregator user data.
  323. FrozenFrameDataStorage frozen_frame_data_
  324. GUARDED_BY_CONTEXT(sequence_checker_);
  325. // Inline storage for PageAggregatorAccess user data.
  326. PageAggregatorDataStorage page_aggregator_data_
  327. GUARDED_BY_CONTEXT(sequence_checker_);
  328. base::WeakPtr<PageNodeImpl> weak_this_;
  329. base::WeakPtrFactory<PageNodeImpl> weak_factory_
  330. GUARDED_BY_CONTEXT(sequence_checker_){this};
  331. };
  332. } // namespace performance_manager
  333. #endif // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PAGE_NODE_IMPL_H_