blob: 88910137368c169cc59684f8ff410d366bb9e5dd [file] [log] [blame]
// 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_PERFORMANCE_MANAGER_IMPL_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_IMPL_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/task_runner_util.h"
#include "components/performance_manager/graph/graph_impl.h"
#include "components/performance_manager/public/graph/worker_node.h"
#include "components/performance_manager/public/performance_manager.h"
#include "components/performance_manager/public/render_process_host_proxy.h"
#include "components/performance_manager/public/web_contents_proxy.h"
class GURL;
namespace performance_manager {
class PageNodeImpl;
// The performance manager is a rendezvous point for binding to performance
// manager interfaces.
class PerformanceManagerImpl : public PerformanceManager {
public:
using FrameNodeCreationCallback = base::OnceCallback<void(FrameNodeImpl*)>;
~PerformanceManagerImpl() override;
// Posts a callback that will run on the PM sequence, and be provided a
// pointer to the Graph. Valid to call from any sequence, but |graph_callback|
// won't run if this is called before Create() or after Destroy().
//
// TODO(chrisha): Move this to the public interface.
using GraphImplCallback = base::OnceCallback<void(GraphImpl*)>;
static void CallOnGraphImpl(const base::Location& from_here,
GraphImplCallback graph_callback);
// Posts a callback that will run on the PM sequence, and be provided a
// pointer to the Graph. Valid to be called from the main thread only, and
// only if "IsAvailable" returns true. The return value is returned as an
// argument to the reply callback.
template <typename TaskReturnType>
void CallOnGraphAndReplyWithResult(
const base::Location& from_here,
base::OnceCallback<TaskReturnType(GraphImpl*)> task,
base::OnceCallback<void(TaskReturnType)> reply);
// Retrieves the currently registered instance. Calls must not race with
// Create() or Destroy(). The returned pointer must not be used after
// Destroy(). This function can be called from any sequence with those
// caveats.
static PerformanceManagerImpl* GetInstance();
// Creates, initializes and registers an instance.
// Invokes |on_start| on the PM sequence.
static std::unique_ptr<PerformanceManagerImpl> Create(
GraphImplCallback on_start);
// Unregisters |instance| and arranges for its deletion on its sequence.
static void Destroy(std::unique_ptr<PerformanceManager> instance);
// Creates a new node of the requested type and adds it to the graph.
// May be called from any sequence. If a |creation_callback| is provided it
// will be run on the performance manager sequence immediately after creating
// the node.
std::unique_ptr<FrameNodeImpl> CreateFrameNode(
ProcessNodeImpl* process_node,
PageNodeImpl* page_node,
FrameNodeImpl* parent_frame_node,
int frame_tree_node_id,
int render_frame_id,
const base::UnguessableToken& dev_tools_token,
int32_t browsing_instance_id,
int32_t site_instance_id,
FrameNodeCreationCallback creation_callback =
FrameNodeCreationCallback());
std::unique_ptr<PageNodeImpl> CreatePageNode(
const WebContentsProxy& contents_proxy,
const std::string& browser_context_id,
const GURL& visible_url,
bool is_visible,
bool is_audible);
std::unique_ptr<ProcessNodeImpl> CreateProcessNode(
RenderProcessHostProxy proxy);
std::unique_ptr<WorkerNodeImpl> CreateWorkerNode(
const std::string& browser_context_id,
WorkerNode::WorkerType worker_type,
ProcessNodeImpl* process_node,
const GURL& url,
const base::UnguessableToken& dev_tools_token);
// Destroys a node returned from the creation functions above.
// May be called from any sequence.
template <typename NodeType>
void DeleteNode(std::unique_ptr<NodeType> node);
// Each node in |nodes| must have been returned from one of the creation
// functions above. This function takes care of removing them from the graph
// in topological order and destroying them.
void BatchDeleteNodes(std::vector<std::unique_ptr<NodeBase>> nodes);
// Returns the performance manager TaskRunner.
// TODO(chrisha): Hide this after the last consumer stops using it!
static scoped_refptr<base::SequencedTaskRunner> GetTaskRunner();
// Indicates whether or not the caller is currently running on the PM task
// runner.
bool OnPMTaskRunnerForTesting() const {
return GetTaskRunner()->RunsTasksInCurrentSequence();
}
private:
friend class PerformanceManager;
PerformanceManagerImpl();
template <typename NodeType, typename... Args>
std::unique_ptr<NodeType> CreateNodeImpl(
base::OnceCallback<void(NodeType*)> creation_callback,
Args&&... constructor_args);
void PostDeleteNode(std::unique_ptr<NodeBase> node);
void DeleteNodeImpl(std::unique_ptr<NodeBase> node);
void BatchDeleteNodesImpl(std::vector<std::unique_ptr<NodeBase>> nodes);
void OnStartImpl(GraphImplCallback graph_callback);
static void RunCallbackWithGraphImpl(GraphImplCallback graph_callback);
static void RunCallbackWithGraph(GraphCallback graph_callback);
template <typename TaskReturnType>
TaskReturnType RunCallbackWithGraphAndReplyWithResult(
base::OnceCallback<TaskReturnType(GraphImpl*)> task);
GraphImpl graph_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(PerformanceManagerImpl);
};
template <typename NodeType>
void PerformanceManagerImpl::DeleteNode(std::unique_ptr<NodeType> node) {
PostDeleteNode(std::move(node));
}
template <typename TaskReturnType>
void PerformanceManagerImpl::CallOnGraphAndReplyWithResult(
const base::Location& from_here,
base::OnceCallback<TaskReturnType(GraphImpl*)> task,
base::OnceCallback<void(TaskReturnType)> reply) {
auto* pm = GetInstance();
base::PostTaskAndReplyWithResult(
GetTaskRunner().get(), from_here,
base::BindOnce(
&PerformanceManagerImpl::RunCallbackWithGraphAndReplyWithResult<
TaskReturnType>,
base::Unretained(pm), std::move(task)),
std::move(reply));
}
template <typename TaskReturnType>
TaskReturnType PerformanceManagerImpl::RunCallbackWithGraphAndReplyWithResult(
base::OnceCallback<TaskReturnType(GraphImpl*)> task) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return std::move(task).Run(&graph_);
}
} // namespace performance_manager
#endif // COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_IMPL_H_