page_node.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. // Copyright 2019 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_PUBLIC_GRAPH_PAGE_NODE_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
  6. #include <ostream>
  7. #include <string>
  8. #include "base/callback_forward.h"
  9. #include "base/containers/flat_set.h"
  10. #include "components/performance_manager/public/freezing/freezing.h"
  11. #include "components/performance_manager/public/graph/node.h"
  12. #include "components/performance_manager/public/mojom/coordination_unit.mojom.h"
  13. #include "components/performance_manager/public/mojom/lifecycle.mojom.h"
  14. #include "components/performance_manager/public/web_contents_proxy.h"
  15. #include "services/metrics/public/cpp/ukm_source_id.h"
  16. #include "third_party/abseil-cpp/absl/types/optional.h"
  17. class GURL;
  18. namespace performance_manager {
  19. class FrameNode;
  20. class PageNodeObserver;
  21. enum class PageType {
  22. // A browser tab.
  23. kTab,
  24. // An extension background page.
  25. kExtension,
  26. // Anything else.
  27. kUnknown,
  28. };
  29. // A PageNode represents the root of a FrameTree, or equivalently a WebContents.
  30. // These may correspond to normal tabs, WebViews, Portals, Chrome Apps or
  31. // Extensions.
  32. class PageNode : public Node {
  33. public:
  34. using FrameNodeVisitor = base::RepeatingCallback<bool(const FrameNode*)>;
  35. using LifecycleState = mojom::LifecycleState;
  36. using Observer = PageNodeObserver;
  37. class ObserverDefaultImpl;
  38. // Reasons for which a frame can become the embedder of a page.
  39. enum class EmbeddingType {
  40. // Returned if this node doesn't have an embedder.
  41. kInvalid,
  42. // This page is a guest view. This can be many things (<webview>, <appview>,
  43. // etc) but is backed by the same inner/outer WebContents mechanism.
  44. kGuestView,
  45. // This page is a portal.
  46. kPortal,
  47. };
  48. // Returns a string for a PageNode::EmbeddingType enumeration.
  49. static const char* ToString(PageNode::EmbeddingType embedding_type);
  50. // Loading state of a page.
  51. enum class LoadingState {
  52. // No top-level document has started loading yet.
  53. kLoadingNotStarted,
  54. // A different top-level document is loading. The load started less than 5
  55. // seconds ago or the initial response was received.
  56. kLoading,
  57. // A different top-level document is loading. The load started more than 5
  58. // seconds ago and no response was received yet. Note: The state will
  59. // transition back to |kLoading| if a response is received.
  60. kLoadingTimedOut,
  61. // A different top-level document finished loading, but the page did not
  62. // reach CPU and network quiescence since then. Note: A page is considered
  63. // to have reached CPU and network quiescence after 1 minute, even if the
  64. // CPU and network are still busy - see page_load_tracker_decorator.h.
  65. kLoadedBusy,
  66. // The page reached CPU and network quiescence after loading the current
  67. // top-level document, or the load failed.
  68. kLoadedIdle,
  69. };
  70. // Returns a string for an enumeration value.
  71. static const char* ToString(PageType type);
  72. static const char* ToString(PageNode::LoadingState loading_state);
  73. // State of a page. Pages can be born in "kActive" or "kPrerendering" state.
  74. enum class PageState {
  75. // The page is a normal page, that is actively running. Can transition from
  76. // here to kBackForwardCache.
  77. kActive,
  78. // The page is a prerender page. It may do some initial loading but will
  79. // never fully run unless it is activated. Can transition from here to
  80. // kActive, or be destroyed.
  81. kPrerendering,
  82. // The page is in the back-forward cache. The page will be frozen during its
  83. // entire stay in the cache. Can transition from here to kActive or be
  84. // destroyed.
  85. kBackForwardCache,
  86. };
  87. static const char* ToString(PageNode::PageState page_state);
  88. PageNode();
  89. PageNode(const PageNode&) = delete;
  90. PageNode& operator=(const PageNode&) = delete;
  91. ~PageNode() override;
  92. // Returns the unique ID of the browser context that this page belongs to.
  93. virtual const std::string& GetBrowserContextID() const = 0;
  94. // Returns the opener frame node, if there is one. This may change over the
  95. // lifetime of this page. See "OnOpenerFrameNodeChanged".
  96. virtual const FrameNode* GetOpenerFrameNode() const = 0;
  97. // Returns the embedder frame node, if there is one. This may change over the
  98. // lifetime of this page. See "OnEmbedderFrameNodeChanged".
  99. virtual const FrameNode* GetEmbedderFrameNode() const = 0;
  100. // Returns the type of relationship this node has with its embedder, if it has
  101. // an embedder.
  102. virtual EmbeddingType GetEmbeddingType() const = 0;
  103. // Returns the type of the page.
  104. virtual PageType GetType() const = 0;
  105. // Returns true if this page is currently visible, false otherwise.
  106. // See PageNodeObserver::OnIsVisibleChanged.
  107. virtual bool IsVisible() const = 0;
  108. // Returns the time since the last visibility change. It is always well
  109. // defined as the visibility property is set at node creation.
  110. virtual base::TimeDelta GetTimeSinceLastVisibilityChange() const = 0;
  111. // Returns true if this page is currently audible, false otherwise.
  112. // See PageNodeObserver::OnIsAudibleChanged.
  113. virtual bool IsAudible() const = 0;
  114. // Returns the page's loading state.
  115. virtual LoadingState GetLoadingState() const = 0;
  116. // Returns the UKM source ID associated with the URL of the main frame of
  117. // this page.
  118. // See PageNodeObserver::OnUkmSourceIdChanged.
  119. virtual ukm::SourceId GetUkmSourceID() const = 0;
  120. // Returns the lifecycle state of this page. This is aggregated from the
  121. // lifecycle state of each frame in the frame tree. See
  122. // PageNodeObserver::OnPageLifecycleStateChanged.
  123. virtual LifecycleState GetLifecycleState() const = 0;
  124. // Returns true if at least one of the frame in this page is currently
  125. // holding a WebLock.
  126. virtual bool IsHoldingWebLock() const = 0;
  127. // Returns true if at least one of the frame in this page is currently
  128. // holding an IndexedDB lock.
  129. virtual bool IsHoldingIndexedDBLock() const = 0;
  130. // Returns the navigation ID associated with the last committed navigation
  131. // event for the main frame of this page.
  132. // See PageNodeObserver::OnMainFrameNavigationCommitted.
  133. virtual int64_t GetNavigationID() const = 0;
  134. // Returns the MIME type of the contents associated with the last committed
  135. // navigation event for the main frame of this page.
  136. virtual const std::string& GetContentsMimeType() const = 0;
  137. // Returns "zero" if no navigation has happened, otherwise returns the time
  138. // since the last navigation commit.
  139. virtual base::TimeDelta GetTimeSinceLastNavigation() const = 0;
  140. // Returns the current main frame node (if there is one), otherwise returns
  141. // any of the potentially multiple main frames that currently exist. If there
  142. // are no main frames at the moment, returns nullptr.
  143. virtual const FrameNode* GetMainFrameNode() const = 0;
  144. // Visits the main frame nodes associated with this page. The iteration is
  145. // halted if the visitor returns false. Returns true if every call to the
  146. // visitor returned true, false otherwise.
  147. virtual bool VisitMainFrameNodes(const FrameNodeVisitor& visitor) const = 0;
  148. // Returns all of the main frame nodes, both current and otherwise. If there
  149. // are no main frames at the moment, returns the empty set. Note that this
  150. // incurs a full container copy of all main frame nodes. Please use
  151. // VisitMainFrameNodes when that makes sense.
  152. virtual const base::flat_set<const FrameNode*> GetMainFrameNodes() const = 0;
  153. // Returns the URL the main frame last committed a navigation to, or the
  154. // initial URL of the page before navigation. The latter case is distinguished
  155. // by a zero navigation ID.
  156. // See PageNodeObserver::OnMainFrameNavigationCommitted.
  157. virtual const GURL& GetMainFrameUrl() const = 0;
  158. // Indicates if at least one of the frames in the page has received some form
  159. // interactions.
  160. virtual bool HadFormInteraction() const = 0;
  161. // Returns the web contents associated with this page node. It is valid to
  162. // call this function on any thread but the weak pointer must only be
  163. // dereferenced on the UI thread.
  164. virtual const WebContentsProxy& GetContentsProxy() const = 0;
  165. // Indicates if there's a freezing vote for this page node. This has 3
  166. // possible values:
  167. // - absl::nullopt: There's no active freezing vote for this page.
  168. // - freezing::FreezingVoteValue::kCanFreeze: There's one or more positive
  169. // freezing vote for this page and no negative vote.
  170. // - freezing::FreezingVoteValue::kCannotFreeze: There's at least one
  171. // negative freezing vote for this page.
  172. virtual const absl::optional<freezing::FreezingVote>& GetFreezingVote()
  173. const = 0;
  174. // Returns the current page state. See "PageNodeObserver::OnPageStateChanged".
  175. virtual PageState GetPageState() const = 0;
  176. };
  177. // Pure virtual observer interface. Derive from this if you want to be forced to
  178. // implement the entire interface.
  179. class PageNodeObserver {
  180. public:
  181. using PageState = PageNode::PageState;
  182. using EmbeddingType = PageNode::EmbeddingType;
  183. PageNodeObserver();
  184. PageNodeObserver(const PageNodeObserver&) = delete;
  185. PageNodeObserver& operator=(const PageNodeObserver&) = delete;
  186. virtual ~PageNodeObserver();
  187. // Node lifetime notifications.
  188. // Called when a |page_node| is added to the graph. Observers must not make
  189. // any property changes or cause re-entrant notifications during the scope of
  190. // this call. Instead, make property changes via a separate posted task.
  191. virtual void OnPageNodeAdded(const PageNode* page_node) = 0;
  192. // Called before a |page_node| is removed from the graph. Observers must not
  193. // make any property changes or cause re-entrant notifications during the
  194. // scope of this call.
  195. virtual void OnBeforePageNodeRemoved(const PageNode* page_node) = 0;
  196. // Notifications of property changes.
  197. // Invoked when this page has been assigned an opener, had the opener
  198. // change, or had the opener removed. This happens when a page is opened
  199. // via window.open, or when that relationship is subsequently severed or
  200. // reparented.
  201. virtual void OnOpenerFrameNodeChanged(const PageNode* page_node,
  202. const FrameNode* previous_opener) = 0;
  203. // Invoked when this page has been assigned an embedder, had the embedder
  204. // change, or had the embedder removed. This can happen if a page is opened
  205. // via webviews, guestviews, portals, etc, or when that relationship is
  206. // subsequently severed or reparented.
  207. virtual void OnEmbedderFrameNodeChanged(
  208. const PageNode* page_node,
  209. const FrameNode* previous_embedder,
  210. EmbeddingType previous_embedder_type) = 0;
  211. // Invoked when the GetType property changes.
  212. virtual void OnTypeChanged(const PageNode* page_node) = 0;
  213. // Invoked when the IsVisible property changes.
  214. virtual void OnIsVisibleChanged(const PageNode* page_node) = 0;
  215. // Invoked when the IsAudible property changes.
  216. virtual void OnIsAudibleChanged(const PageNode* page_node) = 0;
  217. // Invoked when the GetLoadingState property changes.
  218. virtual void OnLoadingStateChanged(const PageNode* page_node,
  219. PageNode::LoadingState previous_state) = 0;
  220. // Invoked when the UkmSourceId property changes.
  221. virtual void OnUkmSourceIdChanged(const PageNode* page_node) = 0;
  222. // Invoked when the PageLifecycleState property changes.
  223. virtual void OnPageLifecycleStateChanged(const PageNode* page_node) = 0;
  224. // Invoked when the IsHoldingWebLock property changes.
  225. virtual void OnPageIsHoldingWebLockChanged(const PageNode* page_node) = 0;
  226. // Invoked when the IsHoldingIndexedDBLock property changes.
  227. virtual void OnPageIsHoldingIndexedDBLockChanged(
  228. const PageNode* page_node) = 0;
  229. // Invoked when the MainFrameUrl property changes.
  230. virtual void OnMainFrameUrlChanged(const PageNode* page_node) = 0;
  231. // This is fired when a non-same document navigation commits in the main
  232. // frame. It indicates that the the |NavigationId| property and possibly the
  233. // |MainFrameUrl| properties have changed.
  234. virtual void OnMainFrameDocumentChanged(const PageNode* page_node) = 0;
  235. // Invoked when the HadFormInteraction property changes.
  236. virtual void OnHadFormInteractionChanged(const PageNode* page_node) = 0;
  237. // Invoked when the page state changes. See `PageState` for the valid
  238. // transitions.
  239. virtual void OnPageStateChanged(const PageNode* page_node,
  240. PageState old_state) = 0;
  241. // Events with no property changes.
  242. // Fired when the tab title associated with a page changes. This property is
  243. // not directly reflected on the node.
  244. virtual void OnTitleUpdated(const PageNode* page_node) = 0;
  245. // Fired when the favicon associated with a page is updated. This property is
  246. // not directly reflected on the node.
  247. virtual void OnFaviconUpdated(const PageNode* page_node) = 0;
  248. // Called every time the aggregated freezing vote changes or gets invalidated.
  249. virtual void OnFreezingVoteChanged(
  250. const PageNode* page_node,
  251. absl::optional<freezing::FreezingVote> previous_vote) = 0;
  252. };
  253. // Default implementation of observer that provides dummy versions of each
  254. // function. Derive from this if you only need to implement a few of the
  255. // functions.
  256. class PageNode::ObserverDefaultImpl : public PageNodeObserver {
  257. public:
  258. ObserverDefaultImpl();
  259. ObserverDefaultImpl(const ObserverDefaultImpl&) = delete;
  260. ObserverDefaultImpl& operator=(const ObserverDefaultImpl&) = delete;
  261. ~ObserverDefaultImpl() override;
  262. // PageNodeObserver implementation:
  263. void OnPageNodeAdded(const PageNode* page_node) override {}
  264. void OnBeforePageNodeRemoved(const PageNode* page_node) override {}
  265. void OnPageStateChanged(const PageNode* page_node,
  266. PageState old_state) override {}
  267. void OnOpenerFrameNodeChanged(const PageNode* page_node,
  268. const FrameNode* previous_opener) override {}
  269. void OnEmbedderFrameNodeChanged(
  270. const PageNode* page_node,
  271. const FrameNode* previous_embedder,
  272. EmbeddingType previous_embedding_type) override {}
  273. void OnTypeChanged(const PageNode* page_node) override {}
  274. void OnIsVisibleChanged(const PageNode* page_node) override {}
  275. void OnIsAudibleChanged(const PageNode* page_node) override {}
  276. void OnLoadingStateChanged(const PageNode* page_node,
  277. PageNode::LoadingState previous_state) override {}
  278. void OnUkmSourceIdChanged(const PageNode* page_node) override {}
  279. void OnPageLifecycleStateChanged(const PageNode* page_node) override {}
  280. void OnPageIsHoldingWebLockChanged(const PageNode* page_node) override {}
  281. void OnPageIsHoldingIndexedDBLockChanged(const PageNode* page_node) override {
  282. }
  283. void OnMainFrameUrlChanged(const PageNode* page_node) override {}
  284. void OnMainFrameDocumentChanged(const PageNode* page_node) override {}
  285. void OnHadFormInteractionChanged(const PageNode* page_node) override {}
  286. void OnTitleUpdated(const PageNode* page_node) override {}
  287. void OnFaviconUpdated(const PageNode* page_node) override {}
  288. void OnFreezingVoteChanged(
  289. const PageNode* page_node,
  290. absl::optional<freezing::FreezingVote> previous_vote) override {}
  291. };
  292. // std::ostream support for PageNode::EmbeddingType.
  293. std::ostream& operator<<(
  294. std::ostream& os,
  295. performance_manager::PageNode::EmbeddingType embedding_type);
  296. } // namespace performance_manager
  297. #endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_