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
|
// 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_CHILD_PROCESS_HOST_IMPL_H_
#define CONTENT_BROWSER_CHILD_PROCESS_HOST_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/process/process.h"
#include "build/build_config.h"
#include "content/common/child_process.mojom.h"
#include "content/common/content_export.h"
#include "content/public/browser/child_process_host.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/invitation.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/memory/memory_pressure_listener.h"
#endif
namespace IPC {
class Channel;
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
class MessageFilter;
#endif
} // namespace IPC
namespace content {
class ChildProcessHostDelegate;
// Provides common functionality for hosting a child process and processing IPC
// messages between the host and the child process. Users are responsible
// for the actual launching and terminating of the child processes.
class CONTENT_EXPORT ChildProcessHostImpl : public ChildProcessHost,
public IPC::Listener,
public mojom::ChildProcessHost {
public:
ChildProcessHostImpl(const ChildProcessHostImpl&) = delete;
ChildProcessHostImpl& operator=(const ChildProcessHostImpl&) = delete;
~ChildProcessHostImpl() override;
// Derives a tracing process id from a child process id. Child process ids
// cannot be used directly in child process for tracing due to security
// reasons (see: discussion in crrev.com/1173263004). This method is meant to
// be used when tracing for identifying cross-process shared memory from a
// process which knows the child process id of its endpoints. The value
// returned by this method is guaranteed to be equal to the value returned by
// MemoryDumpManager::GetTracingProcessId() in the corresponding child
// process.
//
// Never returns MemoryDumpManager::kInvalidTracingProcessId.
// Returns only memory_instrumentation::mojom::kServiceTracingProcessId in
// single-process mode.
static uint64_t ChildProcessIdToTracingProcessId(
ChildProcessId child_process_id);
// TODO(crbug.com/379869738): Deprecated, please use
// ChildProcessIdToTracingProcessId above.
static uint64_t ChildProcessUniqueIdToTracingProcessId(int child_process_id);
// ChildProcessHost implementation
bool Send(IPC::Message* message) override;
void ForceShutdown() override;
std::optional<mojo::OutgoingInvitation>& GetMojoInvitation() override;
void CreateChannelMojo() override;
bool IsChannelOpening() override;
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
void AddFilter(IPC::MessageFilter* filter) override;
#endif
void BindReceiver(mojo::GenericPendingReceiver receiver) override;
void SetBatterySaverMode(bool battery_saver_mode_enabled) override;
#if BUILDFLAG(IS_CHROMEOS)
void ReinitializeLogging(uint32_t logging_dest,
base::ScopedFD log_file_descriptor) override;
#endif
base::Process& GetPeerProcess();
mojom::ChildProcess* child_process() { return child_process_.get(); }
#if BUILDFLAG(IS_ANDROID)
// Notifies the child process of memory pressure level.
void NotifyMemoryPressureToChildProcess(
base::MemoryPressureListener::MemoryPressureLevel level);
#endif
private:
friend class content::ChildProcessHost;
ChildProcessHostImpl(ChildProcessHostDelegate* delegate, IpcMode ipc_mode);
// mojom::ChildProcessHost implementation:
void Ping(PingCallback callback) override;
void BindHostReceiver(mojo::GenericPendingReceiver receiver) override;
// IPC::Listener methods:
bool OnMessageReceived(const IPC::Message& msg) override;
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void OnBadMessageReceived(const IPC::Message& message) override;
// Initializes the IPC channel and returns true on success. |channel_| must be
// non-null.
bool InitChannel();
void OnDisconnectedFromChildProcess();
#if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX)
void DumpProfilingData(base::OnceClosure callback) override;
void SetProfilingFile(base::File file) override;
#endif
// The outgoing Mojo invitation which must be consumed to bootstrap Mojo IPC
// to the child process.
std::optional<mojo::OutgoingInvitation> mojo_invitation_{std::in_place};
const IpcMode ipc_mode_;
raw_ptr<ChildProcessHostDelegate> delegate_;
base::Process peer_process_;
bool opening_channel_; // True while we're waiting the channel to be opened.
std::unique_ptr<IPC::Channel> channel_;
mojo::Remote<mojom::ChildProcess> child_process_;
mojo::Receiver<mojom::ChildProcessHost> receiver_{this};
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
// Holds all the IPC message filters. Since this object lives on the IO
// thread, we don't have a IPC::ChannelProxy and so we manage filters
// manually.
std::vector<scoped_refptr<IPC::MessageFilter>> filters_;
#endif
};
} // namespace content
#endif // CONTENT_BROWSER_CHILD_PROCESS_HOST_IMPL_H_
|