Commit 4e7b710e authored by Sigurdur Asgeirsson's avatar Sigurdur Asgeirsson Committed by Commit Bot

PM: Retire GraphIntrospector interface.

The only user of this interface was the ProcessMemoryMetricsEmitter,
which now simply posts to the PerformanceManager and walks the graph
for the data it needs.

Bug: 910288
Change-Id: Ife9b43a67afeb36084f5e98c7d19740e1c92e7b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1554786
Commit-Queue: Sigurður Ásgeirsson <siggi@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Reviewed-by: default avatarRobert Kaplow <rkaplow@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#648669}
parent 8d334437
...@@ -1060,8 +1060,6 @@ jumbo_split_static_library("browser") { ...@@ -1060,8 +1060,6 @@ jumbo_split_static_library("browser") {
"performance_manager/graph/frame_node_impl.h", "performance_manager/graph/frame_node_impl.h",
"performance_manager/graph/graph.cc", "performance_manager/graph/graph.cc",
"performance_manager/graph/graph.h", "performance_manager/graph/graph.h",
"performance_manager/graph/graph_introspector_impl.cc",
"performance_manager/graph/graph_introspector_impl.h",
"performance_manager/graph/node_attached_data.cc", "performance_manager/graph/node_attached_data.cc",
"performance_manager/graph/node_attached_data.h", "performance_manager/graph/node_attached_data.h",
"performance_manager/graph/node_attached_data_impl.h", "performance_manager/graph/node_attached_data_impl.h",
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "chrome/browser/metrics/process_memory_metrics_emitter.h" #include "chrome/browser/metrics/process_memory_metrics_emitter.h"
#include <set>
#include "base/bind.h" #include "base/bind.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
...@@ -12,6 +14,10 @@ ...@@ -12,6 +14,10 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/tab_footprint_aggregator.h" #include "chrome/browser/metrics/tab_footprint_aggregator.h"
#include "chrome/browser/performance_manager/graph/frame_node_impl.h"
#include "chrome/browser/performance_manager/graph/graph.h"
#include "chrome/browser/performance_manager/graph/page_node_impl.h"
#include "chrome/browser/performance_manager/graph/process_node_impl.h"
#include "chrome/browser/performance_manager/performance_manager.h" #include "chrome/browser/performance_manager/performance_manager.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "content/public/browser/audio_service_info.h" #include "content/public/browser/audio_service_info.h"
...@@ -398,14 +404,13 @@ void EmitBrowserMemoryMetrics(const GlobalMemoryDump::ProcessDump& pmd, ...@@ -398,14 +404,13 @@ void EmitBrowserMemoryMetrics(const GlobalMemoryDump::ProcessDump& pmd,
void EmitRendererMemoryMetrics( void EmitRendererMemoryMetrics(
const GlobalMemoryDump::ProcessDump& pmd, const GlobalMemoryDump::ProcessDump& pmd,
const resource_coordinator::mojom::PageInfoPtr& page_info, const ProcessMemoryMetricsEmitter::PageInfo* page_info,
ukm::UkmRecorder* ukm_recorder, ukm::UkmRecorder* ukm_recorder,
int number_of_extensions, int number_of_extensions,
const base::Optional<base::TimeDelta>& uptime, const base::Optional<base::TimeDelta>& uptime,
bool record_uma) { bool record_uma) {
ukm::SourceId ukm_source_id = page_info.is_null() ukm::SourceId ukm_source_id =
? ukm::UkmRecorder::GetNewSourceID() page_info ? page_info->ukm_source_id : ukm::UkmRecorder::GetNewSourceID();
: page_info->ukm_source_id;
Memory_Experimental builder(ukm_source_id); Memory_Experimental builder(ukm_source_id);
builder.SetProcessType(static_cast<int64_t>( builder.SetProcessType(static_cast<int64_t>(
memory_instrumentation::mojom::ProcessType::RENDERER)); memory_instrumentation::mojom::ProcessType::RENDERER));
...@@ -414,7 +419,7 @@ void EmitRendererMemoryMetrics( ...@@ -414,7 +419,7 @@ void EmitRendererMemoryMetrics(
const char* process = number_of_extensions == 0 ? "Renderer" : "Extension"; const char* process = number_of_extensions == 0 ? "Renderer" : "Extension";
EmitProcessUmaAndUkm(pmd, process, uptime, record_uma, &builder); EmitProcessUmaAndUkm(pmd, process, uptime, record_uma, &builder);
if (!page_info.is_null()) { if (page_info) {
builder.SetIsVisible(page_info->is_visible); builder.SetIsVisible(page_info->is_visible);
builder.SetTimeSinceLastVisibilityChange( builder.SetTimeSinceLastVisibilityChange(
page_info->time_since_last_visibility_change.InSeconds()); page_info->time_since_last_visibility_change.InSeconds());
...@@ -494,10 +499,12 @@ void ProcessMemoryMetricsEmitter::FetchAndEmitProcessMemoryMetrics() { ...@@ -494,10 +499,12 @@ void ProcessMemoryMetricsEmitter::FetchAndEmitProcessMemoryMetrics() {
// The callback keeps this object alive until the callback is invoked. // The callback keeps this object alive until the callback is invoked.
performance_manager::PerformanceManager* performance_manager = performance_manager::PerformanceManager* performance_manager =
performance_manager::PerformanceManager::GetInstance(); performance_manager::PerformanceManager::GetInstance();
performance_manager->BindInterface(mojo::MakeRequest(&introspector_));
auto callback2 = auto callback2 =
base::Bind(&ProcessMemoryMetricsEmitter::ReceivedProcessInfos, this); base::BindOnce(&ProcessMemoryMetricsEmitter::ReceivedProcessInfos, this);
introspector_->GetProcessToURLMap(callback2); performance_manager->CallOnGraph(
FROM_HERE,
base::BindOnce(&ProcessMemoryMetricsEmitter::GetProcessToPageInfoMap,
std::move(callback2)));
} }
void ProcessMemoryMetricsEmitter::MarkServiceRequestsInProgress() { void ProcessMemoryMetricsEmitter::MarkServiceRequestsInProgress() {
...@@ -518,15 +525,14 @@ void ProcessMemoryMetricsEmitter::ReceivedMemoryDump( ...@@ -518,15 +525,14 @@ void ProcessMemoryMetricsEmitter::ReceivedMemoryDump(
} }
void ProcessMemoryMetricsEmitter::ReceivedProcessInfos( void ProcessMemoryMetricsEmitter::ReceivedProcessInfos(
std::vector<resource_coordinator::mojom::ProcessInfoPtr> process_infos) { std::vector<ProcessInfo> process_infos) {
get_process_urls_in_progress_ = false; get_process_urls_in_progress_ = false;
process_infos_.clear(); process_infos_.clear();
process_infos_.reserve(process_infos.size()); process_infos_.reserve(process_infos.size());
// If there are duplicate pids, keep the latest ProcessInfoPtr. // If there are duplicate pids, keep the latest ProcessInfoPtr.
for (resource_coordinator::mojom::ProcessInfoPtr& process_info : for (ProcessInfo& process_info : process_infos) {
process_infos) { base::ProcessId pid = process_info.pid;
base::ProcessId pid = process_info->pid;
process_infos_[pid] = std::move(process_info); process_infos_[pid] = std::move(process_info);
} }
CollateResults(); CollateResults();
...@@ -582,8 +588,8 @@ base::Optional<base::TimeDelta> ProcessMemoryMetricsEmitter::GetProcessUptime( ...@@ -582,8 +588,8 @@ base::Optional<base::TimeDelta> ProcessMemoryMetricsEmitter::GetProcessUptime(
base::ProcessId pid) { base::ProcessId pid) {
auto process_info = process_infos_.find(pid); auto process_info = process_infos_.find(pid);
if (process_info != process_infos_.end()) { if (process_info != process_infos_.end()) {
if (process_info->second->launch_time) if (!process_info->second.launch_time.is_null())
return now - process_info->second->launch_time.value(); return now - process_info->second.launch_time;
} }
return base::Optional<base::TimeDelta>(); return base::Optional<base::TimeDelta>();
} }
...@@ -621,24 +627,22 @@ void ProcessMemoryMetricsEmitter::CollateResults() { ...@@ -621,24 +627,22 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
} }
case memory_instrumentation::mojom::ProcessType::RENDERER: { case memory_instrumentation::mojom::ProcessType::RENDERER: {
renderer_private_footprint_total_kb += process_pmf_kb; renderer_private_footprint_total_kb += process_pmf_kb;
resource_coordinator::mojom::PageInfoPtr single_page_info; const PageInfo* single_page_info = nullptr;
auto iter = process_infos_.find(pmd.pid()); auto iter = process_infos_.find(pmd.pid());
if (iter != process_infos_.end()) { if (iter != process_infos_.end()) {
const resource_coordinator::mojom::ProcessInfoPtr& process_info = const ProcessInfo& process_info = iter->second;
iter->second;
if (emit_metrics_for_all_processes) { if (emit_metrics_for_all_processes) {
// Renderer metrics-by-tab only make sense if we're visiting all // Renderer metrics-by-tab only make sense if we're visiting all
// render processes. // render processes.
for (const resource_coordinator::mojom::PageInfoPtr& page_info : for (const PageInfo& page_info : process_info.page_infos) {
process_info->page_infos) { if (page_info.hosts_main_frame) {
if (page_info->hosts_main_frame) { per_tab_metrics.AssociateMainFrame(page_info.ukm_source_id,
per_tab_metrics.AssociateMainFrame(page_info->ukm_source_id, pmd.pid(), page_info.tab_id,
pmd.pid(), page_info->tab_id,
process_pmf_kb); process_pmf_kb);
} else { } else {
per_tab_metrics.AssociateSubFrame(page_info->ukm_source_id, per_tab_metrics.AssociateSubFrame(page_info.ukm_source_id,
pmd.pid(), page_info->tab_id, pmd.pid(), page_info.tab_id,
process_pmf_kb); process_pmf_kb);
} }
} }
...@@ -648,8 +652,8 @@ void ProcessMemoryMetricsEmitter::CollateResults() { ...@@ -648,8 +652,8 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
// emit any per-renderer URLs. This is not ideal, but UKM does not // emit any per-renderer URLs. This is not ideal, but UKM does not
// support multiple-URLs per entry, and we must have one entry per // support multiple-URLs per entry, and we must have one entry per
// process. // process.
if (process_info->page_infos.size() == 1) { if (process_info.page_infos.size() == 1) {
single_page_info = std::move(process_info->page_infos[0]); single_page_info = &process_info.page_infos[0];
} }
} }
...@@ -728,3 +732,67 @@ void ProcessMemoryMetricsEmitter::CollateResults() { ...@@ -728,3 +732,67 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
per_tab_metrics.RecordPmfs(GetUkmRecorder()); per_tab_metrics.RecordPmfs(GetUkmRecorder());
} }
} }
namespace {
// Returns true iff the given |process| is responsible for hosting the
// main-frame of the given |page|.
bool HostsMainFrame(performance_manager::ProcessNodeImpl* process,
performance_manager::PageNodeImpl* page) {
performance_manager::FrameNodeImpl* main_frame = page->GetMainFrameNode();
if (main_frame == nullptr) {
// |process| can't host a frame that doesn't exist.
return false;
}
return main_frame->process_node() == process;
}
} // namespace
void ProcessMemoryMetricsEmitter::GetProcessToPageInfoMap(
GetProcessToPageInfoMapCallback callback,
performance_manager::Graph* graph) {
std::vector<ProcessInfo> process_infos;
std::vector<performance_manager::ProcessNodeImpl*> process_nodes =
graph->GetAllProcessNodes();
for (auto* process_node : process_nodes) {
if (process_node->process_id() == base::kNullProcessId)
continue;
ProcessInfo process_info;
process_info.pid = process_node->process_id();
process_info.launch_time = process_node->launch_time();
std::set<performance_manager::PageNodeImpl*> page_nodes =
process_node->GetAssociatedPageCoordinationUnits();
for (performance_manager::PageNodeImpl* page_node : page_nodes) {
if (page_node->ukm_source_id() == ukm::kInvalidSourceId)
continue;
PageInfo page_info;
page_info.ukm_source_id = page_node->ukm_source_id();
page_info.tab_id = page_node->id().id;
page_info.hosts_main_frame = HostsMainFrame(process_node, page_node);
page_info.is_visible = page_node->is_visible();
page_info.time_since_last_visibility_change =
page_node->TimeSinceLastVisibilityChange();
page_info.time_since_last_navigation =
page_node->TimeSinceLastNavigation();
process_info.page_infos.push_back(std::move(page_info));
}
process_infos.push_back(std::move(process_info));
}
std::move(callback).Run(std::move(process_infos));
}
ProcessMemoryMetricsEmitter::ProcessInfo::ProcessInfo() = default;
ProcessMemoryMetricsEmitter::ProcessInfo::ProcessInfo(ProcessInfo&& other) =
default;
ProcessMemoryMetricsEmitter::ProcessInfo::~ProcessInfo() = default;
ProcessMemoryMetricsEmitter::ProcessInfo&
ProcessMemoryMetricsEmitter::ProcessInfo::operator=(const ProcessInfo& other) =
default;
...@@ -5,20 +5,25 @@ ...@@ -5,20 +5,25 @@
#ifndef CHROME_BROWSER_METRICS_PROCESS_MEMORY_METRICS_EMITTER_H_ #ifndef CHROME_BROWSER_METRICS_PROCESS_MEMORY_METRICS_EMITTER_H_
#define CHROME_BROWSER_METRICS_PROCESS_MEMORY_METRICS_EMITTER_H_ #define CHROME_BROWSER_METRICS_PROCESS_MEMORY_METRICS_EMITTER_H_
#include <unordered_map>
#include <vector> #include <vector>
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/process/process_handle.h" #include "base/process/process_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h"
#include "services/resource_coordinator/public/mojom/coordination_unit_introspector.mojom.h"
namespace ukm { namespace ukm {
class UkmRecorder; class UkmRecorder;
} }
namespace performance_manager {
class Graph;
}
// This class asynchronously fetches memory metrics for each process, and then // This class asynchronously fetches memory metrics for each process, and then
// emits UMA metrics from those metrics. // emits UMA metrics from those metrics.
// Each instance is self-owned, and will delete itself once it has finished // Each instance is self-owned, and will delete itself once it has finished
...@@ -29,6 +34,9 @@ class UkmRecorder; ...@@ -29,6 +34,9 @@ class UkmRecorder;
class ProcessMemoryMetricsEmitter class ProcessMemoryMetricsEmitter
: public base::RefCountedThreadSafe<ProcessMemoryMetricsEmitter> { : public base::RefCountedThreadSafe<ProcessMemoryMetricsEmitter> {
public: public:
struct PageInfo;
struct ProcessInfo;
// Use this constructor to emit UKM and UMA from all processes, i.e. // Use this constructor to emit UKM and UMA from all processes, i.e.
// browser process, gpu process, and all renderers. // browser process, gpu process, and all renderers.
ProcessMemoryMetricsEmitter(); ProcessMemoryMetricsEmitter();
...@@ -50,10 +58,9 @@ class ProcessMemoryMetricsEmitter ...@@ -50,10 +58,9 @@ class ProcessMemoryMetricsEmitter
bool success, bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump); std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);
// Virtual for testing. Callback invoked when resource_coordinator service // Virtual for testing. Callback invoked when the performance_manager
// returns info for each process. // returns info for each process.
virtual void ReceivedProcessInfos( virtual void ReceivedProcessInfos(std::vector<ProcessInfo> process_infos);
std::vector<resource_coordinator::mojom::ProcessInfoPtr> process_infos);
// Virtual for testing. // Virtual for testing.
virtual ukm::UkmRecorder* GetUkmRecorder(); virtual ukm::UkmRecorder* GetUkmRecorder();
...@@ -75,7 +82,10 @@ class ProcessMemoryMetricsEmitter ...@@ -75,7 +82,10 @@ class ProcessMemoryMetricsEmitter
// be collated. // be collated.
void CollateResults(); void CollateResults();
resource_coordinator::mojom::CoordinationUnitIntrospectorPtr introspector_; using GetProcessToPageInfoMapCallback =
base::OnceCallback<void(std::vector<ProcessInfo>)>;
static void GetProcessToPageInfoMap(GetProcessToPageInfoMapCallback callback,
performance_manager::Graph* graph);
// The results of each request are cached. When both requests are finished, // The results of each request are cached. When both requests are finished,
// the results are collated. // the results are collated.
...@@ -83,9 +93,8 @@ class ProcessMemoryMetricsEmitter ...@@ -83,9 +93,8 @@ class ProcessMemoryMetricsEmitter
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump_; std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump_;
bool get_process_urls_in_progress_ = false; bool get_process_urls_in_progress_ = false;
// The key is ProcessInfoPtr::pid. // The key is ProcessInfo::pid.
std::unordered_map<int64_t, resource_coordinator::mojom::ProcessInfoPtr> base::flat_map<base::ProcessId, ProcessInfo> process_infos_;
process_infos_;
// Specify this pid_scope_ to only record the memory metrics of the specific // Specify this pid_scope_ to only record the memory metrics of the specific
// process. // process.
...@@ -94,4 +103,29 @@ class ProcessMemoryMetricsEmitter ...@@ -94,4 +103,29 @@ class ProcessMemoryMetricsEmitter
DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitter); DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitter);
}; };
// A |PageInfo| describes some metrics about a particular page with respect to
// a given process.
struct ProcessMemoryMetricsEmitter::PageInfo {
// Identifier to distinguish which UMK Source this |PageInfo| corresponds to.
ukm::SourceId ukm_source_id;
// Identifier to distinguish which tab this |PageInfo| corresponds to.
uint64_t tab_id;
// True iff the process for this |PageInfo| hosts the main frame of the page.
bool hosts_main_frame;
bool is_visible;
base::TimeDelta time_since_last_navigation;
base::TimeDelta time_since_last_visibility_change;
};
struct ProcessMemoryMetricsEmitter::ProcessInfo {
ProcessInfo();
ProcessInfo(ProcessInfo&& other);
~ProcessInfo();
ProcessInfo& operator=(const ProcessInfo& other);
base::ProcessId pid;
std::vector<PageInfo> page_infos;
base::Time launch_time;
};
#endif // CHROME_BROWSER_METRICS_PROCESS_MEMORY_METRICS_EMITTER_H_ #endif // CHROME_BROWSER_METRICS_PROCESS_MEMORY_METRICS_EMITTER_H_
...@@ -105,9 +105,7 @@ class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter { ...@@ -105,9 +105,7 @@ class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter {
QuitIfFinished(); QuitIfFinished();
} }
void ReceivedProcessInfos( void ReceivedProcessInfos(std::vector<ProcessInfo> process_infos) override {
std::vector<resource_coordinator::mojom::ProcessInfoPtr> process_infos)
override {
ProcessMemoryMetricsEmitter::ReceivedProcessInfos(std::move(process_infos)); ProcessMemoryMetricsEmitter::ReceivedProcessInfos(std::move(process_infos));
finished_process_info_ = true; finished_process_info_ = true;
QuitIfFinished(); QuitIfFinished();
......
...@@ -21,10 +21,10 @@ using GlobalMemoryDumpPtr = memory_instrumentation::mojom::GlobalMemoryDumpPtr; ...@@ -21,10 +21,10 @@ using GlobalMemoryDumpPtr = memory_instrumentation::mojom::GlobalMemoryDumpPtr;
using ProcessMemoryDumpPtr = using ProcessMemoryDumpPtr =
memory_instrumentation::mojom::ProcessMemoryDumpPtr; memory_instrumentation::mojom::ProcessMemoryDumpPtr;
using OSMemDumpPtr = memory_instrumentation::mojom::OSMemDumpPtr; using OSMemDumpPtr = memory_instrumentation::mojom::OSMemDumpPtr;
using PageInfoPtr = resource_coordinator::mojom::PageInfoPtr; using PageInfo = ProcessMemoryMetricsEmitter::PageInfo;
using ProcessType = memory_instrumentation::mojom::ProcessType; using ProcessType = memory_instrumentation::mojom::ProcessType;
using ProcessInfoPtr = resource_coordinator::mojom::ProcessInfoPtr; using ProcessInfo = ProcessMemoryMetricsEmitter::ProcessInfo;
using ProcessInfoVector = std::vector<ProcessInfoPtr>; using ProcessInfoVector = std::vector<ProcessInfo>;
namespace { namespace {
...@@ -501,60 +501,57 @@ ProcessInfoVector GetProcessInfo(ukm::TestUkmRecorder& ukm_recorder) { ...@@ -501,60 +501,57 @@ ProcessInfoVector GetProcessInfo(ukm::TestUkmRecorder& ukm_recorder) {
// Process 200 always has no URLs. // Process 200 always has no URLs.
{ {
ProcessInfoPtr process_info( ProcessInfo process_info;
resource_coordinator::mojom::ProcessInfo::New()); process_info.pid = 200;
process_info->pid = 200;
process_infos.push_back(std::move(process_info)); process_infos.push_back(std::move(process_info));
} }
// Process kTestRendererPid201 always has 1 URL // Process kTestRendererPid201 always has 1 URL
{ {
ProcessInfoPtr process_info( ProcessInfo process_info;
resource_coordinator::mojom::ProcessInfo::New()); process_info.pid = kTestRendererPid201;
process_info->pid = kTestRendererPid201;
ukm::SourceId first_source_id = ukm::UkmRecorder::GetNewSourceID(); ukm::SourceId first_source_id = ukm::UkmRecorder::GetNewSourceID();
ukm_recorder.UpdateSourceURL(first_source_id, ukm_recorder.UpdateSourceURL(first_source_id,
GURL("http://www.url201.com/")); GURL("http://www.url201.com/"));
PageInfoPtr page_info(resource_coordinator::mojom::PageInfo::New()); PageInfo page_info;
page_info->ukm_source_id = first_source_id; page_info.ukm_source_id = first_source_id;
page_info->tab_id = 201; page_info.tab_id = 201;
page_info->hosts_main_frame = true; page_info.hosts_main_frame = true;
page_info->is_visible = true; page_info.is_visible = true;
page_info->time_since_last_visibility_change = page_info.time_since_last_visibility_change =
base::TimeDelta::FromSeconds(15); base::TimeDelta::FromSeconds(15);
page_info->time_since_last_navigation = base::TimeDelta::FromSeconds(20); page_info.time_since_last_navigation = base::TimeDelta::FromSeconds(20);
process_info->page_infos.push_back(std::move(page_info)); process_info.page_infos.push_back(page_info);
process_infos.push_back(std::move(process_info)); process_infos.push_back(std::move(process_info));
} }
// Process kTestRendererPid202 always has 2 URL // Process kTestRendererPid202 always has 2 URL
{ {
ProcessInfoPtr process_info( ProcessInfo process_info;
resource_coordinator::mojom::ProcessInfo::New()); process_info.pid = kTestRendererPid202;
process_info->pid = kTestRendererPid202;
ukm::SourceId first_source_id = ukm::UkmRecorder::GetNewSourceID(); ukm::SourceId first_source_id = ukm::UkmRecorder::GetNewSourceID();
ukm::SourceId second_source_id = ukm::UkmRecorder::GetNewSourceID(); ukm::SourceId second_source_id = ukm::UkmRecorder::GetNewSourceID();
ukm_recorder.UpdateSourceURL(first_source_id, ukm_recorder.UpdateSourceURL(first_source_id,
GURL("http://www.url2021.com/")); GURL("http://www.url2021.com/"));
ukm_recorder.UpdateSourceURL(second_source_id, ukm_recorder.UpdateSourceURL(second_source_id,
GURL("http://www.url2022.com/")); GURL("http://www.url2022.com/"));
PageInfoPtr page_info1(resource_coordinator::mojom::PageInfo::New()); PageInfo page_info1;
page_info1->ukm_source_id = first_source_id; page_info1.ukm_source_id = first_source_id;
page_info1->tab_id = 2021; page_info1.tab_id = 2021;
page_info1->hosts_main_frame = true; page_info1.hosts_main_frame = true;
page_info1->time_since_last_visibility_change = page_info1.time_since_last_visibility_change =
base::TimeDelta::FromSeconds(11); base::TimeDelta::FromSeconds(11);
page_info1->time_since_last_navigation = base::TimeDelta::FromSeconds(21); page_info1.time_since_last_navigation = base::TimeDelta::FromSeconds(21);
PageInfoPtr page_info2(resource_coordinator::mojom::PageInfo::New()); PageInfo page_info2;
page_info2->ukm_source_id = second_source_id; page_info2.ukm_source_id = second_source_id;
page_info2->tab_id = 2022; page_info2.tab_id = 2022;
page_info2->hosts_main_frame = true; page_info2.hosts_main_frame = true;
page_info2->time_since_last_visibility_change = page_info2.time_since_last_visibility_change =
base::TimeDelta::FromSeconds(12); base::TimeDelta::FromSeconds(12);
page_info2->time_since_last_navigation = base::TimeDelta::FromSeconds(22); page_info2.time_since_last_navigation = base::TimeDelta::FromSeconds(22);
process_info->page_infos.push_back(std::move(page_info1)); process_info.page_infos.push_back(std::move(page_info1));
process_info->page_infos.push_back(std::move(page_info2)); process_info.page_infos.push_back(std::move(page_info2));
process_infos.push_back(std::move(process_info)); process_infos.push_back(std::move(process_info));
} }
......
// Copyright 2017 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/graph/graph_introspector_impl.h"
#include <set>
#include <utility>
#include <vector>
#include "base/process/process_handle.h"
#include "base/time/time.h"
#include "chrome/browser/performance_manager/graph/frame_node_impl.h"
#include "chrome/browser/performance_manager/graph/graph.h"
#include "chrome/browser/performance_manager/graph/page_node_impl.h"
#include "chrome/browser/performance_manager/graph/process_node_impl.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
namespace {
using performance_manager::FrameNodeImpl;
using performance_manager::PageNodeImpl;
using performance_manager::ProcessNodeImpl;
// Returns true iff the given |process| is responsible for hosting the
// main-frame of the given |page|.
bool HostsMainFrame(ProcessNodeImpl* process, PageNodeImpl* page) {
FrameNodeImpl* main_frame = page->GetMainFrameNode();
if (main_frame == nullptr) {
// |process| can't host a frame that doesn't exist.
return false;
}
return main_frame->process_node() == process;
}
} // namespace
namespace performance_manager {
CoordinationUnitIntrospectorImpl::CoordinationUnitIntrospectorImpl(Graph* graph)
: graph_(graph) {}
CoordinationUnitIntrospectorImpl::~CoordinationUnitIntrospectorImpl() = default;
void CoordinationUnitIntrospectorImpl::GetProcessToURLMap(
GetProcessToURLMapCallback callback) {
std::vector<resource_coordinator::mojom::ProcessInfoPtr> process_infos;
std::vector<ProcessNodeImpl*> process_nodes = graph_->GetAllProcessNodes();
for (auto* process_node : process_nodes) {
if (process_node->process_id() == base::kNullProcessId)
continue;
resource_coordinator::mojom::ProcessInfoPtr process_info(
resource_coordinator::mojom::ProcessInfo::New());
process_info->pid = process_node->process_id();
process_info->launch_time = process_node->launch_time();
std::set<PageNodeImpl*> page_nodes =
process_node->GetAssociatedPageCoordinationUnits();
for (PageNodeImpl* page_node : page_nodes) {
if (page_node->ukm_source_id() == ukm::kInvalidSourceId)
continue;
resource_coordinator::mojom::PageInfoPtr page_info(
resource_coordinator::mojom::PageInfo::New());
page_info->ukm_source_id = page_node->ukm_source_id();
page_info->tab_id = page_node->id().id;
page_info->hosts_main_frame = HostsMainFrame(process_node, page_node);
page_info->is_visible = page_node->is_visible();
page_info->time_since_last_visibility_change =
page_node->TimeSinceLastVisibilityChange();
page_info->time_since_last_navigation =
page_node->TimeSinceLastNavigation();
process_info->page_infos.push_back(std::move(page_info));
}
process_infos.push_back(std::move(process_info));
}
std::move(callback).Run(std::move(process_infos));
}
void CoordinationUnitIntrospectorImpl::BindToInterface(
resource_coordinator::mojom::CoordinationUnitIntrospectorRequest request,
const service_manager::BindSourceInfo& source_info) {
bindings_.AddBinding(this, std::move(request));
}
} // namespace performance_manager
// Copyright 2017 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 CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_GRAPH_INTROSPECTOR_IMPL_H_
#define CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_GRAPH_INTROSPECTOR_IMPL_H_
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/resource_coordinator/public/mojom/coordination_unit_introspector.mojom.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
namespace service_manager {
struct BindSourceInfo;
} // namespace service_manager
namespace performance_manager {
class Graph;
class CoordinationUnitIntrospectorImpl
: public resource_coordinator::mojom::CoordinationUnitIntrospector {
public:
explicit CoordinationUnitIntrospectorImpl(Graph* graph);
~CoordinationUnitIntrospectorImpl() override;
void BindToInterface(
resource_coordinator::mojom::CoordinationUnitIntrospectorRequest request,
const service_manager::BindSourceInfo& source_info);
// Overridden from resource_coordinator::mojom::CoordinationUnitIntrospector:
void GetProcessToURLMap(GetProcessToURLMapCallback callback) override;
private:
Graph* const graph_;
mojo::BindingSet<resource_coordinator::mojom::CoordinationUnitIntrospector>
bindings_;
DISALLOW_COPY_AND_ASSIGN(CoordinationUnitIntrospectorImpl);
};
} // namespace performance_manager
#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_GRAPH_INTROSPECTOR_IMPL_H_
...@@ -41,8 +41,7 @@ PerformanceManager* PerformanceManager::GetInstance() { ...@@ -41,8 +41,7 @@ PerformanceManager* PerformanceManager::GetInstance() {
return g_performance_manager; return g_performance_manager;
} }
PerformanceManager::PerformanceManager() PerformanceManager::PerformanceManager() : task_runner_(CreateTaskRunner()) {
: task_runner_(CreateTaskRunner()), introspector_(&graph_) {
DETACH_FROM_SEQUENCE(sequence_checker_); DETACH_FROM_SEQUENCE(sequence_checker_);
} }
...@@ -252,10 +251,6 @@ void PerformanceManager::OnStartImpl( ...@@ -252,10 +251,6 @@ void PerformanceManager::OnStartImpl(
std::unique_ptr<service_manager::Connector> connector) { std::unique_ptr<service_manager::Connector> connector) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
interface_registry_.AddInterface(
base::BindRepeating(&CoordinationUnitIntrospectorImpl::BindToInterface,
base::Unretained(&introspector_)));
// Register new |GraphObserver| implementations here. // Register new |GraphObserver| implementations here.
auto page_signal_generator_impl = std::make_unique<PageSignalGeneratorImpl>(); auto page_signal_generator_impl = std::make_unique<PageSignalGeneratorImpl>();
interface_registry_.AddInterface( interface_registry_.AddInterface(
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "chrome/browser/performance_manager/graph/graph.h" #include "chrome/browser/performance_manager/graph/graph.h"
#include "chrome/browser/performance_manager/graph/graph_introspector_impl.h"
#include "chrome/browser/performance_manager/performance_manager.h" #include "chrome/browser/performance_manager/performance_manager.h"
#include "chrome/browser/performance_manager/webui_graph_dump_impl.h" #include "chrome/browser/performance_manager/webui_graph_dump_impl.h"
#include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h" #include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
...@@ -136,8 +135,6 @@ class PerformanceManager { ...@@ -136,8 +135,6 @@ class PerformanceManager {
// The registered graph observers. // The registered graph observers.
std::vector<std::unique_ptr<GraphObserver>> observers_; std::vector<std::unique_ptr<GraphObserver>> observers_;
CoordinationUnitIntrospectorImpl introspector_;
// Provided to |graph_|. // Provided to |graph_|.
// TODO(siggi): This no longer needs to go through mojo. // TODO(siggi): This no longer needs to go through mojo.
std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_; std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_;
......
...@@ -10,7 +10,6 @@ mojom_component("mojom") { ...@@ -10,7 +10,6 @@ mojom_component("mojom") {
sources = [ sources = [
"coordination_unit.mojom", "coordination_unit.mojom",
"coordination_unit_introspector.mojom",
"lifecycle.mojom", "lifecycle.mojom",
"memory_instrumentation/constants.mojom", "memory_instrumentation/constants.mojom",
"memory_instrumentation/memory_instrumentation.mojom", "memory_instrumentation/memory_instrumentation.mojom",
......
// Copyright 2017 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.
module resource_coordinator.mojom;
import "services/resource_coordinator/public/mojom/coordination_unit.mojom";
import "mojo/public/mojom/base/process_id.mojom";
import "mojo/public/mojom/base/time.mojom";
// A |PageInfo| describes some metrics about a particular page with respect to
// a given process.
struct PageInfo {
// Identifier to distinguish which URL this |PageInfo| corresponds to.
int64 ukm_source_id;
// Identifier to distinguish which tab this |PageInfo| corresponds to.
uint64 tab_id;
// True iff the process for this |PageInfo| hosts the main frame of the page.
bool hosts_main_frame;
bool is_visible;
mojo_base.mojom.TimeDelta time_since_last_navigation;
mojo_base.mojom.TimeDelta time_since_last_visibility_change;
};
struct ProcessInfo {
mojo_base.mojom.ProcessId pid;
array<PageInfo> page_infos;
mojo_base.mojom.Time? launch_time;
};
interface CoordinationUnitIntrospector {
// Returns an array that describes the current topology of Chrome, with
// respect to the relationship between processes and hosted frame URLs.
GetProcessToURLMap() => (array<ProcessInfo> process_infos);
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment