File: utility_process_host.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (236 lines) | stat: -rw-r--r-- 8,176 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// 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 CONTENT_BROWSER_SERVICE_HOST_UTILITY_PROCESS_HOST_H_
#define CONTENT_BROWSER_SERVICE_HOST_UTILITY_PROCESS_HOST_H_

#include <memory>
#include <optional>
#include <string>
#include <variant>
#include <vector>

#include "base/environment.h"
#include "base/process/launch.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "content/browser/child_process_launcher.h"
#include "content/common/child_process.mojom.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/common/zygote/zygote_buildflags.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "sandbox/policy/mojom/sandbox.mojom.h"

#if BUILDFLAG(USE_ZYGOTE)
#include "content/public/common/zygote/zygote_handle.h"
#endif  // BUILDFLAG(USE_ZYGOTE)

namespace base {
class Thread;
}  // namespace base

#if BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)
namespace viz {
class GpuClient;
}  // namespace viz
#endif  // BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)

namespace content {
class BrowserChildProcessHostImpl;
class InProcessChildThreadParams;

typedef base::Thread* (*UtilityMainThreadFactoryFunction)(
    const InProcessChildThreadParams&);

// This class acts as the browser-side host to a utility child process hosting a
// mojo service. This class lives solely on the UI thread. If you need to bind
// a Mojo interface, specify it via `WithBoundServiceInterfaceOnChildProcess` on
// the `Options` passed in.
class CONTENT_EXPORT UtilityProcessHost
    : public BrowserChildProcessHostDelegate {
 public:
  static void RegisterUtilityMainThreadFactory(
      UtilityMainThreadFactoryFunction create);

  // Interface which may be passed to a UtilityProcessHost on construction. All
  // methods are called from the IO thread.
  class Client {
   public:
    virtual ~Client() {}

    virtual void OnProcessLaunched(const base::Process& process) {}
    virtual void OnProcessTerminatedNormally() {}
    virtual void OnProcessCrashed() {}
  };

  struct CONTENT_EXPORT Options {
    Options();
    ~Options();

    Options(const Options&) = delete;
    Options& operator=(const Options&) = delete;

    Options(Options&&);
    Options& operator=(Options&&);

    // Makes the process run with a specific sandbox type, or unsandboxed if
    // Sandbox::kNoSandbox is specified.
    Options& WithSandboxType(sandbox::mojom::Sandbox sandbox_type);

    // Sets the name of the process to appear in the task manager.
    Options& WithName(const std::u16string& name);

    // Sets the name used for metrics reporting. This should not be a localized
    // name. This is recorded to metrics, so update UtilityProcessNameHash enum
    // in enums.xml if new values are passed here.
    Options& WithMetricsName(const std::string& metrics_name);

    Options& WithChildFlags(int flags);

    // Provides extra switches to append to the process's command line.
    Options& WithExtraCommandLineSwitches(std::vector<std::string> switches);

#if BUILDFLAG(IS_WIN)
    // Specifies libraries to preload before the sandbox is locked down. Paths
    // should be absolute.
    Options& WithPreloadLibraries(const std::vector<base::FilePath>& preloads);
#endif  // BUILDFLAG(IS_WIN)

    // Allows the child process to bind viz.mojom.Gpu.
    Options& WithGpuClientAllowed();

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
    // Adds to ChildProcessLauncherFileData::files_to_preload, which maps |key|
    // -> |file| in the new process's base::FileDescriptorStore.
    Options& WithFileToPreload(
        std::string key,
        std::variant<base::FilePath, base::ScopedFD> file);
#endif

#if BUILDFLAG(IS_POSIX)
    Options& WithEnvironment(const base::EnvironmentMap& env);
#endif

#if BUILDFLAG(USE_ZYGOTE)
    Options& WithZygoteForTesting(ZygoteCommunication* handle);
#endif  // BUILDFLAG(USE_ZYGOTE)

    // Requests that the process bind a receiving pipe targeting the interface
    // named by `receiver`. Calls to this method generally end up in
    // `ChildThreadImpl::OnBindReceiver()` and the option is used for testing
    // only.
    Options& WithBoundReceiverOnChildProcessForTesting(
        mojo::GenericPendingReceiver receiver);

    // Requests that the utility process bind a receiving pipe targeting the
    // service interface named by `receiver`.
    Options& WithBoundServiceInterfaceOnChildProcess(
        mojo::GenericPendingReceiver receiver);

    // Passes the contents of this Options object to a newly returned Options
    // value. This can be called when moving an in-line built Options object
    // directly into a call to `Start`.
    Options Pass();

   private:
    friend class UtilityProcessHost;

    sandbox::mojom::Sandbox sandbox_type_;

    // Map of environment variables to values.
    base::EnvironmentMap env_;

    // The non-localized name used for metrics reporting.
    std::string metrics_name_;

    // ChildProcessHost flags to use when starting the child process.
    int child_flags_;

    // Extra command line switches to append.
    std::vector<std::string> extra_switches_;

#if BUILDFLAG(IS_WIN)
    // Libraries to load before sandbox lockdown. Only used on Windows.
    std::vector<base::FilePath> preload_libraries_;
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(USE_ZYGOTE)
    std::optional<raw_ptr<ZygoteCommunication>> zygote_for_testing_;
#endif  // BUILDFLAG(USE_ZYGOTE)

#if BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)
    // Whether or not to bind viz::mojom::Gpu to the utility process.
    bool allowed_gpu_;
#endif  // BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)

    // A mojo receiver to bind once the process starts.
    std::optional<mojo::GenericPendingReceiver> receiver_to_bind_;

    // A mojo service interface to bind once the process starts.
    std::optional<mojo::GenericPendingReceiver> service_interface_to_bind_;

    // Extra files and file descriptors to preload in the new process.
    std::unique_ptr<ChildProcessLauncherFileData> file_data_;

    // The process name used to identify the process in task manager.
    std::u16string name_;
  };

  // Creates and starts a new UtilityProcessHost with the specified `Options`.
  // Pass a `client` if delegate callbacks are needed.
  static bool Start(Options options, std::unique_ptr<Client> client = nullptr);

  UtilityProcessHost(const UtilityProcessHost&) = delete;
  UtilityProcessHost& operator=(const UtilityProcessHost&) = delete;

 private:
  UtilityProcessHost(Options options, std::unique_ptr<Client> client);

  ~UtilityProcessHost() override;

  // Returns a control interface for the running child process.
  mojom::ChildProcess* GetChildProcess();

  void MaybeBindMojoInterfaces();

  // Starts the child process if needed, returns true on success.
  bool StartProcess();

  // BrowserChildProcessHostDelegate:
  void OnProcessLaunched() override;
  void OnProcessLaunchFailed(int error_code) override;
  void OnProcessCrashed(int exit_code) override;
  std::optional<std::string> GetServiceName() override;
  void BindHostReceiver(mojo::GenericPendingReceiver receiver) override;

  Options options_;

  // Child process host implementation.
  std::unique_ptr<BrowserChildProcessHostImpl> process_;

  // Used in single-process mode instead of |process_|.
  std::unique_ptr<base::Thread> in_process_thread_;

  // Indicates whether the process has been successfully launched yet, or if
  // launch failed.
  enum class LaunchState {
    kLaunchInProgress,
    kLaunchComplete,
    kLaunchFailed,
  };
  LaunchState launch_state_ = LaunchState::kLaunchInProgress;

#if BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)
  std::unique_ptr<viz::GpuClient, base::OnTaskRunnerDeleter> gpu_client_;
#endif  // BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)

  std::unique_ptr<Client> client_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_SERVICE_HOST_UTILITY_PROCESS_HOST_H_