blob: ef6e1fbfb98673491e0151e2463bd730b3f6b303 [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.
#include "chrome/browser/performance_manager/render_process_user_data.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "chrome/browser/performance_manager/graph/process_node_impl.h"
#include "chrome/browser/performance_manager/performance_manager.h"
#include "content/public/browser/child_process_termination_info.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "services/service_manager/public/cpp/connector.h"
namespace performance_manager {
namespace {
const void* const kRenderProcessUserDataKey = &kRenderProcessUserDataKey;
} // namespace
RenderProcessUserData* RenderProcessUserData::first_ = nullptr;
RenderProcessUserData::RenderProcessUserData(
content::RenderProcessHost* render_process_host)
: host_(render_process_host),
process_node_(PerformanceManager::GetInstance()->CreateProcessNode()) {
host_->AddObserver(this);
// Push this instance to the list.
next_ = first_;
if (next_)
next_->prev_ = this;
prev_ = nullptr;
first_ = this;
}
RenderProcessUserData::~RenderProcessUserData() {
PerformanceManager::GetInstance()->DeleteNode(std::move(process_node_));
host_->RemoveObserver(this);
if (first_ == this)
first_ = next_;
if (prev_) {
DCHECK_EQ(prev_->next_, this);
prev_->next_ = next_;
}
if (next_) {
DCHECK_EQ(next_->prev_, this);
next_->prev_ = prev_;
}
}
// static
void RenderProcessUserData::DetachAndDestroyAll() {
while (first_)
first_->host_->RemoveUserData(kRenderProcessUserDataKey);
}
// static
RenderProcessUserData* RenderProcessUserData::GetForRenderProcessHost(
content::RenderProcessHost* host) {
return static_cast<RenderProcessUserData*>(
host->GetUserData(kRenderProcessUserDataKey));
}
// static
RenderProcessUserData* RenderProcessUserData::GetOrCreateForRenderProcessHost(
content::RenderProcessHost* host) {
auto* raw_user_data = GetForRenderProcessHost(host);
if (raw_user_data)
return raw_user_data;
std::unique_ptr<RenderProcessUserData> user_data =
base::WrapUnique(new RenderProcessUserData(host));
raw_user_data = user_data.get();
host->SetUserData(kRenderProcessUserDataKey, std::move(user_data));
return raw_user_data;
}
void RenderProcessUserData::RenderProcessReady(
content::RenderProcessHost* host) {
PerformanceManager* performance_manager = PerformanceManager::GetInstance();
const base::Time launch_time =
#if defined(OS_ANDROID)
// Process::CreationTime() is not available on Android. Since this
// method is called immediately after the process is launched, the
// process launch time can be approximated with the current time.
base::Time::Now();
#else
host->GetProcess().CreationTime();
#endif
performance_manager->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ProcessNodeImpl::SetProcess,
base::Unretained(process_node_.get()),
host->GetProcess().Duplicate(), launch_time));
}
void RenderProcessUserData::RenderProcessExited(
content::RenderProcessHost* host,
const content::ChildProcessTerminationInfo& info) {
PerformanceManager* performance_manager = PerformanceManager::GetInstance();
performance_manager->task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&ProcessNodeImpl::SetProcessExitStatus,
base::Unretained(process_node_.get()), info.exit_code));
}
void RenderProcessUserData::RenderProcessHostDestroyed(
content::RenderProcessHost* host) {
host->RemoveUserData(kRenderProcessUserDataKey);
}
} // namespace performance_manager