File: client_connection_manager.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; 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 (153 lines) | stat: -rw-r--r-- 6,394 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
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_HEAP_PROFILING_MULTI_PROCESS_CLIENT_CONNECTION_MANAGER_H_
#define COMPONENTS_HEAP_PROFILING_MULTI_PROCESS_CLIENT_CONNECTION_MANAGER_H_

#include <unordered_set>

#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "content/public/browser/render_process_host_observer.h"

namespace content {
class RenderProcessHost;
}  // namespace content

namespace heap_profiling {

class Controller;
enum class Mode;

// This class is responsible for connecting HeapProfilingClients to the
// HeapProfilingService.
//   * It inherits from content::RenderProcessHostCreationObserver to listen for
//     the creation of the renderer processes.
//   * It registers itself as a content::BrowserChildProcessObserver to listen
//     for the creation of non-renderer processes.
// When a new process is created, it checks the current |Mode| to see whether
// the process should be profiled. If so, it grabs the HeapProfilingClient from
// the newly created process and connects it to the HeapProfilingService.
//
// This class is intended to be used from the browser/privileged process of the
// embedder.
//
// This class must be constructed/accessed/destroyed from the UI thread.
//
// This class can be subclassed for exactly one reason: to allow embedders to
// override AllowedToProfileRenderer in order to prevent incognito renderers
// from being profiled.
class ClientConnectionManager
    : public content::BrowserChildProcessObserver,
      public content::RenderProcessHostCreationObserver,
      public content::RenderProcessHostObserver {
 public:
  // The owner of this instance must guarantee that |controller_| outlives this
  // class.
  // |controller| must be bound to the IO thread.
  ClientConnectionManager(base::WeakPtr<Controller> controller, Mode mode);

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

  ~ClientConnectionManager() override;

  // Start must be called immediately after the constructor. The only reason
  // that this is not a part of the constructor is to allow tests to skip this
  // step.
  void Start();

  Mode GetMode();

  // In addition to profiling `pid`, this will change the Mode to kManual. From
  // here on out, the caller must manually specify processes to be profiled.
  // Invokes `started_profiling_closure` if and when profiling starts
  // successfully.
  void StartProfilingProcess(base::ProcessId pid,
                             mojom::ProfilingService::AddProfilingClientCallback
                                 started_profiling_closure);

  virtual bool AllowedToProfileRenderer(content::RenderProcessHost* host);

 private:
  FRIEND_TEST_ALL_PREFIXES(ChromeClientConnectionManager,
                           ShouldProfileNewRenderer);

  // Exists for testing only.
  void SetModeForTesting(Mode mode);

  // New processes will be profiled as they are created. Existing processes msut
  // be manually checked upon creation.
  void StartProfilingExistingProcessesIfNecessary();

  // BrowserChildProcessObserver
  // Observe connection of non-renderer child processes.
  void BrowserChildProcessLaunchedAndConnected(
      const content::ChildProcessData& data) override;

  void StartProfilingNonRendererChild(
      const content::ChildProcessData& data,
      mojom::ProfilingService::AddProfilingClientCallback
          started_profiling_closure);

  // content::RenderProcessHostCreationObserver
  void OnRenderProcessHostCreated(content::RenderProcessHost* host) override;

  // RenderProcessHostObserver:
  // RenderProcessHostDestroyed() corresponds to death of an underlying
  // RenderProcess. RenderProcessExited() corresponds to when the
  // RenderProcessHost's lifetime is ending. Ideally, we'd only listen to the
  // former, but if the RenderProcessHost is destroyed before the RenderProcess,
  // then the former is never observed.
  void RenderProcessExited(
      content::RenderProcessHost* host,
      const content::ChildProcessTerminationInfo& info) override;
  void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;

  bool ShouldProfileNewRenderer(content::RenderProcessHost* renderer);

  void StartProfilingRenderer(
      content::RenderProcessHost* renderer,
      mojom::ProfilingService::AddProfilingClientCallback
          started_profiling_closure);

  // The owner of this instance must guarantee that |controller_| outlives this
  // class.
  // |controller_| must be bound to the IO thread.
  base::WeakPtr<Controller> controller_;

  Mode mode_;

  base::ScopedMultiSourceObservation<content::RenderProcessHost,
                                     content::RenderProcessHostObserver>
      host_observation_{this};

  // This is used to identify the currently profiled renderers. Elements should
  // only be accessed on the UI thread and their values should be considered
  // opaque.
  //
  // Semantically, the elements must be something that identifies which specific
  // RenderProcess is being profiled. When the underlying RenderProcess goes
  // away, the element must be removed. The RenderProcessHost pointer and the
  // RenderProcessHostCreationObserver notification can be used to provide these
  // semantics.
  //
  // This variable represents renderers that have been instructed to start
  // profiling - it does not reflect whether a renderer is currently still being
  // profiled. That information is only known by the profiling service, and for
  // simplicity, it's easier to just track this variable in this process.
  std::unordered_set<raw_ptr<void, CtnExperimental>> profiled_renderers_;
};

}  // namespace heap_profiling

#endif  // COMPONENTS_HEAP_PROFILING_MULTI_PROCESS_CLIENT_CONNECTION_MANAGER_H_