blob: b00e881e7f04fb7fc53e91fbf61b8acef4e7a6a4 [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2019 The Chromium Authors
Chris Hamilton3e598872019-05-06 16:15:132// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Sigurdur Asgeirsson51d9d242019-10-07 20:38:345#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_
6#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_
Chris Hamilton3e598872019-05-06 16:15:137
Chris Hamiltonff2b2ced2019-05-30 13:29:058#include <cstdint>
Chris Hamilton8f5839732019-06-27 23:13:089#include <memory>
Patrick Monette6a213b672024-06-07 03:05:2410#include <unordered_set>
Chris Hamiltonff2b2ced2019-05-30 13:29:0511
Chris Hamiltonf3beb682020-07-07 21:23:2212#include "base/dcheck_is_on.h"
Chris Hamilton8f5839732019-06-27 23:13:0813#include "base/memory/ptr_util.h"
Joe Mason7db74f52024-06-17 13:54:3114#include "base/memory/raw_ptr.h"
Joe Masonde0c60f2024-04-16 16:51:4915#include "base/observer_list_types.h"
Joe Mason48ac2fa2025-02-09 05:03:3616#include "base/scoped_observation_traits.h"
Joe Masonbbc660a2024-06-18 15:21:0617#include "base/sequence_checker.h"
Patrick Monette6a213b672024-06-07 03:05:2418#include "components/performance_manager/public/graph/node_set_view.h"
Chris Hamilton3e598872019-05-06 16:15:1319
Chris Hamiltonf48eead2019-07-04 18:07:4020namespace ukm {
21class UkmRecorder;
22} // namespace ukm
23
Chris Hamilton3e598872019-05-06 16:15:1324namespace performance_manager {
25
Chris Hamilton8f5839732019-06-27 23:13:0826class GraphOwned;
Chris Hamilton1b06b3292020-05-06 19:58:0627class GraphRegistered;
Chris Hamilton4a717262019-07-03 15:57:3328class FrameNode;
Chris Hamiltonc8f596e12019-06-03 15:24:5829class FrameNodeObserver;
Chris Hamilton1b06b3292020-05-06 19:58:0630class NodeDataDescriberRegistry;
Chris Hamilton4a717262019-07-03 15:57:3331class PageNode;
Chris Hamiltonc8f596e12019-06-03 15:24:5832class PageNodeObserver;
Chris Hamilton4a717262019-07-03 15:57:3333class ProcessNode;
Chris Hamiltonc8f596e12019-06-03 15:24:5834class ProcessNodeObserver;
Chris Hamilton4a717262019-07-03 15:57:3335class SystemNode;
Chris Hamiltonc8f596e12019-06-03 15:24:5836class SystemNodeObserver;
Patrick Monette514a5432019-08-12 22:00:4737class WorkerNode;
38class WorkerNodeObserver;
Chris Hamiltonc8f596e12019-06-03 15:24:5839
Chris Hamilton1b06b3292020-05-06 19:58:0640template <typename DerivedType>
41class GraphRegisteredImpl;
Sigurdur Asgeirssonfab8e9e2020-04-07 20:22:5742
Chris Hamilton3e598872019-05-06 16:15:1343// Represents a graph of the nodes representing a single browser. Maintains a
44// set of nodes that can be retrieved in different ways, some indexed. Keeps
45// a list of observers that are notified of node addition and removal.
46class Graph {
47 public:
Patrick Monette6a213b672024-06-07 03:05:2448 using NodeSet = std::unordered_set<const Node*>;
49 template <class NodeViewPtr>
50 using NodeSetView = NodeSetView<NodeSet, NodeViewPtr>;
Joe Mason8da0b8f02023-08-04 16:48:3251
Chris Hamilton3e598872019-05-06 16:15:1352 Graph();
Peter Boström09c01822021-09-20 22:43:2753
54 Graph(const Graph&) = delete;
55 Graph& operator=(const Graph&) = delete;
56
Chris Hamilton3e598872019-05-06 16:15:1357 virtual ~Graph();
58
Chris Hamiltonc8f596e12019-06-03 15:24:5859 // Adds an |observer| on the graph. It is safe for observers to stay
60 // registered on the graph at the time of its death.
Chris Hamiltonc8f596e12019-06-03 15:24:5861 virtual void AddFrameNodeObserver(FrameNodeObserver* observer) = 0;
62 virtual void AddPageNodeObserver(PageNodeObserver* observer) = 0;
63 virtual void AddProcessNodeObserver(ProcessNodeObserver* observer) = 0;
64 virtual void AddSystemNodeObserver(SystemNodeObserver* observer) = 0;
Patrick Monette514a5432019-08-12 22:00:4765 virtual void AddWorkerNodeObserver(WorkerNodeObserver* observer) = 0;
Chris Hamiltonc8f596e12019-06-03 15:24:5866
67 // Removes an |observer| from the graph.
Chris Hamiltonc8f596e12019-06-03 15:24:5868 virtual void RemoveFrameNodeObserver(FrameNodeObserver* observer) = 0;
69 virtual void RemovePageNodeObserver(PageNodeObserver* observer) = 0;
70 virtual void RemoveProcessNodeObserver(ProcessNodeObserver* observer) = 0;
71 virtual void RemoveSystemNodeObserver(SystemNodeObserver* observer) = 0;
Patrick Monette514a5432019-08-12 22:00:4772 virtual void RemoveWorkerNodeObserver(WorkerNodeObserver* observer) = 0;
Chris Hamiltonc8f596e12019-06-03 15:24:5873
Chris Hamilton8f5839732019-06-27 23:13:0874 // For convenience, allows you to pass ownership of an object to the graph.
75 // Useful for attaching observers that will live with the graph until it dies.
76 // If you can name the object you can also take it back via "TakeFromGraph".
Chris Hamilton48cf6f02020-09-30 15:43:2177 virtual void PassToGraphImpl(std::unique_ptr<GraphOwned> graph_owned) = 0;
Chris Hamilton8f5839732019-06-27 23:13:0878 virtual std::unique_ptr<GraphOwned> TakeFromGraph(
79 GraphOwned* graph_owned) = 0;
80
Chris Hamilton48cf6f02020-09-30 15:43:2181 // Templated PassToGraph helper that also returns a pointer to the object,
82 // which makes it easy to use PassToGraph in constructors.
83 template <typename DerivedType>
84 DerivedType* PassToGraph(std::unique_ptr<DerivedType> graph_owned) {
85 DerivedType* object = graph_owned.get();
86 PassToGraphImpl(std::move(graph_owned));
87 return object;
88 }
89
Sigurdur Asgeirssond2ee573e2019-08-28 15:20:3890 // A TakeFromGraph helper for taking back the ownership of a GraphOwned
91 // subclass.
Chris Hamilton8f5839732019-06-27 23:13:0892 template <typename DerivedType>
Sigurdur Asgeirssond2ee573e2019-08-28 15:20:3893 std::unique_ptr<DerivedType> TakeFromGraphAs(DerivedType* graph_owned) {
Chris Hamilton8f5839732019-06-27 23:13:0894 return base::WrapUnique(
95 static_cast<DerivedType*>(TakeFromGraph(graph_owned).release()));
96 }
97
Chris Hamilton1b06b3292020-05-06 19:58:0698 // Registers an object with this graph. It is expected that no more than one
99 // object of a given type is registered at a given moment, and that all
100 // registered objects are unregistered before graph tear-down.
101 virtual void RegisterObject(GraphRegistered* object) = 0;
102
103 // Unregisters the provided |object|, which must previously have been
104 // registered with "RegisterObject". It is expected that all registered
105 // objects are unregistered before graph tear-down.
106 virtual void UnregisterObject(GraphRegistered* object) = 0;
107
108 // Returns the registered object of the given type, nullptr if none has been
109 // registered.
110 template <typename DerivedType>
111 DerivedType* GetRegisteredObjectAs() {
Chris Hamiltonf7effeb2020-05-19 21:43:12112 // Be sure to access the TypeId provided by GraphRegisteredImpl, in case
113 // this class has other TypeId implementations.
Chris Hamilton1b06b3292020-05-06 19:58:06114 GraphRegistered* object =
115 GetRegisteredObject(GraphRegisteredImpl<DerivedType>::TypeId());
116 return static_cast<DerivedType*>(object);
117 }
118
Joe Mason8da0b8f02023-08-04 16:48:32119 // Returns the single system node.
Sebastien Marchandb56b8aa9a2021-06-15 14:46:27120 virtual const SystemNode* GetSystemNode() const = 0;
Joe Mason8da0b8f02023-08-04 16:48:32121
Patrick Monetteb981853d2024-06-07 03:38:34122 // Returns a collection of all known nodes of the given type.
Patrick Monette6a213b672024-06-07 03:05:24123 virtual NodeSetView<const ProcessNode*> GetAllProcessNodes() const = 0;
124 virtual NodeSetView<const FrameNode*> GetAllFrameNodes() const = 0;
125 virtual NodeSetView<const PageNode*> GetAllPageNodes() const = 0;
126 virtual NodeSetView<const WorkerNode*> GetAllWorkerNodes() const = 0;
Chris Hamilton4a717262019-07-03 15:57:33127
Sebastien Marchandb56b8aa9a2021-06-15 14:46:27128 // Returns true if the graph only contains the default nodes.
129 virtual bool HasOnlySystemNode() const = 0;
Chris Hamilton417d0372019-11-08 17:13:22130
Chris Hamiltonf48eead2019-07-04 18:07:40131 // Returns the associated UKM recorder if it is defined.
132 virtual ukm::UkmRecorder* GetUkmRecorder() const = 0;
133
Sigurdur Asgeirssonfab8e9e2020-04-07 20:22:57134 // Returns the data describer registry.
135 virtual NodeDataDescriberRegistry* GetNodeDataDescriberRegistry() const = 0;
136
Chris Hamiltonff2b2ced2019-05-30 13:29:05137 // The following functions are implementation detail and should not need to be
138 // used by external clients. They provide the ability to safely downcast to
139 // the underlying implementation.
140 virtual uintptr_t GetImplType() const = 0;
141 virtual const void* GetImpl() const = 0;
142
Chris Hamiltonf3beb682020-07-07 21:23:22143 // Allows code that is not explicitly aware of the Graph sequence to determine
144 // if they are in fact on the right sequence. Prefer to use the
145 // DCHECK_ON_GRAPH_SEQUENCE macro.
146#if DCHECK_IS_ON()
147 virtual bool IsOnGraphSequence() const = 0;
148#endif
149
Chris Hamilton3e598872019-05-06 16:15:13150 private:
Chris Hamilton1b06b3292020-05-06 19:58:06151 // Retrieves the object with the given |type_id|, returning nullptr if none
152 // exists. Clients must use the GetRegisteredObjectAs wrapper instead.
153 virtual GraphRegistered* GetRegisteredObject(uintptr_t type_id) = 0;
Chris Hamilton3e598872019-05-06 16:15:13154};
155
Chris Hamiltonf3beb682020-07-07 21:23:22156#if DCHECK_IS_ON()
157#define DCHECK_ON_GRAPH_SEQUENCE(graph) DCHECK(graph->IsOnGraphSequence())
158#else
159// Compiles to a nop, and will eat ostream input.
160#define DCHECK_ON_GRAPH_SEQUENCE(graph) DCHECK(true)
161#endif
162
Chris Hamilton8f5839732019-06-27 23:13:08163// Helper class for passing ownership of objects to a graph.
164class GraphOwned {
165 public:
166 GraphOwned();
Peter Boström09c01822021-09-20 22:43:27167
168 GraphOwned(const GraphOwned&) = delete;
169 GraphOwned& operator=(const GraphOwned&) = delete;
170
Chris Hamilton8f5839732019-06-27 23:13:08171 virtual ~GraphOwned();
172
173 // Called when the object is passed into the graph.
174 virtual void OnPassedToGraph(Graph* graph) = 0;
175
176 // Called when the object is removed from the graph, either via an explicit
177 // call to Graph::TakeFromGraph, or prior to the Graph being destroyed.
178 virtual void OnTakenFromGraph(Graph* graph) = 0;
Joe Masonbe3fb0f02024-06-14 15:45:22179
Joe Mason7db74f52024-06-17 13:54:31180 // Returns a pointer to the owning Graph. The will return nullptr before
181 // OnPassedToGraph() and after OnTakenFromGraph(), and a valid pointer at all
182 // other times.
Joe Masonbbc660a2024-06-18 15:21:06183 Graph* GetOwningGraph() const;
Joe Mason7db74f52024-06-17 13:54:31184
Joe Masonbe3fb0f02024-06-14 15:45:22185 private:
186 // GraphImpl is allowed to call PassToGraphImpl and TakeFromGraphImpl.
187 friend class GraphImpl;
188
189 // GraphOwnedAndRegistered overrides PassToGraphImpl and TakeFromGraphImpl.
190 template <typename SelfType>
191 friend class GraphOwnedAndRegistered;
192
193 // Only friends can override these. The default implementations just call
194 // OnPassedToGraph() and OnTakenFromGraph(). Helper classes like
195 // GraphOwnedAndRegistered can override these to add actions, while their
196 // subclasses continue to override OnPassedToGraph and OnTakenFromGraph
197 // without having to remember to call the inherited methods.
198 virtual void PassToGraphImpl(Graph* graph);
199 virtual void TakeFromGraphImpl(Graph* graph);
Joe Mason7db74f52024-06-17 13:54:31200
Joe Masonbbc660a2024-06-18 15:21:06201 SEQUENCE_CHECKER(sequence_checker_);
202
Joe Mason7db74f52024-06-17 13:54:31203 // Pointer back to the owning graph.
Joe Masonbbc660a2024-06-18 15:21:06204 raw_ptr<Graph> graph_ GUARDED_BY_CONTEXT(sequence_checker_) = nullptr;
Chris Hamilton8f5839732019-06-27 23:13:08205};
206
207// A default implementation of GraphOwned.
208class GraphOwnedDefaultImpl : public GraphOwned {
209 public:
210 GraphOwnedDefaultImpl();
Peter Boström09c01822021-09-20 22:43:27211
212 GraphOwnedDefaultImpl(const GraphOwnedDefaultImpl&) = delete;
213 GraphOwnedDefaultImpl& operator=(const GraphOwnedDefaultImpl&) = delete;
214
Chris Hamilton8f5839732019-06-27 23:13:08215 ~GraphOwnedDefaultImpl() override;
216
217 // GraphOwned implementation:
218 void OnPassedToGraph(Graph* graph) override {}
219 void OnTakenFromGraph(Graph* graph) override {}
Chris Hamilton8f5839732019-06-27 23:13:08220};
221
Chris Hamilton3e598872019-05-06 16:15:13222} // namespace performance_manager
223
Joe Mason48ac2fa2025-02-09 05:03:36224namespace base {
225
226// Specialize ScopedObservation to invoke the correct add and remove methods for
227// each node observer type. These must be in the same namespace as
228// base::ScopedObservationTraits.
229
230template <>
231struct ScopedObservationTraits<performance_manager::Graph,
232 performance_manager::FrameNodeObserver> {
233 static void AddObserver(performance_manager::Graph* graph,
234 performance_manager::FrameNodeObserver* observer) {
235 graph->AddFrameNodeObserver(observer);
236 }
237 static void RemoveObserver(performance_manager::Graph* graph,
238 performance_manager::FrameNodeObserver* observer) {
239 graph->RemoveFrameNodeObserver(observer);
240 }
241};
242
243template <>
244struct ScopedObservationTraits<performance_manager::Graph,
245 performance_manager::PageNodeObserver> {
246 static void AddObserver(performance_manager::Graph* graph,
247 performance_manager::PageNodeObserver* observer) {
248 graph->AddPageNodeObserver(observer);
249 }
250 static void RemoveObserver(performance_manager::Graph* graph,
251 performance_manager::PageNodeObserver* observer) {
252 graph->RemovePageNodeObserver(observer);
253 }
254};
255
256template <>
257struct ScopedObservationTraits<performance_manager::Graph,
258 performance_manager::ProcessNodeObserver> {
259 static void AddObserver(performance_manager::Graph* graph,
260 performance_manager::ProcessNodeObserver* observer) {
261 graph->AddProcessNodeObserver(observer);
262 }
263 static void RemoveObserver(
264 performance_manager::Graph* graph,
265 performance_manager::ProcessNodeObserver* observer) {
266 graph->RemoveProcessNodeObserver(observer);
267 }
268};
269
270template <>
271struct ScopedObservationTraits<performance_manager::Graph,
272 performance_manager::SystemNodeObserver> {
273 static void AddObserver(performance_manager::Graph* graph,
274 performance_manager::SystemNodeObserver* observer) {
275 graph->AddSystemNodeObserver(observer);
276 }
277 static void RemoveObserver(
278 performance_manager::Graph* graph,
279 performance_manager::SystemNodeObserver* observer) {
280 graph->RemoveSystemNodeObserver(observer);
281 }
282};
283
284template <>
285struct ScopedObservationTraits<performance_manager::Graph,
286 performance_manager::WorkerNodeObserver> {
287 static void AddObserver(performance_manager::Graph* graph,
288 performance_manager::WorkerNodeObserver* observer) {
289 graph->AddWorkerNodeObserver(observer);
290 }
291 static void RemoveObserver(
292 performance_manager::Graph* graph,
293 performance_manager::WorkerNodeObserver* observer) {
294 graph->RemoveWorkerNodeObserver(observer);
295 }
296};
297
298} // namespace base
299
Sigurdur Asgeirsson51d9d242019-10-07 20:38:34300#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_