blob: 53fe4a107a35befcfd1436fbd92569db660ba291 [file] [log] [blame]
// Copyright 2012 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_METRICS_POWER_PROCESS_MONITOR_H_
#define CHROME_BROWSER_METRICS_POWER_PROCESS_MONITOR_H_
#include <array>
#include <map>
#include <memory>
#include <optional>
#include "base/observer_list.h"
#include "base/process/process_handle.h"
#include "base/scoped_multi_source_observation.h"
#include "build/build_config.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/common/process_type.h"
namespace base {
class ProcessMetrics;
}
enum MonitoredProcessType {
kBrowser,
kRenderer,
kExtensionPersistent,
kExtensionEvent,
kGpu,
kUtility,
kNetwork,
kOther, // Contains all other process types that are not explicitly tracked.
kCount,
};
MonitoredProcessType
GetMonitoredProcessTypeForNonRendererChildProcessForTesting(
const content::ChildProcessData& data);
struct ProcessInfo {
ProcessInfo(MonitoredProcessType type,
std::unique_ptr<base::ProcessMetrics> process_metrics);
~ProcessInfo();
MonitoredProcessType type;
std::unique_ptr<base::ProcessMetrics> process_metrics;
// The time at which the first process sample was taken (i.e. When the
// constructor is called). Used to distribute the calculated resource usage of
// the first interval over the full kLongIntervalDuration. Set to nullopt
// after the metrics for the first interval is calculated because the
// subsequent intervals will always take the full duration of
// kLongIntervalDuration.
std::optional<base::TimeTicks> first_sample_time;
};
// ProcessMonitor is a tool which allows the sampling of power-related metrics
// for all Chrome processes. The metrics sampling is driven externally by
// calling SampleAllProcesses() periodically.
class ProcessMonitor : public content::BrowserChildProcessObserver,
public content::RenderProcessHostCreationObserver,
public content::RenderProcessHostObserver {
public:
struct Metrics {
Metrics();
Metrics(const Metrics& other);
Metrics& operator=(const Metrics& other);
~Metrics();
// The percentage of time spent executing, across all threads of the
// process, in the interval since the last time the metric was sampled. This
// can exceed 100% in multi-thread processes running on multi-core systems.
// nullopt if there was an error calculating the CPU usage.
std::optional<double> cpu_usage;
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
BUILDFLAG(IS_AIX)
// Returns the number of average idle cpu wakeups per second since the last
// time the metric was sampled.
int idle_wakeups = 0;
#endif
#if BUILDFLAG(IS_MAC)
// The number of average "package idle exits" per second since the last
// time the metric was sampled. See base/process/process_metrics.h for a
// more detailed explanation.
int package_idle_wakeups = 0;
#endif
};
class Observer : public base::CheckedObserver {
public:
// Provides aggregated sampled metrics for all Chrome process of type
// `type`. This is called once per process type whenever
// `SampleAllProcesses` is called.
virtual void OnMetricsSampled(MonitoredProcessType type,
const Metrics& metrics) {}
// Provides the aggregated sampled metrics from every Chrome process. This
// is called once whenever `SampleAllProcesses` is called.
virtual void OnAggregatedMetricsSampled(const Metrics& metrics) {}
};
ProcessMonitor();
ProcessMonitor(const ProcessMonitor&) = delete;
ProcessMonitor& operator=(const ProcessMonitor&) = delete;
~ProcessMonitor() override;
// Gather the metrics for all the processes.
virtual void SampleAllProcesses(Observer* observer);
private:
// content::RenderProcessHostCreationObserver:
void OnRenderProcessHostCreated(
content::RenderProcessHost* render_process_host) override;
// content::RenderProcessHostObserver:
void RenderProcessReady(
content::RenderProcessHost* render_process_host) override;
void RenderProcessExited(
content::RenderProcessHost* render_process_host,
const content::ChildProcessTerminationInfo& info) override;
void RenderProcessHostDestroyed(
content::RenderProcessHost* render_process_host) override;
// content::BrowserChildProcessObserver:
void BrowserChildProcessLaunchedAndConnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessCrashed(
const content::ChildProcessData& data,
const content::ChildProcessTerminationInfo& info) override;
void BrowserChildProcessKilled(
const content::ChildProcessData& data,
const content::ChildProcessTerminationInfo& info) override;
void BrowserChildProcessExitedNormally(
const content::ChildProcessData& data,
const content::ChildProcessTerminationInfo& info) override;
void OnBrowserChildProcessExited(
const content::ChildProcessData& data,
const content::ChildProcessTerminationInfo& info);
base::ScopedMultiSourceObservation<content::RenderProcessHost,
content::RenderProcessHostObserver>
render_process_host_observations_{this};
ProcessInfo browser_process_info_;
std::map<content::RenderProcessHost*, ProcessInfo> render_process_infos_;
std::map<int, ProcessInfo> browser_child_process_infos_;
// The metrics for the processes that exited during the last interval. Added
// to the current interval's sample and then reset to zero.
std::array<Metrics, MonitoredProcessType::kCount> exited_processes_metrics_;
};
#endif // CHROME_BROWSER_METRICS_POWER_PROCESS_MONITOR_H_