PM: Start moving performance manager to components/.
This moves the performance manager and the graph implementation
as well as the public API to a new component.
Bug: 953031
Change-Id: Ie96011bbe615e31f183da8aae24a20b6e9c79228
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1829911
Commit-Queue: Sébastien Marchand <[email protected]>
Reviewed-by: Robert Kaplow <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Reviewed-by: Chris Hamilton <[email protected]>
Reviewed-by: Avi Drissman <[email protected]>
Reviewed-by: Cait Phillips <[email protected]>
Cr-Commit-Position: refs/heads/master@{#703442}
diff --git a/components/performance_manager/public/graph/frame_node.h b/components/performance_manager/public/graph/frame_node.h
new file mode 100644
index 0000000..2957a69
--- /dev/null
+++ b/components/performance_manager/public/graph/frame_node.h
@@ -0,0 +1,247 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_FRAME_NODE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_FRAME_NODE_H_
+
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "components/performance_manager/public/frame_priority/frame_priority.h"
+#include "components/performance_manager/public/graph/node.h"
+#include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
+#include "services/resource_coordinator/public/mojom/lifecycle.mojom.h"
+
+class GURL;
+
+namespace base {
+class UnguessableToken;
+} // namespace base
+
+namespace performance_manager {
+
+class FrameNodeObserver;
+class PageNode;
+class ProcessNode;
+class WorkerNode;
+
+// Frame nodes form a tree structure, each FrameNode at most has one parent that
+// is a FrameNode. Conceptually, a frame corresponds to a
+// content::RenderFrameHost in the browser, and a content::RenderFrameImpl /
+// blink::LocalFrame/blink::Document in a renderer.
+//
+// Note that a frame in a frame tree can be replaced with another, with the
+// continuity of that position represented via the |frame_tree_node_id|. It is
+// possible to have multiple "sibling" nodes that share the same
+// |frame_tree_node_id|. Only one of these may contribute to the content being
+// rendered, and this node is designated the "current" node in content
+// terminology. A swap is effectively atomic but will take place in two steps
+// in the graph: the outgoing frame will first be marked as not current, and the
+// incoming frame will be marked as current. As such, the graph invariant is
+// that there will be 0 or 1 |is_current| frames with a given
+// |frame_tree_node_id|.
+//
+// This occurs when a frame is navigated and the existing frame can't be reused.
+// In that case a "provisional" frame is created to start the navigation. Once
+// the navigation completes (which may actually involve a redirect to another
+// origin meaning the frame has to be destroyed and another one created in
+// another process!) and commits, the frame will be swapped with the previously
+// active frame.
+//
+// It is only valid to access this object on the sequence of the graph that owns
+// it.
+class FrameNode : public Node {
+ public:
+ using LifecycleState = resource_coordinator::mojom::LifecycleState;
+ using InterventionPolicy = resource_coordinator::mojom::InterventionPolicy;
+ using Observer = FrameNodeObserver;
+ using PriorityAndReason = frame_priority::PriorityAndReason;
+
+ class ObserverDefaultImpl;
+
+ FrameNode();
+ ~FrameNode() override;
+
+ // Returns the parent of this frame node. This may be null if this frame node
+ // is the main (root) node of a frame tree. This is a constant over the
+ // lifetime of the frame.
+ virtual const FrameNode* GetParentFrameNode() const = 0;
+
+ // Returns the page node to which this frame belongs. This is a constant over
+ // the lifetime of the frame.
+ virtual const PageNode* GetPageNode() const = 0;
+
+ // Returns the process node with which this frame belongs. This is a constant
+ // over the lifetime of the frame.
+ virtual const ProcessNode* GetProcessNode() const = 0;
+
+ // Gets the FrameTree node ID associated with this node. There may be multiple
+ // sibling nodes with the same frame tree node ID, but at most 1 of them may
+ // be current at a time. This is a constant over the lifetime of the frame.
+ virtual int GetFrameTreeNodeId() const = 0;
+
+ // Gets the devtools token associated with this frame. This is a constant over
+ // the lifetime of the frame.
+ virtual const base::UnguessableToken& GetDevToolsToken() const = 0;
+
+ // Gets the ID of the browsing instance to which this frame belongs. This is a
+ // constant over the lifetime of the frame.
+ virtual int32_t GetBrowsingInstanceId() const = 0;
+
+ // Gets the ID of the site instance to which this frame belongs. This is a
+ // constant over the lifetime of the frame.
+ virtual int32_t GetSiteInstanceId() const = 0;
+
+ // A frame is a main frame if it has no parent FrameNode. This can be
+ // called from any thread.
+ virtual bool IsMainFrame() const = 0;
+
+ // Returns the set of child frame associated with this frame. Note that this
+ // incurs a full container copy of all child nodes. Please use ForEach when
+ // that makes sense.
+ virtual const base::flat_set<const FrameNode*> GetChildFrameNodes() const = 0;
+
+ // Returns the current lifecycle state of this frame. See
+ // FrameNodeObserver::OnFrameLifecycleStateChanged.
+ virtual LifecycleState GetLifecycleState() const = 0;
+
+ // Returns the freeze policy set via origin trial. kDefault when no freeze
+ // policy is set via origin trial.
+ virtual InterventionPolicy GetOriginTrialFreezePolicy() const = 0;
+
+ // Returns true if this frame had a non-empty before-unload handler at the
+ // time of its last transition to the frozen lifecycle state. This is only
+ // meaningful while the object is frozen.
+ virtual bool HasNonemptyBeforeUnload() const = 0;
+
+ // Returns the URL associated with this frame.
+ // See FrameNodeObserver::OnURLChanged.
+ virtual const GURL& GetURL() const = 0;
+
+ // Returns true if this frame is current (is part of a content::FrameTree).
+ // See FrameNodeObserver::OnIsCurrentChanged.
+ virtual bool IsCurrent() const = 0;
+
+ // Returns true if this frames use of the network is "almost idle", indicating
+ // that it is not doing any heavy loading work.
+ virtual bool GetNetworkAlmostIdle() const = 0;
+
+ // Returns true if this frame is ad frame. This can change from false to true
+ // over the lifetime of the frame, but once it is true it will always remain
+ // true.
+ virtual bool IsAdFrame() const = 0;
+
+ // Returns true if this frame holds at least one Web Lock.
+ virtual bool HoldsWebLock() const = 0;
+
+ // Returns true if this frame holds at least one IndexedDB lock. An IndexedDB
+ // lock is held by an active transaction or an active DB open request.
+ virtual bool HoldsIndexedDBLock() const = 0;
+
+ // Returns the child workers of this frame. These are either dedicated workers
+ // or shared workers created by this frame, or a service worker that handles
+ // this frame's network requests.
+ virtual const base::flat_set<const WorkerNode*> GetChildWorkerNodes()
+ const = 0;
+
+ // Returns the current priority of the frame, and the reason for the frame
+ // having that particular priority.
+ virtual const PriorityAndReason& GetPriorityAndReason() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrameNode);
+};
+
+// Pure virtual observer interface. Derive from this if you want to be forced to
+// implement the entire interface.
+class FrameNodeObserver {
+ public:
+ using InterventionPolicy = resource_coordinator::mojom::InterventionPolicy;
+
+ FrameNodeObserver();
+ virtual ~FrameNodeObserver();
+
+ // Node lifetime notifications.
+
+ // Called when a |frame_node| is added to the graph.
+ virtual void OnFrameNodeAdded(const FrameNode* frame_node) = 0;
+
+ // Called before a |frame_node| is removed from the graph.
+ virtual void OnBeforeFrameNodeRemoved(const FrameNode* frame_node) = 0;
+
+ // Notifications of property changes.
+
+ // Invoked when the IsCurrent property changes.
+ virtual void OnIsCurrentChanged(const FrameNode* frame_node) = 0;
+
+ // Invoked when the NetworkAlmostIdle property changes.
+ virtual void OnNetworkAlmostIdleChanged(const FrameNode* frame_node) = 0;
+
+ // Invoked when the LifecycleState property changes.
+ virtual void OnFrameLifecycleStateChanged(const FrameNode* frame_node) = 0;
+
+ // Invoked when the OriginTrialFreezePolicy changes.
+ virtual void OnOriginTrialFreezePolicyChanged(
+ const FrameNode* frame_node,
+ const InterventionPolicy& previous_value) = 0;
+
+ // Invoked when the URL property changes.
+ virtual void OnURLChanged(const FrameNode* frame_node,
+ const GURL& previous_value) = 0;
+
+ // Invoked when the IsAdFrame property changes.
+ virtual void OnIsAdFrameChanged(const FrameNode* frame_node) = 0;
+
+ // Invoked when the HoldsWebLock() property changes.
+ virtual void OnFrameHoldsWebLockChanged(const FrameNode* frame_node) = 0;
+
+ // Invoked when the HoldsIndexedDBLock() property changes.
+ virtual void OnFrameHoldsIndexedDBLockChanged(
+ const FrameNode* frame_node) = 0;
+
+ // Invoked when the frame priority and reason changes.
+ virtual void OnPriorityAndReasonChanged(const FrameNode* frame_node) = 0;
+
+ // Events with no property changes.
+
+ // Invoked when a non-persistent notification has been issued by the frame.
+ virtual void OnNonPersistentNotificationCreated(
+ const FrameNode* frame_node) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrameNodeObserver);
+};
+
+// Default implementation of observer that provides dummy versions of each
+// function. Derive from this if you only need to implement a few of the
+// functions.
+class FrameNode::ObserverDefaultImpl : public FrameNodeObserver {
+ public:
+ ObserverDefaultImpl();
+ ~ObserverDefaultImpl() override;
+
+ // FrameNodeObserver implementation:
+ void OnFrameNodeAdded(const FrameNode* frame_node) override {}
+ void OnBeforeFrameNodeRemoved(const FrameNode* frame_node) override {}
+ void OnIsCurrentChanged(const FrameNode* frame_node) override {}
+ void OnNetworkAlmostIdleChanged(const FrameNode* frame_node) override {}
+ void OnFrameLifecycleStateChanged(const FrameNode* frame_node) override {}
+ void OnOriginTrialFreezePolicyChanged(
+ const FrameNode* frame_node,
+ const InterventionPolicy& previous_value) override {}
+ void OnURLChanged(const FrameNode* frame_node,
+ const GURL& previous_value) override {}
+ void OnIsAdFrameChanged(const FrameNode* frame_node) override {}
+ void OnFrameHoldsWebLockChanged(const FrameNode* frame_node) override {}
+ void OnFrameHoldsIndexedDBLockChanged(const FrameNode* frame_node) override {}
+ void OnNonPersistentNotificationCreated(
+ const FrameNode* frame_node) override {}
+ void OnPriorityAndReasonChanged(const FrameNode* frame_node) override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_FRAME_NODE_H_
diff --git a/components/performance_manager/public/graph/graph.h b/components/performance_manager/public/graph/graph.h
new file mode 100644
index 0000000..37cd408
--- /dev/null
+++ b/components/performance_manager/public/graph/graph.h
@@ -0,0 +1,147 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_
+
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+
+namespace ukm {
+class UkmRecorder;
+} // namespace ukm
+
+namespace performance_manager {
+
+class GraphObserver;
+class GraphOwned;
+class FrameNode;
+class FrameNodeObserver;
+class PageNode;
+class PageNodeObserver;
+class ProcessNode;
+class ProcessNodeObserver;
+class SystemNode;
+class SystemNodeObserver;
+class WorkerNode;
+class WorkerNodeObserver;
+
+// Represents a graph of the nodes representing a single browser. Maintains a
+// set of nodes that can be retrieved in different ways, some indexed. Keeps
+// a list of observers that are notified of node addition and removal.
+class Graph {
+ public:
+ using Observer = GraphObserver;
+
+ Graph();
+ virtual ~Graph();
+
+ // Adds an |observer| on the graph. It is safe for observers to stay
+ // registered on the graph at the time of its death.
+ virtual void AddGraphObserver(GraphObserver* observer) = 0;
+ virtual void AddFrameNodeObserver(FrameNodeObserver* observer) = 0;
+ virtual void AddPageNodeObserver(PageNodeObserver* observer) = 0;
+ virtual void AddProcessNodeObserver(ProcessNodeObserver* observer) = 0;
+ virtual void AddSystemNodeObserver(SystemNodeObserver* observer) = 0;
+ virtual void AddWorkerNodeObserver(WorkerNodeObserver* observer) = 0;
+
+ // Removes an |observer| from the graph.
+ virtual void RemoveGraphObserver(GraphObserver* observer) = 0;
+ virtual void RemoveFrameNodeObserver(FrameNodeObserver* observer) = 0;
+ virtual void RemovePageNodeObserver(PageNodeObserver* observer) = 0;
+ virtual void RemoveProcessNodeObserver(ProcessNodeObserver* observer) = 0;
+ virtual void RemoveSystemNodeObserver(SystemNodeObserver* observer) = 0;
+ virtual void RemoveWorkerNodeObserver(WorkerNodeObserver* observer) = 0;
+
+ // For convenience, allows you to pass ownership of an object to the graph.
+ // Useful for attaching observers that will live with the graph until it dies.
+ // If you can name the object you can also take it back via "TakeFromGraph".
+ virtual void PassToGraph(std::unique_ptr<GraphOwned> graph_owned) = 0;
+ virtual std::unique_ptr<GraphOwned> TakeFromGraph(
+ GraphOwned* graph_owned) = 0;
+
+ // A TakeFromGraph helper for taking back the ownership of a GraphOwned
+ // subclass.
+ template <typename DerivedType>
+ std::unique_ptr<DerivedType> TakeFromGraphAs(DerivedType* graph_owned) {
+ return base::WrapUnique(
+ static_cast<DerivedType*>(TakeFromGraph(graph_owned).release()));
+ }
+
+ // Returns a collection of all known nodes of the given type.
+ virtual const SystemNode* FindOrCreateSystemNode() = 0;
+ virtual std::vector<const ProcessNode*> GetAllProcessNodes() const = 0;
+ virtual std::vector<const FrameNode*> GetAllFrameNodes() const = 0;
+ virtual std::vector<const PageNode*> GetAllPageNodes() const = 0;
+ virtual std::vector<const WorkerNode*> GetAllWorkerNodes() const = 0;
+
+ // Returns the associated UKM recorder if it is defined.
+ virtual ukm::UkmRecorder* GetUkmRecorder() const = 0;
+
+ // The following functions are implementation detail and should not need to be
+ // used by external clients. They provide the ability to safely downcast to
+ // the underlying implementation.
+ virtual uintptr_t GetImplType() const = 0;
+ virtual const void* GetImpl() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Graph);
+};
+
+// Observer interface for the graph.
+class GraphObserver {
+ public:
+ GraphObserver();
+ virtual ~GraphObserver();
+
+ // Called before the |graph| associated with this observer disappears. This
+ // allows the observer to do any necessary cleanup work. Note that the
+ // observer should remove itself from observing the graph using this
+ // callback.
+ // TODO(chrisha): Make this run before the destructor!
+ // crbug.com/966840
+ virtual void OnBeforeGraphDestroyed(Graph* graph) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GraphObserver);
+};
+
+// Helper class for passing ownership of objects to a graph.
+class GraphOwned {
+ public:
+ GraphOwned();
+ virtual ~GraphOwned();
+
+ // Called when the object is passed into the graph.
+ virtual void OnPassedToGraph(Graph* graph) = 0;
+
+ // Called when the object is removed from the graph, either via an explicit
+ // call to Graph::TakeFromGraph, or prior to the Graph being destroyed.
+ virtual void OnTakenFromGraph(Graph* graph) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GraphOwned);
+};
+
+// A default implementation of GraphOwned.
+class GraphOwnedDefaultImpl : public GraphOwned {
+ public:
+ GraphOwnedDefaultImpl();
+ ~GraphOwnedDefaultImpl() override;
+
+ // GraphOwned implementation:
+ void OnPassedToGraph(Graph* graph) override {}
+ void OnTakenFromGraph(Graph* graph) override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GraphOwnedDefaultImpl);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_H_
diff --git a/components/performance_manager/public/graph/graph_operations.h b/components/performance_manager/public/graph/graph_operations.h
new file mode 100644
index 0000000..8f5d549
--- /dev/null
+++ b/components/performance_manager/public/graph/graph_operations.h
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_OPERATIONS_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_OPERATIONS_H_
+
+#include "base/callback_forward.h"
+#include "base/containers/flat_set.h"
+
+namespace performance_manager {
+
+class FrameNode;
+class PageNode;
+class ProcessNode;
+
+// A collection of utilities for performing common queries and traversals on a
+// graph.
+struct GraphOperations {
+ using FrameNodeVisitor = base::Callback<bool(const FrameNode*)>;
+
+ // Returns the collection of page nodes that are associated with the given
+ // |process|. A page is associated with a process if the page's frame tree
+ // contains 1 or more frames hosted in the given |process|.
+ static base::flat_set<const PageNode*> GetAssociatedPageNodes(
+ const ProcessNode* process);
+
+ // Returns the collection of process nodes associated with the given |page|.
+ // A |process| is associated with a page if the page's frame tree contains 1
+ // or more frames hosted in that |process|.
+ static base::flat_set<const ProcessNode*> GetAssociatedProcessNodes(
+ const PageNode* page);
+
+ // Returns the collection of frame nodes associated with a page. This is
+ // returned in level order, with main frames first (level 0), main frame
+ // children next (level 1), all the way down to the deepest leaf frames.
+ static std::vector<const FrameNode*> GetFrameNodes(const PageNode* page);
+
+ // Traverse the frame tree of a |page| in the given order, invoking the
+ // provided |callable| for each frame node in the tree. If the visitor returns
+ // false then then the iteration is halted.
+ static void VisitFrameTreePreOrder(const PageNode* page,
+ const FrameNodeVisitor& visitor);
+ static void VisitFrameTreePostOrder(const PageNode* page,
+ const FrameNodeVisitor& visitor);
+
+ // Returns true if the given |frame| is in the frame tree associated with the
+ // given |page|.
+ static bool HasFrame(const PageNode* page, const FrameNode* frame);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_GRAPH_OPERATIONS_H_
diff --git a/components/performance_manager/public/graph/node.h b/components/performance_manager/public/graph/node.h
new file mode 100644
index 0000000..ae76e363
--- /dev/null
+++ b/components/performance_manager/public/graph/node.h
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_H_
+
+#include <cstdint>
+
+#include "base/macros.h"
+
+namespace performance_manager {
+
+class Graph;
+
+// Interface that all nodes must implement.
+// TODO(chrisha): Move NodeTypeEnum to the public interface and expose it here,
+// then add FromNode casts on the public node interfaces.
+class Node {
+ public:
+ Node();
+ virtual ~Node();
+
+ // Returns the graph to which this node belongs.
+ virtual Graph* GetGraph() const = 0;
+
+ // The following functions are implementation detail and should not need to be
+ // used by external clients. They provide the ability to safely downcast to
+ // the underlying implementation.
+ virtual uintptr_t GetImplType() const = 0;
+ virtual const void* GetImpl() const = 0;
+
+ // Returns the serialization ID of the given |node|. This is a stable and
+ // opaque value that will always refer only to this node, and never be reused
+ // over the lifetime of the browser.
+ // TODO(chrisha): Deprecate this, and move the logic inside of the only
+ // client using it.
+ static int64_t GetSerializationId(const Node* node);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Node);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_H_
diff --git a/components/performance_manager/public/graph/node_attached_data.h b/components/performance_manager/public/graph/node_attached_data.h
new file mode 100644
index 0000000..88e9561
--- /dev/null
+++ b/components/performance_manager/public/graph/node_attached_data.h
@@ -0,0 +1,137 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_ATTACHED_DATA_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_ATTACHED_DATA_H_
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/macros.h"
+
+namespace performance_manager {
+
+class Node;
+
+// NodeAttachedData allows external observers of the graph to store data that is
+// associated with a graph node, providing lifetime management as a service.
+//
+// External (to performance_manager) implementations of NodeAttachedData should
+// derive from ExternalNodeAttachedDataImpl. For internal implementations refer
+// to NodeAttachedDataImpl and see node_attached_data_impl.h.
+class NodeAttachedData {
+ public:
+ NodeAttachedData();
+ virtual ~NodeAttachedData();
+
+ // Returns the 'key' associated with this type of NodeAttachedData. This needs
+ // to be unique per data type or bad things happen.
+ virtual const void* GetKey() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NodeAttachedData);
+};
+
+// Implements NodeAttachedData for a given UserDataType.
+//
+// In order for a UserDataType to be attached to a node of type |NodeType| it
+// must have a constructor of the form "UserDataType(const NodeType* node)".
+template <typename UserDataType>
+class ExternalNodeAttachedDataImpl : public NodeAttachedData {
+ public:
+ ExternalNodeAttachedDataImpl() = default;
+ ~ExternalNodeAttachedDataImpl() override = default;
+
+ // NodeAttachedData implementation:
+ const void* GetKey() const override { return &kUserDataKey; }
+
+ // Gets the user data for the given |node|, creating it if it doesn't yet
+ // exist.
+ template <typename NodeType>
+ static UserDataType* GetOrCreate(const NodeType* node);
+
+ // Gets the user data for the given |node|, returning nullptr if it doesn't
+ // exist.
+ template <typename NodeType>
+ static UserDataType* Get(const NodeType* node);
+
+ // Destroys the user data associated with the given node, returning true
+ // on success or false if the user data did not exist to begin with.
+ template <typename NodeType>
+ static bool Destroy(const NodeType* node);
+
+ private:
+ static constexpr int kUserDataKey = 0;
+ static const void* UserDataKey() { return &kUserDataKey; }
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalNodeAttachedDataImpl);
+};
+
+// Everything below this point is pure implementation detail.
+
+// Provides access for setting/getting data in the map based storage. Not
+// intended to be used directly, but rather by (External)NodeAttachedDataImpl.
+class NodeAttachedDataMapHelper {
+ public:
+ // Attaches the provided |data| to the provided |node|. This should only be
+ // called if the data does not exist (GetFromMap returns nullptr), and will
+ // DCHECK otherwise.
+ static void AttachInMap(const Node* node,
+ std::unique_ptr<NodeAttachedData> data);
+
+ // Retrieves the data associated with the provided |node| and |key|. This
+ // returns nullptr if no data exists.
+ static NodeAttachedData* GetFromMap(const Node* node, const void* key);
+
+ // Detaches the data associated with the provided |node| and |key|. It is
+ // harmless to call this when no data exists.
+ static std::unique_ptr<NodeAttachedData> DetachFromMap(const Node* node,
+ const void* key);
+};
+
+// Implementation of ExternalNodeAttachedDataImpl, which is declared in the
+// corresponding public header. This helps keep the public headers as clean as
+// possible.
+
+// static
+template <typename UserDataType>
+constexpr int ExternalNodeAttachedDataImpl<UserDataType>::kUserDataKey;
+
+template <typename UserDataType>
+template <typename NodeType>
+UserDataType* ExternalNodeAttachedDataImpl<UserDataType>::GetOrCreate(
+ const NodeType* node) {
+ if (auto* data = Get(node))
+ return data;
+ std::unique_ptr<UserDataType> data = std::make_unique<UserDataType>(node);
+ auto* raw_data = data.get();
+ auto* base = static_cast<const Node*>(node);
+ NodeAttachedDataMapHelper::AttachInMap(base, std::move(data));
+ return raw_data;
+}
+
+template <typename UserDataType>
+template <typename NodeType>
+UserDataType* ExternalNodeAttachedDataImpl<UserDataType>::Get(
+ const NodeType* node) {
+ auto* base = static_cast<const Node*>(node);
+ auto* data = NodeAttachedDataMapHelper::GetFromMap(base, UserDataKey());
+ if (!data)
+ return nullptr;
+ DCHECK_EQ(UserDataKey(), data->GetKey());
+ return static_cast<UserDataType*>(data);
+}
+
+template <typename UserDataType>
+template <typename NodeType>
+bool ExternalNodeAttachedDataImpl<UserDataType>::Destroy(const NodeType* node) {
+ auto* base = static_cast<const Node*>(node);
+ std::unique_ptr<NodeAttachedData> data =
+ NodeAttachedDataMapHelper::DetachFromMap(base, UserDataKey());
+ return data.get();
+}
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_ATTACHED_DATA_H_
diff --git a/components/performance_manager/public/graph/page_node.h b/components/performance_manager/public/graph/page_node.h
new file mode 100644
index 0000000..bc92f77
--- /dev/null
+++ b/components/performance_manager/public/graph/page_node.h
@@ -0,0 +1,198 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
+
+#include <string>
+
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "components/performance_manager/public/graph/node.h"
+#include "components/performance_manager/public/web_contents_proxy.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
+#include "services/resource_coordinator/public/mojom/lifecycle.mojom.h"
+
+class GURL;
+
+namespace performance_manager {
+
+class FrameNode;
+class PageNodeObserver;
+
+// A PageNode represents the root of a FrameTree, or equivalently a WebContents.
+// These may correspond to normal tabs, WebViews, Portals, Chrome Apps or
+// Extensions.
+class PageNode : public Node {
+ public:
+ using InterventionPolicy = resource_coordinator::mojom::InterventionPolicy;
+ using LifecycleState = resource_coordinator::mojom::LifecycleState;
+ using Observer = PageNodeObserver;
+ class ObserverDefaultImpl;
+
+ PageNode();
+ ~PageNode() override;
+
+ // Returns the unique ID of the browser context that this page belongs to.
+ virtual const std::string& GetBrowserContextID() const = 0;
+
+ // Returns the page almost idle state of this page.
+ // See PageNodeObserver::OnPageAlmostIdleChanged.
+ virtual bool IsPageAlmostIdle() const = 0;
+
+ // Returns true if this page is currently visible, false otherwise.
+ // See PageNodeObserver::OnIsVisibleChanged.
+ virtual bool IsVisible() const = 0;
+
+ // Returns the time since the last visibility change. It is always well
+ // defined as the visibility property is set at node creation.
+ virtual base::TimeDelta GetTimeSinceLastVisibilityChange() const = 0;
+
+ // Returns true if this page is currently audible, false otherwise.
+ // See PageNodeObserver::OnIsAudibleChanged.
+ virtual bool IsAudible() const = 0;
+
+ // Returns true if this page is currently loading, false otherwise.
+ // See PageNodeObserver::OnIsLoadingChanged.
+ virtual bool IsLoading() const = 0;
+
+ // Returns the UKM source ID associated with the URL of the main frame of
+ // this page.
+ // See PageNodeObserver::OnUkmSourceIdChanged.
+ virtual ukm::SourceId GetUkmSourceID() const = 0;
+
+ // Returns the lifecycle state of this page. This is aggregated from the
+ // lifecycle state of each frame in the frame tree. See
+ // PageNodeObserver::OnPageLifecycleStateChanged.
+ virtual LifecycleState GetLifecycleState() const = 0;
+
+ // Returns the freeze policy set via origin trial.
+ virtual InterventionPolicy GetOriginTrialFreezePolicy() const = 0;
+
+ // Returns the navigation ID associated with the last committed navigation
+ // event for the main frame of this page.
+ // See PageNodeObserver::OnMainFrameNavigationCommitted.
+ virtual int64_t GetNavigationID() const = 0;
+
+ // Returns "zero" if no navigation has happened, otherwise returns the time
+ // since the last navigation commit.
+ virtual base::TimeDelta GetTimeSinceLastNavigation() const = 0;
+
+ // Returns the current main frame node (if there is one), otherwise returns
+ // any of the potentially multiple main frames that currently exist. If there
+ // are no main frames at the moment, returns nullptr.
+ virtual const FrameNode* GetMainFrameNode() const = 0;
+
+ // Returns all of the main frame nodes, both current and otherwise. If there
+ // are no main frames at the moment, returns the empty set.
+ virtual const base::flat_set<const FrameNode*> GetMainFrameNodes() const = 0;
+
+ // Returns the URL the main frame last committed a navigation to, or the
+ // initial URL of the page before navigation. The latter case is distinguished
+ // by a zero navigation ID.
+ // See PageNodeObserver::OnMainFrameNavigationCommitted.
+ virtual const GURL& GetMainFrameUrl() const = 0;
+
+ // Returns the web contents associated with this page node. It is valid to
+ // call this function on any thread but the weak pointer must only be
+ // dereferenced on the UI thread.
+ virtual const WebContentsProxy& GetContentsProxy() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PageNode);
+};
+
+// Pure virtual observer interface. Derive from this if you want to be forced to
+// implement the entire interface.
+class PageNodeObserver {
+ public:
+ PageNodeObserver();
+ virtual ~PageNodeObserver();
+
+ // Node lifetime notifications.
+
+ // Called when a |page_node| is added to the graph.
+ virtual void OnPageNodeAdded(const PageNode* page_node) = 0;
+
+ // Called before a |page_node| is removed from the graph.
+ virtual void OnBeforePageNodeRemoved(const PageNode* page_node) = 0;
+
+ // Notifications of property changes.
+
+ // Invoked when the IsVisible property changes.
+ virtual void OnIsVisibleChanged(const PageNode* page_node) = 0;
+
+ // Invoked when the IsAudible property changes.
+ virtual void OnIsAudibleChanged(const PageNode* page_node) = 0;
+
+ // Invoked when the IsLoading property changes.
+ virtual void OnIsLoadingChanged(const PageNode* page_node) = 0;
+
+ // Invoked when the UkmSourceId property changes.
+ virtual void OnUkmSourceIdChanged(const PageNode* page_node) = 0;
+
+ // Invoked when the PageLifecycleState property changes.
+ virtual void OnPageLifecycleStateChanged(const PageNode* page_node) = 0;
+
+ // Invoked when the OriginTrialFreezePolicy property changes.
+ virtual void OnPageOriginTrialFreezePolicyChanged(
+ const PageNode* page_node) = 0;
+
+ // Invoked when the MainFrameUrl property changes.
+ virtual void OnMainFrameUrlChanged(const PageNode* page_node) = 0;
+
+ // Invoked when the PageAlmostIdle property changes.
+ virtual void OnPageAlmostIdleChanged(const PageNode* page_node) = 0;
+
+ // This is fired when a non-same document navigation commits in the main
+ // frame. It indicates that the the |NavigationId| property and possibly the
+ // |MainFrameUrl| properties have changed.
+ virtual void OnMainFrameDocumentChanged(const PageNode* page_node) = 0;
+
+ // Events with no property changes.
+
+ // Fired when the tab title associated with a page changes. This property is
+ // not directly reflected on the node.
+ virtual void OnTitleUpdated(const PageNode* page_node) = 0;
+
+ // Fired when the favicon associated with a page is updated. This property is
+ // not directly reflected on the node.
+ virtual void OnFaviconUpdated(const PageNode* page_node) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PageNodeObserver);
+};
+
+// Default implementation of observer that provides dummy versions of each
+// function. Derive from this if you only need to implement a few of the
+// functions.
+class PageNode::ObserverDefaultImpl : public PageNodeObserver {
+ public:
+ ObserverDefaultImpl();
+ ~ObserverDefaultImpl() override;
+
+ // PageNodeObserver implementation:
+ void OnPageNodeAdded(const PageNode* page_node) override {}
+ void OnBeforePageNodeRemoved(const PageNode* page_node) override {}
+ void OnIsVisibleChanged(const PageNode* page_node) override {}
+ void OnIsAudibleChanged(const PageNode* page_node) override {}
+ void OnIsLoadingChanged(const PageNode* page_node) override {}
+ void OnUkmSourceIdChanged(const PageNode* page_node) override {}
+ void OnPageLifecycleStateChanged(const PageNode* page_node) override {}
+ void OnPageOriginTrialFreezePolicyChanged(
+ const PageNode* page_node) override {}
+ void OnPageAlmostIdleChanged(const PageNode* page_node) override {}
+ void OnMainFrameUrlChanged(const PageNode* page_node) override {}
+ void OnMainFrameDocumentChanged(const PageNode* page_node) override {}
+ void OnTitleUpdated(const PageNode* page_node) override {}
+ void OnFaviconUpdated(const PageNode* page_node) override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
diff --git a/components/performance_manager/public/graph/process_node.h b/components/performance_manager/public/graph/process_node.h
new file mode 100644
index 0000000..0ae476aa
--- /dev/null
+++ b/components/performance_manager/public/graph/process_node.h
@@ -0,0 +1,170 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
+
+#include "base/callback_forward.h"
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "base/process/process.h"
+#include "components/performance_manager/public/graph/node.h"
+
+namespace base {
+class Process;
+} // namespace base
+
+namespace performance_manager {
+
+class FrameNode;
+class ProcessNodeObserver;
+class RenderProcessHostProxy;
+
+// A process node follows the lifetime of a RenderProcessHost.
+// It may reference zero or one processes at a time, but during its lifetime, it
+// may reference more than one process. This can happen if the associated
+// renderer crashes, and an associated frame is then reloaded or re-navigated.
+// The state of the process node goes through:
+// 1. Created, no PID.
+// 2. Process started, have PID - in the case where the associated render
+// process fails to start, this state may not occur.
+// 3. Process died or failed to start, have exit status.
+// 4. Back to 2.
+//
+// It is only valid to access this object on the sequence of the graph that owns
+// it.
+class ProcessNode : public Node {
+ public:
+ using FrameNodeVisitor = base::Callback<bool(const FrameNode*)>;
+ using Observer = ProcessNodeObserver;
+ class ObserverDefaultImpl;
+
+ ProcessNode();
+ ~ProcessNode() override;
+
+ // Returns the process ID associated with this process. Use this in preference
+ // to querying GetProcess.Pid(). It's always valid to access, but will return
+ // kNullProcessId if the process has yet started. It will also retain the
+ // process ID for a process that has exited (at least until the underlying
+ // RenderProcessHost gets reused in the case of a crash). Refrain from using
+ // this as a unique identifier as on some platforms PIDs are reused
+ // aggressively. See GetLaunchTime for more information.
+ virtual base::ProcessId GetProcessId() const = 0;
+
+ // Returns the base::Process backing this process. This will be an invalid
+ // process if it has not yet started, or if it has exited.
+ virtual const base::Process& GetProcess() const = 0;
+
+ // Returns the launch time associated with the process. Combined with the
+ // process ID this can be used as a unique identifier for the process.
+ virtual base::Time GetLaunchTime() const = 0;
+
+ // Returns the exit status of this process. This will be empty if the process
+ // has not yet exited.
+ virtual base::Optional<int32_t> GetExitStatus() const = 0;
+
+ // Visits the frame nodes that are hosted in this process. The iteration is
+ // halted if the visitor returns false.
+ virtual void VisitFrameNodes(const FrameNodeVisitor& visitor) const = 0;
+
+ // Returns the set of frame nodes that are hosted in this process. Note that
+ // calling this causes the set of nodes to be generated.
+ virtual base::flat_set<const FrameNode*> GetFrameNodes() const = 0;
+
+ // Returns the current expected task queuing duration in the process. This is
+ // measure of main thread latency. See
+ // ProcessNodeObserver::OnExpectedTaskQueueingDurationSample.
+ virtual base::TimeDelta GetExpectedTaskQueueingDuration() const = 0;
+
+ // Returns true if the main thread task load is low (below some threshold
+ // of usage). See ProcessNodeObserver::OnMainThreadTaskLoadIsLow.
+ virtual bool GetMainThreadTaskLoadIsLow() const = 0;
+
+ // Returns the current renderer process CPU usage. A value of 1.0 can mean 1
+ // core at 100%, or 2 cores at 50% each, for example.
+ virtual double GetCpuUsage() const = 0;
+
+ // Returns the cumulative CPU usage of the renderer process over its entire
+ // lifetime, expressed as CPU seconds.
+ virtual base::TimeDelta GetCumulativeCpuUsage() const = 0;
+
+ // Returns the most recently measured private memory footprint of the process.
+ // This is roughly private, anonymous, non-discardable, resident or swapped
+ // memory in kilobytes. For more details, see https://goo.gl/3kPb9S.
+ virtual uint64_t GetPrivateFootprintKb() const = 0;
+
+ // Returns the most recently measured resident set of the process, in
+ // kilobytes.
+ virtual uint64_t GetResidentSetKb() const = 0;
+
+ // Returns a proxy to the RenderProcessHost associated with this node. The
+ // proxy may only be dereferenced on the UI thread.
+ virtual const RenderProcessHostProxy& GetRenderProcessHostProxy() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProcessNode);
+};
+
+// Pure virtual observer interface. Derive from this if you want to be forced to
+// implement the entire interface.
+class ProcessNodeObserver {
+ public:
+ ProcessNodeObserver();
+ virtual ~ProcessNodeObserver();
+
+ // Node lifetime notifications.
+
+ // Called when a |process_node| is added to the graph.
+ virtual void OnProcessNodeAdded(const ProcessNode* process_node) = 0;
+
+ // The process associated with |process_node| has been started or has exited.
+ // This implies some or all of the process, process_id, launch time and/or
+ // exit status properties have changed.
+ virtual void OnProcessLifetimeChange(const ProcessNode* process_node) = 0;
+
+ // Called before a |process_node| is removed from the graph.
+ virtual void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) = 0;
+
+ // Notifications of property changes.
+
+ // Invoked when a new |expected_task_queueing_duration| sample is available.
+ virtual void OnExpectedTaskQueueingDurationSample(
+ const ProcessNode* process_node) = 0;
+
+ // Invoked when the |main_thread_task_load_is_low| property changes.
+ virtual void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) = 0;
+
+ // Events with no property changes.
+
+ // Fired when all frames in a process have transitioned to being frozen.
+ virtual void OnAllFramesInProcessFrozen(const ProcessNode* process_node) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProcessNodeObserver);
+};
+
+// Default implementation of observer that provides dummy versions of each
+// function. Derive from this if you only need to implement a few of the
+// functions.
+class ProcessNode::ObserverDefaultImpl : public ProcessNodeObserver {
+ public:
+ ObserverDefaultImpl();
+ ~ObserverDefaultImpl() override;
+
+ // ProcessNodeObserver implementation:
+ void OnProcessNodeAdded(const ProcessNode* process_node) override {}
+ void OnProcessLifetimeChange(const ProcessNode* process_node) override {}
+ void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) override {}
+ void OnExpectedTaskQueueingDurationSample(
+ const ProcessNode* process_node) override {}
+ void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) override {}
+ void OnAllFramesInProcessFrozen(const ProcessNode* process_node) override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PROCESS_NODE_H_
diff --git a/components/performance_manager/public/graph/system_node.h b/components/performance_manager/public/graph/system_node.h
new file mode 100644
index 0000000..dacf1f03
--- /dev/null
+++ b/components/performance_manager/public/graph/system_node.h
@@ -0,0 +1,72 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_SYSTEM_NODE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_SYSTEM_NODE_H_
+
+#include "base/macros.h"
+#include "components/performance_manager/public/graph/node.h"
+
+namespace performance_manager {
+
+class SystemNodeObserver;
+
+// The SystemNode represents system-wide state. There is at most one system node
+// in a graph.
+class SystemNode : public Node {
+ public:
+ using Observer = SystemNodeObserver;
+ class ObserverDefaultImpl;
+
+ SystemNode();
+ ~SystemNode() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SystemNode);
+};
+
+// Pure virtual observer interface. Derive from this if you want to be forced to
+// implement the entire interface.
+class SystemNodeObserver {
+ public:
+ SystemNodeObserver();
+ virtual ~SystemNodeObserver();
+
+ // Node lifetime notifications.
+
+ // Called when the |system_node| is added to the graph.
+ virtual void OnSystemNodeAdded(const SystemNode* system_node) = 0;
+
+ // Called before the |system_node| is removed from the graph.
+ virtual void OnBeforeSystemNodeRemoved(const SystemNode* system_node) = 0;
+
+ // Called when a new set of process memory metrics is available.
+ virtual void OnProcessMemoryMetricsAvailable(
+ const SystemNode* system_node) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SystemNodeObserver);
+};
+
+// Default implementation of observer that provides dummy versions of each
+// function. Derive from this if you only need to implement a few of the
+// functions.
+class SystemNode::ObserverDefaultImpl : public SystemNodeObserver {
+ public:
+ ObserverDefaultImpl();
+ ~ObserverDefaultImpl() override;
+
+ // SystemNodeObserver implementation:
+ void OnSystemNodeAdded(const SystemNode* system_node) override {}
+ void OnBeforeSystemNodeRemoved(const SystemNode* system_node) override {}
+ void OnProcessMemoryMetricsAvailable(const SystemNode* system_node) override {
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_SYSTEM_NODE_H_
diff --git a/components/performance_manager/public/graph/worker_node.h b/components/performance_manager/public/graph/worker_node.h
new file mode 100644
index 0000000..7c7d476
--- /dev/null
+++ b/components/performance_manager/public/graph/worker_node.h
@@ -0,0 +1,171 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_WORKER_NODE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_WORKER_NODE_H_
+
+#include <string>
+
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "components/performance_manager/public/graph/node.h"
+
+class GURL;
+
+namespace base {
+class UnguessableToken;
+}
+
+namespace performance_manager {
+
+class WorkerNodeObserver;
+class FrameNode;
+class ProcessNode;
+
+// Represents a running instance of a WorkerGlobalScope.
+// See https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope.
+//
+// A worker is the equivalent of a thread on the web platform. To do
+// asynchronous work, a frame can create a dedicated worker or a shared worker
+// with Javascript. Those workers can now be used by sending an asynchronous
+// message using the postMessage() method, and replies can be received by
+// registering a message handler on the worker object.
+//
+// One notable special case is that dedicated workers can be nested. That means
+// that a dedicated worker can create another dedicated worker which is then
+// only accessible from the parent worker.
+//
+// Service workers are different. Instead of being created by the javascript
+// when needed, a service worker is registered once and affects all frames and
+// dedicated/shared workers whose URL matches the scope of the service worker.
+// A service worker is mainly used to intercept network requests and optionally
+// serve the responses from a cache, making the web site work offline.
+//
+// A client, from the point of view of the worker, is the frame or worker that
+// caused the worker to start running, either because it explicitly created it,
+// or a service worker is registered to handle their network requests.
+class WorkerNode : public Node {
+ public:
+ // The different possible worker types.
+ enum class WorkerType {
+ kDedicated,
+ kShared,
+ kService,
+ };
+
+ using Observer = WorkerNodeObserver;
+ class ObserverDefaultImpl;
+
+ WorkerNode();
+ ~WorkerNode() override;
+
+ // Returns the worker type. Note that this is different from the NodeTypeEnum.
+ virtual WorkerType GetWorkerType() const = 0;
+
+ // Returns the unique ID of the browser context that this worker belongs to.
+ virtual const std::string& GetBrowserContextID() const = 0;
+
+ // Returns the process node to which this worker belongs. This is a constant
+ // over the lifetime of the frame.
+ virtual const ProcessNode* GetProcessNode() const = 0;
+
+ // Returns the URL of the worker script.
+ virtual const GURL& GetURL() const = 0;
+
+ // Returns the dev tools token for this worker.
+ virtual const base::UnguessableToken& GetDevToolsToken() const = 0;
+
+ // Returns the frames that are clients of this worker.
+ virtual const base::flat_set<const FrameNode*> GetClientFrames() const = 0;
+
+ // Returns the workers that are clients of this worker.
+ // There are 2 cases where this is possible:
+ // - A dedicated worker can create nested workers. The parent worker becomes
+ // one of its client worker.
+ // - A dedicated worker or a shared worker will become a client of the service
+ // worker that handles their network requests.
+ virtual const base::flat_set<const WorkerNode*> GetClientWorkers() const = 0;
+
+ // Returns the child workers of this worker.
+ // There are 2 cases where a worker can be the child of another worker:
+ // - A dedicated worker can create nested workers. The nested worker becomes
+ // a child worker of the parent.
+ // - A service worker will become a child worker of every worker for which
+ // it handles network requests.
+ virtual const base::flat_set<const WorkerNode*> GetChildWorkers() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WorkerNode);
+};
+
+// Pure virtual observer interface. Derive from this if you want to be forced to
+// implement the entire interface.
+class WorkerNodeObserver {
+ public:
+ WorkerNodeObserver();
+ virtual ~WorkerNodeObserver();
+
+ // Node lifetime notifications.
+
+ // Called when a |worker_node| is added to the graph.
+ virtual void OnWorkerNodeAdded(const WorkerNode* worker_node) = 0;
+
+ // Called before a |worker_node| is removed from the graph.
+ virtual void OnBeforeWorkerNodeRemoved(const WorkerNode* worker_node) = 0;
+
+ // Notifications of property changes.
+
+ // Invoked when |client_frame_node| becomes a client of |worker_node|.
+ virtual void OnClientFrameAdded(const WorkerNode* worker_node,
+ const FrameNode* client_frame_node) = 0;
+
+ // Invoked when |client_frame_node| is no longer a client of |worker_node|.
+ virtual void OnBeforeClientFrameRemoved(
+ const WorkerNode* worker_node,
+ const FrameNode* client_frame_node) = 0;
+
+ // Invoked when |client_worker_node| becomes a client of |worker_node|.
+ virtual void OnClientWorkerAdded(const WorkerNode* worker_node,
+ const WorkerNode* client_worker_node) = 0;
+
+ // Invoked when |client_worker_node| is no longer a client of |worker_node|.
+ virtual void OnBeforeClientWorkerRemoved(
+ const WorkerNode* worker_node,
+ const WorkerNode* client_worker_node) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WorkerNodeObserver);
+};
+
+// Default implementation of observer that provides dummy versions of each
+// function. Derive from this if you only need to implement a few of the
+// functions.
+class WorkerNode::ObserverDefaultImpl : public WorkerNodeObserver {
+ public:
+ ObserverDefaultImpl();
+ ~ObserverDefaultImpl() override;
+
+ // WorkerNodeObserver implementation:
+
+ // Called when a |worker_node| is added to the graph.
+ void OnWorkerNodeAdded(const WorkerNode* worker_node) override {}
+ void OnBeforeWorkerNodeRemoved(const WorkerNode* worker_node) override {}
+ void OnClientFrameAdded(const WorkerNode* worker_node,
+ const FrameNode* client_frame_node) override {}
+ void OnBeforeClientFrameRemoved(const WorkerNode* worker_node,
+ const FrameNode* client_frame_node) override {
+ }
+ void OnClientWorkerAdded(const WorkerNode* worker_node,
+ const WorkerNode* client_worker_node) override {}
+ void OnBeforeClientWorkerRemoved(
+ const WorkerNode* worker_node,
+ const WorkerNode* client_worker_node) override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
+};
+
+} // namespace performance_manager
+
+#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_WORKER_NODE_H_