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 
5 #ifndef COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_TAB_HELPER_H_
6 #define COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_TAB_HELPER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <vector>
12 
13 #include "base/macros.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "components/performance_manager/public/mojom/coordination_unit.mojom-forward.h"
17 #include "components/performance_manager/web_contents_proxy_impl.h"
18 #include "content/public/browser/web_contents_observer.h"
19 #include "content/public/browser/web_contents_user_data.h"
20 #include "services/metrics/public/cpp/ukm_source_id.h"
21 #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h"
22 
23 namespace performance_manager {
24 
25 class FrameNodeImpl;
26 class PageNodeImpl;
27 
28 // This tab helper maintains a page node, and its associated tree of frame nodes
29 // in the performance manager graph. It also sources a smattering of attributes
30 // into the graph, including visibility, title, and favicon bits.
31 // In addition it handles forwarding interface requests from the render frame
32 // host to the frame graph entity.
33 class PerformanceManagerTabHelper
34     : public content::WebContentsObserver,
35       public content::WebContentsUserData<PerformanceManagerTabHelper>,
36       public WebContentsProxyImpl {
37  public:
38   // Observer interface to be notified when a PerformanceManagerTabHelper is
39   // being teared down.
40   class DestructionObserver {
41    public:
42     virtual ~DestructionObserver() = default;
43     virtual void OnPerformanceManagerTabHelperDestroying(
44         content::WebContents*) = 0;
45   };
46 
47   ~PerformanceManagerTabHelper() override;
48 
page_node()49   PageNodeImpl* page_node() { return page_node_.get(); }
50 
51   // Registers an observer that is notified when the PerformanceManagerTabHelper
52   // is destroyed. Can only be set to non-nullptr if it was previously nullptr,
53   // and vice-versa.
54   void SetDestructionObserver(DestructionObserver* destruction_observer);
55 
56   // Must be invoked prior to detaching a PerformanceManagerTabHelper from its
57   // WebContents.
58   void TearDown();
59 
60   // WebContentsObserver overrides.
61   void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
62   void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
63   void RenderFrameHostChanged(content::RenderFrameHost* old_host,
64                               content::RenderFrameHost* new_host) override;
65   void OnVisibilityChanged(content::Visibility visibility) override;
66   void OnAudioStateChanged(bool audible) override;
67   void DidFinishNavigation(
68       content::NavigationHandle* navigation_handle) override;
69   void TitleWasSet(content::NavigationEntry* entry) override;
70   void WebContentsDestroyed() override;
71   void DidUpdateFaviconURL(
72       const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
73 
74   // WebContentsProxyImpl overrides.
75   content::WebContents* GetWebContents() const override;
76   int64_t LastNavigationId() const override;
77 
78   void BindDocumentCoordinationUnit(
79       content::RenderFrameHost* render_frame_host,
80       mojo::PendingReceiver<mojom::DocumentCoordinationUnit> receiver);
81 
SetUkmSourceIdForTesting(ukm::SourceId id)82   void SetUkmSourceIdForTesting(ukm::SourceId id) { ukm_source_id_ = id; }
83 
84   // Retrieves the frame node associated with |render_frame_host|. Returns
85   // nullptr if none exist for that frame.
86   FrameNodeImpl* GetFrameNode(content::RenderFrameHost* render_frame_host);
87 
88   class Observer : public base::CheckedObserver {
89    public:
90     // Invoked when a frame node is about to be removed from the graph.
91     virtual void OnBeforeFrameNodeRemoved(
92         PerformanceManagerTabHelper* performance_manager,
93         FrameNodeImpl* frame_node) = 0;
94   };
95 
96   // Adds/removes an observer.
97   void AddObserver(Observer* observer);
98   void RemoveObserver(Observer* observer);
99 
100  private:
101   friend class content::WebContentsUserData<PerformanceManagerTabHelper>;
102   friend class PerformanceManagerRegistryImpl;
103   friend class WebContentsProxyImpl;
104 
105   explicit PerformanceManagerTabHelper(content::WebContents* web_contents);
106 
107   // Make CreateForWebContents private to restrict usage to
108   // PerformanceManagerRegistry.
109   using WebContentsUserData<PerformanceManagerTabHelper>::CreateForWebContents;
110 
111   void OnMainFrameNavigation(int64_t navigation_id);
112 
113   std::unique_ptr<PageNodeImpl> page_node_;
114   ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId;
115 
116   // Favicon and title are set when a page is loaded, we only want to send
117   // signals to the page node about title and favicon update from the previous
118   // title and favicon, thus we want to ignore the very first update since it is
119   // always supposed to happen.
120   bool first_time_favicon_set_ = false;
121   bool first_time_title_set_ = false;
122 
123   // The last navigation ID that was committed to a main frame in this web
124   // contents.
125   int64_t last_navigation_id_ = 0;
126 
127   // Maps from RenderFrameHost to the associated PM node.
128   std::map<content::RenderFrameHost*, std::unique_ptr<FrameNodeImpl>> frames_;
129 
130   DestructionObserver* destruction_observer_ = nullptr;
131   base::ObserverList<Observer, true, false> observers_;
132 
133   WEB_CONTENTS_USER_DATA_KEY_DECL();
134 
135   base::WeakPtrFactory<PerformanceManagerTabHelper> weak_factory_{this};
136 
137   DISALLOW_COPY_AND_ASSIGN(PerformanceManagerTabHelper);
138 };
139 
140 }  // namespace performance_manager
141 
142 #endif  // COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_TAB_HELPER_H_
143