| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #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; |
| |
| // Creates a new DiscardsGraphDumpImpl to service |receiver| and passes its |
| // ownership to |graph|. |
| static void CreateAndBind( |
| mojo::PendingReceiver<discards::mojom::GraphDump> receiver, |
| performance_manager::Graph* graph); |
| |
| // Exposed for testing. |
| void BindWithGraph( |
| performance_manager::Graph* graph, |
| mojo::PendingReceiver<discards::mojom::GraphDump> receiver); |
| |
| int64_t GetNodeIdForTesting(const performance_manager::Node* node); |
| |
| protected: |
| // WebUIGraphDump implementation. |
| void SubscribeToChanges( |
| mojo::PendingRemote<discards::mojom::GraphChangeStream> change_subscriber) |
| override; |
| void RequestNodeDescriptions( |
| const std::vector<int64_t>& node_ids, |
| RequestNodeDescriptionsCallback callback) override; |
| |
| // GraphOwned implementation. |
| void OnPassedToGraph(performance_manager::Graph* graph) override; |
| void OnTakenFromGraph(performance_manager::Graph* graph) override; |
| |
| // FrameNodeObserver implementation: |
| 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; |
| |
| // PageNodeObserver implementation: |
| 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; |
| |
| // ProcessNodeObserver implementation: |
| 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; |
| |
| // WorkerNodeObserver implementation: |
| 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: |
| // The favicon requests happen on the UI thread. This helper class |
| // maintains the state required to do that. |
| 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(); |
| |
| // Returns a callback that will invoke SendFaviconNotification on the graph |
| // sequence with the given `serialization_id`. |
| 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); |
| |
| // Helper that requests favicons on the UI thread. Initialized to null to |
| // avoid posting an initialization task to the UI thread during startup. |
| // Access this through EnsureFaviconRequestHelper to initialize it on first |
| // use. |
| base::SequenceBound<FaviconRequestHelper> favicon_request_helper_; |
| |
| // The live nodes and their IDs. |
| 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_; |
| |
| // The current change subscriber to this dumper. This instance is subscribed |
| // to every node in the graph save for the system node, so long as there is a |
| // subscriber. |
| 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 // CHROME_BROWSER_UI_WEBUI_DISCARDS_GRAPH_DUMP_IMPL_H_ |