#ifndef CHROME_BROWSER_UI_WEBUI_DISCARDS_GRAPH_DUMP_IMPL_H_
#define CHROME_BROWSER_UI_WEBUI_DISCARDS_GRAPH_DUMP_IMPL_H_
#include "base/containers/flat_map.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/threading/sequence_bound.h"
#include "base/types/id_type.h"
#include "chrome/browser/ui/webui/discards/discards.mojom.h"
#include "components/performance_manager/public/graph/frame_node.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/graph/page_node.h"
#include "components/performance_manager/public/graph/process_node.h"
#include "components/performance_manager/public/graph/worker_node.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
class DiscardsGraphDumpImpl : public discards::mojom::GraphDump,
public performance_manager::GraphOwned,
public performance_manager::FrameNodeObserver,
public performance_manager::PageNodeObserver,
public performance_manager::ProcessNodeObserver,
public performance_manager::WorkerNodeObserver {
public:
DiscardsGraphDumpImpl();
DiscardsGraphDumpImpl(const DiscardsGraphDumpImpl&) = delete;
DiscardsGraphDumpImpl& operator=(const DiscardsGraphDumpImpl&) = delete;
~DiscardsGraphDumpImpl() override;
static void CreateAndBind(
mojo::PendingReceiver<discards::mojom::GraphDump> receiver,
performance_manager::Graph* graph);
void BindWithGraph(
performance_manager::Graph* graph,
mojo::PendingReceiver<discards::mojom::GraphDump> receiver);
int64_t GetNodeIdForTesting(const performance_manager::Node* node);
protected:
void SubscribeToChanges(
mojo::PendingRemote<discards::mojom::GraphChangeStream> change_subscriber)
override;
void RequestNodeDescriptions(
const std::vector<int64_t>& node_ids,
RequestNodeDescriptionsCallback callback) override;
void OnPassedToGraph(performance_manager::Graph* graph) override;
void OnTakenFromGraph(performance_manager::Graph* graph) override;
void OnFrameNodeAdded(
const performance_manager::FrameNode* frame_node) override;
void OnBeforeFrameNodeRemoved(
const performance_manager::FrameNode* frame_node) override;
void OnURLChanged(const performance_manager::FrameNode* frame_node,
const GURL& previous_value) override;
void OnPageNodeAdded(const performance_manager::PageNode* page_node) override;
void OnBeforePageNodeRemoved(
const performance_manager::PageNode* page_node) override;
void OnOpenerFrameNodeChanged(
const performance_manager::PageNode* page_node,
const performance_manager::FrameNode* previous_opener) override;
void OnEmbedderFrameNodeChanged(
const performance_manager::PageNode* page_node,
const performance_manager::FrameNode* previous_embedder) override;
void OnMainFrameUrlChanged(
const performance_manager::PageNode* page_node) override;
void OnFaviconUpdated(
const performance_manager::PageNode* page_node) override;
void OnProcessNodeAdded(
const performance_manager::ProcessNode* process_node) override;
void OnProcessLifetimeChange(
const performance_manager::ProcessNode* process_node) override;
void OnBeforeProcessNodeRemoved(
const performance_manager::ProcessNode* process_node) override;
void OnWorkerNodeAdded(
const performance_manager::WorkerNode* worker_node) override;
void OnBeforeWorkerNodeRemoved(
const performance_manager::WorkerNode* worker_node) override;
void OnFinalResponseURLDetermined(
const performance_manager::WorkerNode* worker_node) override;
void OnBeforeClientFrameAdded(
const performance_manager::WorkerNode* worker_node,
const performance_manager::FrameNode* client_frame_node) override;
void OnClientFrameAdded(
const performance_manager::WorkerNode* worker_node,
const performance_manager::FrameNode* client_frame_node) override;
void OnBeforeClientFrameRemoved(
const performance_manager::WorkerNode* worker_node,
const performance_manager::FrameNode* client_frame_node) override;
void OnBeforeClientWorkerAdded(
const performance_manager::WorkerNode* worker_node,
const performance_manager::WorkerNode* client_worker_node) override;
void OnClientWorkerAdded(
const performance_manager::WorkerNode* worker_node,
const performance_manager::WorkerNode* client_worker_node) override;
void OnBeforeClientWorkerRemoved(
const performance_manager::WorkerNode* worker_node,
const performance_manager::WorkerNode* client_worker_node) override;
private:
class FaviconRequestHelper;
using FaviconAvailableCallback =
base::OnceCallback<void(scoped_refptr<base::RefCountedMemory>)>;
using NodeId = base::IdType64<class NodeIdTag>;
void AddNode(const performance_manager::Node* node);
void RemoveNode(const performance_manager::Node* node);
bool HasNode(const performance_manager::Node* node) const;
int64_t GetNodeId(const performance_manager::Node* node) const;
base::SequenceBound<FaviconRequestHelper>& EnsureFaviconRequestHelper();
FaviconAvailableCallback GetFaviconAvailableCallback(
int64_t serialization_id);
void StartPageFaviconRequest(const performance_manager::PageNode* page_node);
void StartFrameFaviconRequest(
const performance_manager::FrameNode* frame_node);
void SendNotificationToAllNodes(bool created);
void SendFrameNotification(const performance_manager::FrameNode* frame,
bool created);
void SendPageNotification(const performance_manager::PageNode* page,
bool created);
void SendProcessNotification(const performance_manager::ProcessNode* process,
bool created);
void SendWorkerNotification(const performance_manager::WorkerNode* worker,
bool created);
void SendDeletionNotification(const performance_manager::Node* node);
void SendFaviconNotification(
int64_t serialization_id,
scoped_refptr<base::RefCountedMemory> bitmap_data);
static void OnConnectionError(DiscardsGraphDumpImpl* impl);
base::SequenceBound<FaviconRequestHelper> favicon_request_helper_;
base::flat_map<const performance_manager::Node*, NodeId> node_ids_;
base::flat_map<NodeId,
raw_ptr<const performance_manager::Node, CtnExperimental>>
nodes_by_id_;
NodeId::Generator node_id_generator_;
mojo::Remote<discards::mojom::GraphChangeStream> change_subscriber_;
mojo::Receiver<discards::mojom::GraphDump> receiver_{this};
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<DiscardsGraphDumpImpl> weak_factory_{this};
};
#endif