#ifndef CONTENT_CHILD_CHILD_THREAD_IMPL_H_
#define CONTENT_CHILD_CHILD_THREAD_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include "base/auto_reset.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "components/variations/child_process_field_trial_syncer.h"
#include "content/child/child_process_synthetic_trial_syncer.h"
#include "content/common/associated_interfaces.mojom.h"
#include "content/common/child_process.mojom.h"
#include "content/public/child/child_thread.h"
#include "ipc/ipc.mojom.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
#include "mojo/public/cpp/bindings/shared_remote.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/tracing/public/mojom/background_tracing_agent.mojom.h"
#include "third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom.h"
#if BUILDFLAG(IS_WIN)
#include "content/public/common/font_cache_win.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
#endif
namespace IPC {
class SyncChannel;
class UrgentMessageObserver;
}
namespace mojo {
class OutgoingInvitation;
class BinderMap;
namespace core {
class ScopedIPCSupport;
}
}
namespace tracing {
class BackgroundTracingAgentProviderImpl;
}
namespace content {
class ChildPerformanceCoordinator;
class InProcessChildThreadParams;
class ChildThreadImpl : public IPC::Listener, virtual public ChildThread {
public:
struct Options;
explicit ChildThreadImpl(base::RepeatingClosure quit_closure);
ChildThreadImpl(base::RepeatingClosure quit_closure, const Options& options);
ChildThreadImpl(const ChildThreadImpl&) = delete;
ChildThreadImpl& operator=(const ChildThreadImpl&) = delete;
~ChildThreadImpl() override;
virtual void Shutdown();
virtual bool ShouldBeDestroyed();
#if BUILDFLAG(IS_WIN)
void PreCacheFont(const LOGFONT& log_font) override;
void ReleaseCachedFonts() override;
#endif
void RecordAction(const base::UserMetricsAction& action) override;
void RecordComputedAction(const std::string& action) override;
void BindHostReceiver(mojo::GenericPendingReceiver receiver) override;
scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() override;
void SetFieldTrialGroup(const std::string& trial_name,
const std::string& group_name) override;
IPC::SyncChannel* channel() { return channel_.get(); }
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner() const {
return main_thread_runner_;
}
static ChildThreadImpl* current();
void GetBackgroundTracingAgentProvider(
mojo::PendingReceiver<tracing::mojom::BackgroundTracingAgentProvider>
receiver);
const mojo::SharedRemote<mojom::ChildProcessHost>& child_process_host()
const {
return child_process_host_;
}
void DisconnectChildProcessHost();
#if BUILDFLAG(ARKWEB_PERFORMANCE_SCHEDULING)
void ReportKeyThread(int32_t status, int32_t process_id, int32_t thread_id, int32_t roleAdapter);
#endif
#if BUILDFLAG(ARKWEB_DFX_TRACING)
void ReportHisyevent(int64_t block_time, const std::string& mode);
#endif
virtual void BindServiceInterface(mojo::GenericPendingReceiver receiver);
virtual void OnBindReceiver(mojo::GenericPendingReceiver receiver);
protected:
friend class ChildProcess;
virtual void OnProcessFinalRelease();
virtual void SetBatterySaverMode(bool battery_saver_mode_enabled);
void ExposeInterfacesToBrowser(mojo::BinderMap binders);
void OnAssociatedInterfaceRequest(
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle handle) override;
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
bool on_channel_error_called() const { return on_channel_error_called_; }
bool IsInBrowserProcess() const;
#if BUILDFLAG(IS_ANDROID)
virtual void OnMemoryPressureFromBrowserReceived(
base::MemoryPressureLevel level);
#endif
#if BUILDFLAG(ARKWEB_RENDERER_ANR_DUMP)
void SetWebkitInited();
#endif
private:
class IOThreadState;
void Init(const Options& options);
void EnsureConnected(int connection_timeout);
#if BUILDFLAG(IS_WIN)
const mojo::Remote<mojom::FontCacheWin>& GetFontCacheWin();
#endif
const base::AutoReset<ChildThreadImpl*> resetter_;
base::Thread mojo_ipc_thread_{"Mojo IPC"};
std::unique_ptr<mojo::core::ScopedIPCSupport> mojo_ipc_support_;
#if BUILDFLAG(IS_WIN)
mutable mojo::Remote<mojom::FontCacheWin> font_cache_win_;
#endif
std::unique_ptr<IPC::SyncChannel> channel_;
bool on_channel_error_called_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner_;
base::RepeatingClosure quit_closure_;
std::unique_ptr<tracing::BackgroundTracingAgentProviderImpl>
background_tracing_agent_provider_;
scoped_refptr<base::SingleThreadTaskRunner> browser_process_io_runner_;
raw_ptr<variations::ChildProcessFieldTrialSyncer> field_trial_syncer_ =
nullptr;
std::unique_ptr<base::WeakPtrFactory<ChildThreadImpl>>
channel_connected_factory_;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
mojo::SharedRemote<mojom::ChildProcessHost> child_process_host_;
scoped_refptr<IOThreadState> io_thread_state_;
#if BUILDFLAG(ARKWEB_RENDERER_ANR_DUMP)
bool webkit_inited_ = false;
#endif
std::unique_ptr<ChildPerformanceCoordinator> performance_coordinator_;
base::WeakPtrFactory<ChildThreadImpl> weak_factory_{this};
};
struct ChildThreadImpl::Options {
Options(const Options& other);
~Options();
class Builder;
bool with_legacy_ipc_channel = true;
bool connect_to_browser = false;
scoped_refptr<base::SingleThreadTaskRunner> browser_process_io_runner;
raw_ptr<mojo::OutgoingInvitation> mojo_invitation = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner;
raw_ptr<IPC::UrgentMessageObserver> urgent_message_observer = nullptr;
bool exposes_interfaces_to_browser = false;
using ServiceBinder =
base::RepeatingCallback<void(mojo::GenericPendingReceiver*)>;
ServiceBinder service_binder;
private:
Options();
};
class ChildThreadImpl::Options::Builder {
public:
Builder();
Builder(const Builder&) = delete;
Builder& operator=(const Builder&) = delete;
Builder& InBrowserProcess(const InProcessChildThreadParams& params);
Builder& ConnectToBrowser(bool connect_to_browser);
Builder& WithLegacyIPCChannel(bool with_legacy_ipc_channel);
Builder& IPCTaskRunner(
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner);
Builder& ServiceBinder(ServiceBinder binder);
Builder& ExposesInterfacesToBrowser();
Builder& SetUrgentMessageObserver(IPC::UrgentMessageObserver* observer);
Options Build();
private:
struct Options options_;
};
}
#endif