blob: 9773afe6b27d740d6ac5dd2fe5a73a74d19066f9 [file] [log] [blame]
Aman Verma327f9b42022-11-08 12:44:401// Copyright 2022 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_PROCESS_CURRENT_PROCESS_H_
6#define BASE_PROCESS_CURRENT_PROCESS_H_
7
David Benjamindc19d422023-03-14 16:31:578#include <atomic>
Aman Verma327f9b42022-11-08 12:44:409#include <string>
David Benjamindc19d422023-03-14 16:31:5710
Aman Verma327f9b42022-11-08 12:44:4011#include "base/base_export.h"
Etienne Pierre-doray2a39a4e32025-02-26 19:42:1612#include "base/memory/raw_ptr.h"
Aman Verma327f9b42022-11-08 12:44:4013#include "base/no_destructor.h"
14#include "base/process/process_handle.h"
Byoungchan Leeff42d8d2022-12-05 08:22:3615#include "base/synchronization/lock.h"
Aman Verma327f9b42022-11-08 12:44:4016#include "build/buildflag.h"
Etienne Pierre-dorayfc7952f02025-06-06 00:04:3317#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h"
Aman Verma327f9b42022-11-08 12:44:4018
Aman Verma0bf8c112022-11-15 13:01:2419namespace tracing {
20class TraceEventDataSource;
21class CustomEventRecorder;
Etienne Pierre-doray2a39a4e32025-02-26 19:42:1622class TrackNameRecorder;
Aman Verma0bf8c112022-11-15 13:01:2423} // namespace tracing
24
Aman Vermae64a2feb2022-11-30 10:52:4825namespace mojo::core {
26class Channel;
27}
28
Tsuyoshi Horo41f81f22025-04-04 00:23:4529namespace network {
30class ContentDecodingInterceptor;
31} // namespace network
32
Aman Verma327f9b42022-11-08 12:44:4033namespace base {
34namespace test {
35class CurrentProcessForTest;
Aman Vermae64a2feb2022-11-30 10:52:4836} // namespace test
Aman Verma327f9b42022-11-08 12:44:4037
38using CurrentProcessType =
39 perfetto::protos::pbzero::ChromeProcessDescriptor::ProcessType;
40
Aman Vermae64a2feb2022-11-30 10:52:4841// These values are persisted to logs. Entries should not be renumbered and
42// numeric values should never be reused.
43// Use coalesced service process for recording histograms.
44enum class ShortProcessType {
45 kUnspecified = 0,
46 kBrowser = 1,
47 kRenderer = 2,
48 kUtility = 3,
49 kZygote = 4,
50 kSandboxHelper = 5,
51 kGpu = 6,
52 kPpapiPlugin = 7,
53 kPpapiBroker = 8,
54 kServiceNetwork = 9,
55 kServiceStorage = 10,
56 kService = 11,
57 kRendererExtension = 12,
58 kMaxValue = kRendererExtension,
59};
60
Aman Verma327f9b42022-11-08 12:44:4061// CurrentProcess class provides access to set of current process properties
62// which are accessible only from the process itself (e.g. ProcessType,
63// ProcessName).
64// See base::CurrentThread for access to properties of the running
65// thread and base::Process::Current for the properties which are known both
66// from within and without the process (e.g. pid).
67class BASE_EXPORT CurrentProcess {
68 public:
69 static CurrentProcess& GetInstance();
70
71 CurrentProcess(const CurrentProcess&) = delete;
72 CurrentProcess& operator=(const CurrentProcess&) = delete;
73 ~CurrentProcess();
74
75 bool operator==(const CurrentProcess& other) const;
76
77 class TypeKey {
78 private:
79 TypeKey() = default;
80 friend class ::base::test::CurrentProcessForTest;
Aman Verma0bf8c112022-11-15 13:01:2481 friend class ::tracing::TraceEventDataSource;
82 friend class ::tracing::CustomEventRecorder;
Etienne Pierre-doray2a39a4e32025-02-26 19:42:1683 friend class ::tracing::TrackNameRecorder;
Aman Vermae64a2feb2022-11-30 10:52:4884 friend class ::mojo::core::Channel;
Tsuyoshi Horo41f81f22025-04-04 00:23:4585 friend class ::network::ContentDecodingInterceptor;
Aman Verma327f9b42022-11-08 12:44:4086 };
87 // Returns an enum corresponding to the type of the current process (e.g.
88 // browser / renderer / utility / etc). It can be used in metrics or tracing
89 // code — for example, to split a number of low-level events with
90 // process-type-agnostic implementation (e.g. number of posted tasks) by
91 // process type for diagnostic purposes.
92 // To avoid layering violations (i.e. //base or other low-level code modifying
93 // its behaviour based on the //chrome or //content-level concepts like a
94 // "browser" or "renderer" process), the access to this function is controlled
95 // by an explicit list.
96 CurrentProcessType GetType(TypeKey key) {
Etienne Pierre-doray2a39a4e32025-02-26 19:42:1697 return process_type_.load(std::memory_order_relaxed);
Aman Verma327f9b42022-11-08 12:44:4098 }
99
Aman Vermae64a2feb2022-11-30 10:52:48100 ShortProcessType GetShortType(TypeKey key);
101
Aman Verma327f9b42022-11-08 12:44:40102 class NameKey {
103 private:
104 NameKey() = default;
105 friend class ::base::test::CurrentProcessForTest;
Aman Verma0bf8c112022-11-15 13:01:24106 friend class ::tracing::TraceEventDataSource;
Etienne Pierre-doray2a39a4e32025-02-26 19:42:16107 friend class ::tracing::TrackNameRecorder;
Aman Verma327f9b42022-11-08 12:44:40108 };
109 std::string GetName(NameKey key) {
110 AutoLock lock(lock_);
111 return process_name_;
112 }
113
Etienne Pierre-doray2a39a4e32025-02-26 19:42:16114 class BASE_EXPORT Delegate {
115 public:
116 // Called on the main thread of the process whose name is changing,
117 // immediately after the name is set.
118 virtual void OnProcessNameChanged(const std::string& process_name,
119 CurrentProcessType process_type) = 0;
120
121 protected:
122 ~Delegate() = default;
123 };
124
Aman Verma327f9b42022-11-08 12:44:40125 // Sets the name and type of the process for the metrics and tracing. This
126 // function should be called as early as possible in the process's lifetime
127 // before starting any threads, typically in *Main() function. Provide
128 // process_name as an argument if it can't be trivially derived from the
129 // process type.
130 void SetProcessType(CurrentProcessType process_type);
Etienne Pierre-doray2a39a4e32025-02-26 19:42:16131
132 // `delegate` might racily be invoked after resetting, thus its lifetime must
133 // match `CurrentProcess`.
134 void SetDelegate(Delegate* delegate, NameKey key);
Aman Verma327f9b42022-11-08 12:44:40135
136 bool IsProcessNameEmpty() const {
137 AutoLock lock(lock_);
138 return process_name_.empty();
139 }
140
141 private:
142 friend class base::NoDestructor<CurrentProcess>;
143
144 CurrentProcess() = default;
145
Etienne Pierre-doray2a39a4e32025-02-26 19:42:16146 void SetProcessNameAndType(const std::string& process_name,
147 CurrentProcessType process_type);
148
Aman Verma327f9b42022-11-08 12:44:40149 mutable Lock lock_;
150 std::string process_name_;
151 // The process_type_ is set at the startup before processes start running.
152 // However, since it runs in multi-threaded environment and if has to be
153 // changed later, we would want well-defined behaviour even if one thread
154 // writes while another reads. There are some processes (e.g. Service process)
155 // where we don't have a guarantee that it will be called early enough in the
156 // process's lifetime, thus we use std::atomic here.
157 std::atomic<CurrentProcessType> process_type_;
Etienne Pierre-doray2a39a4e32025-02-26 19:42:16158
159 raw_ptr<Delegate> delegate_;
Aman Verma327f9b42022-11-08 12:44:40160};
161
162} // namespace base
163
164#endif // BASE_PROCESS_CURRENT_PROCESS_H_