1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef _include_ipc_glue_UtilityProcessHost_h_
8 #define _include_ipc_glue_UtilityProcessHost_h_
10 #include "mozilla/UniquePtr.h"
11 #include "mozilla/ipc/UtilityProcessParent.h"
12 #include "mozilla/ipc/UtilityProcessSandboxing.h"
13 #include "mozilla/ipc/GeckoChildProcessHost.h"
14 #include "mozilla/ipc/ProtocolUtils.h"
15 #include "mozilla/media/MediaUtils.h"
16 #include "mozilla/ipc/ProcessUtils.h"
18 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
19 # include "mozilla/SandboxBroker.h"
22 namespace mozilla::ipc
{
24 class UtilityProcessParent
;
26 // UtilityProcessHost is the "parent process" container for a subprocess handle
27 // and IPC connection. It owns the parent process IPDL actor, which in this
28 // case, is a UtilityChild.
30 // UtilityProcessHosts are allocated and managed by UtilityProcessManager.
31 class UtilityProcessHost final
: public mozilla::ipc::GeckoChildProcessHost
{
32 friend class UtilityProcessParent
;
37 virtual ~Listener() = default;
40 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UtilityProcessHost::Listener
);
42 // The UtilityProcessHost has unexpectedly shutdown or had its connection
43 // severed. This is not called if an error occurs after calling
45 virtual void OnProcessUnexpectedShutdown(UtilityProcessHost
* aHost
) {}
48 explicit UtilityProcessHost(SandboxingKind aSandbox
,
49 RefPtr
<Listener
> listener
);
51 // Launch the subprocess asynchronously. On failure, false is returned.
52 // Otherwise, true is returned. If succeeded, a follow-up call should be made
53 // to LaunchPromise() which will return a promise that will be resolved once
54 // the Utility process has launched and a channel has been established.
56 // @param aExtraOpts (StringVector)
57 // Extra options to pass to the subprocess.
58 bool Launch(StringVector aExtraOpts
);
60 // Return a promise that will be resolved once the process has completed its
61 // launch. The promise will be immediately resolved if the launch has already
63 RefPtr
<GenericNonExclusivePromise
> LaunchPromise();
65 // Inform the process that it should clean up its resources and shut
66 // down. This initiates an asynchronous shutdown sequence. After this
67 // method returns, it is safe for the caller to forget its pointer to
68 // the UtilityProcessHost.
70 // After this returns, the attached Listener is no longer used.
73 // Return the actor for the top-level actor of the process. If the process
74 // has not connected yet, this returns null.
75 RefPtr
<UtilityProcessParent
> GetActor() const {
76 MOZ_ASSERT(NS_IsMainThread());
77 return mUtilityProcessParent
;
80 bool IsConnected() const {
81 MOZ_ASSERT(NS_IsMainThread());
82 return bool(mUtilityProcessParent
);
85 // Called on the IO thread.
86 void OnChannelConnected(base::ProcessId peer_pid
) override
;
87 void OnChannelError() override
;
89 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
90 // Return the sandbox type to be used with this process type.
91 static MacSandboxType
GetMacSandboxType();
95 ~UtilityProcessHost();
97 // Called on the main thread with true after a connection has been established
98 // or false if it failed (including if it failed before the timeout kicked in)
99 void InitAfterConnect(bool aSucceeded
);
101 // Called on the main thread when the mUtilityProcessParent actor is shutting
103 void OnChannelClosed();
105 // Kill the remote process, triggering IPC shutdown.
106 void KillHard(const char* aReason
);
108 void DestroyProcess();
110 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
111 static bool sLaunchWithMacSandbox
;
113 // Sandbox the Utility process at launch for all instances
114 bool IsMacSandboxLaunchEnabled() override
{ return sLaunchWithMacSandbox
; }
116 // Override so we can turn on Utility process-specific sandbox logging
117 bool FillMacSandboxInfo(MacSandboxInfo
& aInfo
) override
;
120 DISALLOW_COPY_AND_ASSIGN(UtilityProcessHost
);
122 RefPtr
<Listener
> mListener
;
124 // All members below are only ever accessed on the main thread.
125 enum class LaunchPhase
{ Unlaunched
, Waiting
, Complete
};
126 LaunchPhase mLaunchPhase
= LaunchPhase::Unlaunched
;
128 RefPtr
<UtilityProcessParent
> mUtilityProcessParent
;
130 UniquePtr
<ipc::SharedPreferenceSerializer
> mPrefSerializer
{};
132 bool mShutdownRequested
= false;
134 void RejectPromise();
135 void ResolvePromise();
137 // Set to true on construction and to false just prior deletion.
138 // The UtilityProcessHost isn't refcounted; so we can capture this by value in
139 // lambdas along with a strong reference to mLiveToken and check if that value
140 // is true before accessing "this".
141 // While a reference to mLiveToken can be taken on any thread; its value can
142 // only be read or written on the main thread.
143 const RefPtr
<media::Refcountable
<bool>> mLiveToken
;
145 RefPtr
<GenericNonExclusivePromise::Private
> mLaunchPromise
{};
146 bool mLaunchPromiseSettled
= false;
147 bool mLaunchPromiseLaunched
= false;
148 // Will be set to true if the Utility process as successfully started.
149 bool mLaunchCompleted
= false;
151 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
152 UniquePtr
<SandboxBroker
> mSandboxBroker
{};
156 } // namespace mozilla::ipc
158 #endif // _include_ipc_glue_UtilityProcessHost_h_