UtilityProcessHost.h (5964B)
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/. */ 6 7 #ifndef _include_ipc_glue_UtilityProcessHost_h_ 8 #define _include_ipc_glue_UtilityProcessHost_h_ 9 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" 17 18 #if defined(XP_LINUX) && defined(MOZ_SANDBOX) 19 # include "mozilla/SandboxBroker.h" 20 #endif 21 22 namespace mozilla::ipc { 23 24 class UtilityProcessParent; 25 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. 29 // 30 // UtilityProcessHosts are allocated and managed by UtilityProcessManager. 31 class UtilityProcessHost final : public mozilla::ipc::GeckoChildProcessHost { 32 friend class UtilityProcessParent; 33 34 public: 35 class Listener { 36 protected: 37 virtual ~Listener() = default; 38 39 public: 40 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UtilityProcessHost::Listener); 41 42 // The UtilityProcessHost has unexpectedly shutdown or had its connection 43 // severed. This is not called if an error occurs after calling 44 // Shutdown(). 45 virtual void OnProcessUnexpectedShutdown(UtilityProcessHost* aHost) {} 46 }; 47 48 explicit UtilityProcessHost(SandboxingKind aSandbox, 49 RefPtr<Listener> listener); 50 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. 55 // 56 // @param aExtraOpts (geckoargs::ChildProcessArgs) 57 // Extra options to pass to the subprocess. 58 bool Launch(geckoargs::ChildProcessArgs aExtraOpts); 59 60 using LaunchPromiseType = MozPromise<Ok, LaunchError, false>; 61 // Return a promise that will be resolved once the process has completed its 62 // launch. The promise will be immediately resolved if the launch has already 63 // succeeded. 64 RefPtr<LaunchPromiseType> LaunchPromise(); 65 66 // Inform the process that it should clean up its resources and shut 67 // down. This initiates an asynchronous shutdown sequence. After this 68 // method returns, it is safe for the caller to forget its pointer to 69 // the UtilityProcessHost. 70 // 71 // After this returns, the attached Listener is no longer used. 72 void Shutdown(); 73 74 // Return the actor for the top-level actor of the process. If the process 75 // has not connected yet, this returns null. 76 RefPtr<UtilityProcessParent> GetActor() const { 77 MOZ_ASSERT(NS_IsMainThread()); 78 return mUtilityProcessParent; 79 } 80 81 bool IsConnected() const { 82 MOZ_ASSERT(NS_IsMainThread()); 83 return bool(mUtilityProcessParent); 84 } 85 86 // Called on the IO thread. 87 void OnChannelConnected(base::ProcessId peer_pid) override; 88 89 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) 90 // Return the sandbox type to be used with this process type. 91 static MacSandboxType GetMacSandboxType(); 92 #endif 93 94 private: 95 ~UtilityProcessHost(); 96 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); 100 101 // Called on the main thread when the mUtilityProcessParent actor is shutting 102 // down. 103 void OnChannelClosed(IProtocol::ActorDestroyReason aReason); 104 105 // Kill the remote process, triggering IPC shutdown. 106 void KillHard(const char* aReason); 107 108 void DestroyProcess(); 109 110 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) 111 static bool sLaunchWithMacSandbox; 112 113 // Sandbox the Utility process at launch for all instances 114 bool IsMacSandboxLaunchEnabled() override { return sLaunchWithMacSandbox; } 115 116 // Override so we can turn on Utility process-specific sandbox logging 117 bool FillMacSandboxInfo(MacSandboxInfo& aInfo) override; 118 #endif 119 120 DISALLOW_COPY_AND_ASSIGN(UtilityProcessHost); 121 122 RefPtr<Listener> mListener; 123 124 // All members below are only ever accessed on the main thread. 125 enum class LaunchPhase { Unlaunched, Waiting, Complete }; 126 LaunchPhase mLaunchPhase = LaunchPhase::Unlaunched; 127 128 RefPtr<UtilityProcessParent> mUtilityProcessParent; 129 130 UniquePtr<ipc::SharedPreferenceSerializer> mPrefSerializer{}; 131 132 bool mShutdownRequested = false; 133 134 void ResolvePromise(); 135 void RejectPromise(LaunchError); 136 137 #if defined(MOZ_WMF_CDM) && defined(MOZ_SANDBOX) && !defined(MOZ_ASAN) 138 void EnsureWidevineL1PathForSandbox(geckoargs::ChildProcessArgs& aExtraOpts); 139 #endif 140 141 #if defined(MOZ_WMF_CDM) && defined(MOZ_SANDBOX) 142 void EnanbleMFCDMTelemetryEventIfNeeded() const; 143 #endif 144 145 // Set to true on construction and to false just prior deletion. 146 // The UtilityProcessHost isn't refcounted; so we can capture this by value in 147 // lambdas along with a strong reference to mLiveToken and check if that value 148 // is true before accessing "this". 149 // While a reference to mLiveToken can be taken on any thread; its value can 150 // only be read or written on the main thread. 151 const RefPtr<media::Refcountable<bool>> mLiveToken; 152 153 RefPtr<LaunchPromiseType::Private> mLaunchPromise{}; 154 bool mLaunchPromiseSettled = false; 155 bool mLaunchPromiseLaunched = false; 156 // Will be set to true if the Utility process as successfully started. 157 bool mLaunchCompleted = false; 158 159 #if defined(XP_LINUX) && defined(MOZ_SANDBOX) 160 RefPtr<SandboxBroker> mSandboxBroker{}; 161 #endif 162 }; 163 164 } // namespace mozilla::ipc 165 166 #endif // _include_ipc_glue_UtilityProcessHost_h_