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
;
88 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
89 // Return the sandbox type to be used with this process type.
90 static MacSandboxType
GetMacSandboxType();
94 ~UtilityProcessHost();
96 // Called on the main thread with true after a connection has been established
97 // or false if it failed (including if it failed before the timeout kicked in)
98 void InitAfterConnect(bool aSucceeded
);
100 // Called on the main thread when the mUtilityProcessParent actor is shutting
102 void OnChannelClosed();
104 // Kill the remote process, triggering IPC shutdown.
105 void KillHard(const char* aReason
);
107 void DestroyProcess();
109 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
110 static bool sLaunchWithMacSandbox
;
112 // Sandbox the Utility process at launch for all instances
113 bool IsMacSandboxLaunchEnabled() override
{ return sLaunchWithMacSandbox
; }
115 // Override so we can turn on Utility process-specific sandbox logging
116 bool FillMacSandboxInfo(MacSandboxInfo
& aInfo
) override
;
119 DISALLOW_COPY_AND_ASSIGN(UtilityProcessHost
);
121 RefPtr
<Listener
> mListener
;
123 // All members below are only ever accessed on the main thread.
124 enum class LaunchPhase
{ Unlaunched
, Waiting
, Complete
};
125 LaunchPhase mLaunchPhase
= LaunchPhase::Unlaunched
;
127 RefPtr
<UtilityProcessParent
> mUtilityProcessParent
;
129 UniquePtr
<ipc::SharedPreferenceSerializer
> mPrefSerializer
{};
131 bool mShutdownRequested
= false;
133 void RejectPromise();
134 void ResolvePromise();
136 #if defined(MOZ_WMF_CDM) && defined(MOZ_SANDBOX) && !defined(MOZ_ASAN)
137 void EnsureWidevineL1PathForSandbox(StringVector
& aExtraOpts
);
140 // Set to true on construction and to false just prior deletion.
141 // The UtilityProcessHost isn't refcounted; so we can capture this by value in
142 // lambdas along with a strong reference to mLiveToken and check if that value
143 // is true before accessing "this".
144 // While a reference to mLiveToken can be taken on any thread; its value can
145 // only be read or written on the main thread.
146 const RefPtr
<media::Refcountable
<bool>> mLiveToken
;
148 RefPtr
<GenericNonExclusivePromise::Private
> mLaunchPromise
{};
149 bool mLaunchPromiseSettled
= false;
150 bool mLaunchPromiseLaunched
= false;
151 // Will be set to true if the Utility process as successfully started.
152 bool mLaunchCompleted
= false;
154 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
155 UniquePtr
<SandboxBroker
> mSandboxBroker
{};
159 } // namespace mozilla::ipc
161 #endif // _include_ipc_glue_UtilityProcessHost_h_