performance_manager_tab_helper.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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_PERFORMANCE_MANAGER_TAB_HELPER_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_TAB_HELPER_H_
  6. #include <map>
  7. #include <memory>
  8. #include <vector>
  9. #include "base/containers/flat_set.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/observer_list.h"
  13. #include "components/performance_manager/public/mojom/coordination_unit.mojom-forward.h"
  14. #include "components/performance_manager/web_contents_proxy_impl.h"
  15. #include "content/public/browser/web_contents_observer.h"
  16. #include "content/public/browser/web_contents_user_data.h"
  17. #include "services/metrics/public/cpp/ukm_source_id.h"
  18. #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h"
  19. namespace performance_manager {
  20. class FrameNodeImpl;
  21. class PageNodeImpl;
  22. // This tab helper maintains a page node, and its associated tree of frame nodes
  23. // in the performance manager graph. It also sources a smattering of attributes
  24. // into the graph, including visibility, title, and favicon bits.
  25. // In addition it handles forwarding interface requests from the render frame
  26. // host to the frame graph entity.
  27. class PerformanceManagerTabHelper
  28. : public content::WebContentsObserver,
  29. public content::WebContentsUserData<PerformanceManagerTabHelper>,
  30. public WebContentsProxyImpl {
  31. public:
  32. // Observer interface to be notified when a PerformanceManagerTabHelper is
  33. // being teared down.
  34. class DestructionObserver {
  35. public:
  36. virtual ~DestructionObserver() = default;
  37. virtual void OnPerformanceManagerTabHelperDestroying(
  38. content::WebContents*) = 0;
  39. };
  40. PerformanceManagerTabHelper(const PerformanceManagerTabHelper&) = delete;
  41. PerformanceManagerTabHelper& operator=(const PerformanceManagerTabHelper&) =
  42. delete;
  43. ~PerformanceManagerTabHelper() override;
  44. // Returns the PageNode associated with the primary page. This can change
  45. // during the WebContents lifetime.
  46. PageNodeImpl* primary_page_node() { return primary_page_->page_node.get(); }
  47. // Returns the PageNode assicated with the given RenderFrameHost, or nullptr
  48. // if it doesn't exist.
  49. PageNodeImpl* GetPageNodeForRenderFrameHost(content::RenderFrameHost* rfh);
  50. // Registers an observer that is notified when the PerformanceManagerTabHelper
  51. // is destroyed. Can only be set to non-nullptr if it was previously nullptr,
  52. // and vice-versa.
  53. void SetDestructionObserver(DestructionObserver* destruction_observer);
  54. // Must be invoked prior to detaching a PerformanceManagerTabHelper from its
  55. // WebContents.
  56. void TearDown();
  57. // WebContentsObserver overrides.
  58. void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
  59. void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
  60. void RenderFrameHostChanged(content::RenderFrameHost* old_host,
  61. content::RenderFrameHost* new_host) override;
  62. void OnVisibilityChanged(content::Visibility visibility) override;
  63. void OnAudioStateChanged(bool audible) override;
  64. void OnFrameAudioStateChanged(content::RenderFrameHost* render_frame_host,
  65. bool is_audible) override;
  66. void DidFinishNavigation(
  67. content::NavigationHandle* navigation_handle) override;
  68. void TitleWasSet(content::NavigationEntry* entry) override;
  69. void InnerWebContentsAttached(content::WebContents* inner_web_contents,
  70. content::RenderFrameHost* render_frame_host,
  71. bool is_full_page) override;
  72. void InnerWebContentsDetached(
  73. content::WebContents* inner_web_contents) override;
  74. void WebContentsDestroyed() override;
  75. void DidUpdateFaviconURL(
  76. content::RenderFrameHost* render_frame_host,
  77. const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
  78. // WebContentsProxyImpl overrides. Note that `LastNavigationId()` and
  79. // `LastNewDocNavigationId()` refer to navigations associated with the
  80. // primary page.
  81. content::WebContents* GetWebContents() const override;
  82. int64_t LastNavigationId() const override;
  83. int64_t LastNewDocNavigationId() const override;
  84. void BindDocumentCoordinationUnit(
  85. content::RenderFrameHost* render_frame_host,
  86. mojo::PendingReceiver<mojom::DocumentCoordinationUnit> receiver);
  87. // Retrieves the frame node associated with |render_frame_host|. Returns
  88. // nullptr if none exist for that frame.
  89. FrameNodeImpl* GetFrameNode(content::RenderFrameHost* render_frame_host);
  90. class Observer : public base::CheckedObserver {
  91. public:
  92. // Invoked when a frame node is about to be removed from the graph.
  93. virtual void OnBeforeFrameNodeRemoved(
  94. PerformanceManagerTabHelper* performance_manager,
  95. FrameNodeImpl* frame_node) = 0;
  96. };
  97. // Adds/removes an observer.
  98. void AddObserver(Observer* observer);
  99. void RemoveObserver(Observer* observer);
  100. private:
  101. friend class content::WebContentsUserData<PerformanceManagerTabHelper>;
  102. friend class PerformanceManagerRegistryImpl;
  103. friend class WebContentsProxyImpl;
  104. FRIEND_TEST_ALL_PREFIXES(PerformanceManagerFencedFrameBrowserTest,
  105. FencedFrameDoesNotHaveParentFrameNode);
  106. explicit PerformanceManagerTabHelper(content::WebContents* web_contents);
  107. // Make CreateForWebContents private to restrict usage to
  108. // PerformanceManagerRegistry.
  109. using WebContentsUserData<PerformanceManagerTabHelper>::CreateForWebContents;
  110. void OnMainFrameNavigation(int64_t navigation_id, bool same_doc);
  111. // Data that is tracked per page.
  112. struct PageData {
  113. PageData();
  114. ~PageData();
  115. // The actual page node.
  116. std::unique_ptr<PageNodeImpl> page_node;
  117. // The frame tree node ID of the main frame of this PageNode. This is the
  118. // primary sort key for the PageNode, as it remains constant over its
  119. // lifetime. It allows an abitrary RFH to be mapped to the appropriate
  120. // page via RFH::GetMainFrame()->GetFrameTreeNodeId().
  121. // TODO(crbug.com/1211368): This is not true under MPArch, because the
  122. // frame tree node ID of a prerendered RFH changes when it's activated.
  123. // (Also, until PM's MPArch support is finished, the "main" FrameNode for a
  124. // PageNode can change.) Fortunately `main_frame_tree_node_id` is currently
  125. // only used as a DCHECK that pages are not added twice to the `pages_`
  126. // set. Make `pages_` a simple list, or a set keyed on something else.
  127. int main_frame_tree_node_id = 0;
  128. // The UKM source ID for this page.
  129. ukm::SourceId ukm_source_id = ukm::kInvalidSourceId;
  130. // Favicon and title are set when a page is loaded, we only want to send
  131. // signals to the page node about title and favicon update from the previous
  132. // title and favicon, thus we want to ignore the very first update since it
  133. // is always supposed to happen.
  134. bool first_time_favicon_set = false;
  135. bool first_time_title_set = false;
  136. // The last navigation ID that was committed to a main frame in this web
  137. // contents.
  138. int64_t last_navigation_id = 0;
  139. // Similar to the above, but for the last non same-document navigation
  140. // associated with this WebContents. This is always for a navigation that is
  141. // older or equal to |last_navigation_id_|.
  142. int64_t last_new_doc_navigation_id = 0;
  143. };
  144. // A transparent comparator for PageData. These are keyed by FrameTreeNodeId,
  145. // which is unique per Page.
  146. struct PageDataComparator {
  147. using is_transparent = void;
  148. bool operator()(const std::unique_ptr<PageData>& pd1,
  149. const std::unique_ptr<PageData>& pd2) const {
  150. return pd1->main_frame_tree_node_id < pd2->main_frame_tree_node_id;
  151. }
  152. bool operator()(const std::unique_ptr<PageData>& pd1,
  153. int main_frame_tree_node_id2) const {
  154. return pd1->main_frame_tree_node_id < main_frame_tree_node_id2;
  155. }
  156. bool operator()(int main_frame_tree_node_id1,
  157. const std::unique_ptr<PageData>& pd2) const {
  158. return main_frame_tree_node_id1 < pd2->main_frame_tree_node_id;
  159. }
  160. };
  161. // Stores data related to all pages associated with this WebContents. Multiple
  162. // pages may exist due to things like BFCache, Portals, Prerendering, etc.
  163. // Exactly *one* page will be primary.
  164. base::flat_set<std::unique_ptr<PageData>, PageDataComparator> pages_;
  165. // Tracks the primary page associated with this WebContents.
  166. raw_ptr<PageData> primary_page_ = nullptr;
  167. // Maps from RenderFrameHost to the associated PM node. This is a single
  168. // map across all pages associated with this WebContents.
  169. std::map<content::RenderFrameHost*, std::unique_ptr<FrameNodeImpl>> frames_;
  170. raw_ptr<DestructionObserver> destruction_observer_ = nullptr;
  171. base::ObserverList<Observer, true, false> observers_;
  172. WEB_CONTENTS_USER_DATA_KEY_DECL();
  173. base::WeakPtrFactory<PerformanceManagerTabHelper> weak_factory_{this};
  174. };
  175. } // namespace performance_manager
  176. #endif // COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_TAB_HELPER_H_