UtilityMediaServiceParent.cpp (7085B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 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 #include "UtilityMediaServiceParent.h" 8 9 #include "GeckoProfiler.h" 10 #include "nsDebugImpl.h" 11 12 #include "MediaCodecsSupport.h" 13 #include "mozilla/RemoteMediaManagerParent.h" 14 15 #include "mozilla/gfx/gfxVars.h" 16 17 #if defined(XP_WIN) && defined(MOZ_SANDBOX) 18 # include "WMF.h" 19 # include "WMFDecoderModule.h" 20 # include "WMFUtils.h" 21 22 # include "mozilla/sandboxTarget.h" 23 # include "mozilla/ipc/UtilityProcessImpl.h" 24 #endif // defined(XP_WIN) && defined(MOZ_SANDBOX) 25 26 #ifdef MOZ_WIDGET_ANDROID 27 # include "mozilla/StaticPrefs_media.h" 28 # include "AndroidDecoderModule.h" 29 #endif 30 31 #include "mozilla/ipc/UtilityProcessChild.h" 32 #include "mozilla/RemoteDecodeUtils.h" 33 34 #ifdef MOZ_WMF_MEDIA_ENGINE 35 # include "gfxConfig.h" 36 # include "mozilla/gfx/DeviceManagerDx.h" 37 #endif 38 39 #ifdef MOZ_WMF_CDM 40 # include "mozilla/MFCDMParent.h" 41 # include "mozilla/PMFCDM.h" 42 #endif 43 44 namespace mozilla::ipc { 45 46 UtilityMediaServiceParent::UtilityMediaServiceParent( 47 nsTArray<gfx::GfxVarUpdate>&& aUpdates) 48 : mKind(GetCurrentSandboxingKind()), 49 mUtilityMediaServiceParentStart(TimeStamp::Now()) { 50 switch (mKind) { 51 #ifdef MOZ_WMF_MEDIA_ENGINE 52 case SandboxingKind::MF_MEDIA_ENGINE_CDM: 53 nsDebugImpl::SetMultiprocessMode("MF Media Engine CDM"); 54 profiler_set_process_name(nsCString("MF Media Engine CDM")); 55 break; 56 #endif 57 case SandboxingKind::GENERIC_UTILITY: 58 break; 59 default: 60 nsDebugImpl::SetMultiprocessMode("Utility AudioDecoder"); 61 profiler_set_process_name(nsCString("Utility AudioDecoder")); 62 break; 63 } 64 gfx::gfxVars::Initialize(); 65 gfx::gfxVars::ApplyUpdate(aUpdates); 66 #ifdef MOZ_WMF_MEDIA_ENGINE 67 if (mKind == SandboxingKind::MF_MEDIA_ENGINE_CDM) { 68 gfx::gfxConfig::Init(); 69 gfx::DeviceManagerDx::Init(); 70 } 71 #endif 72 } 73 74 UtilityMediaServiceParent::~UtilityMediaServiceParent() { 75 gfx::gfxVars::Shutdown(); 76 #ifdef MOZ_WMF_MEDIA_ENGINE 77 if (mKind == SandboxingKind::MF_MEDIA_ENGINE_CDM) { 78 gfx::gfxConfig::Shutdown(); 79 gfx::DeviceManagerDx::Shutdown(); 80 } 81 #endif 82 #ifdef MOZ_WMF_CDM 83 if (mKind == SandboxingKind::MF_MEDIA_ENGINE_CDM) { 84 MFCDMParent::Shutdown(); 85 } 86 #endif 87 } 88 89 /* static */ 90 void UtilityMediaServiceParent::GenericPreloadForSandbox() { 91 #if defined(MOZ_SANDBOX) && defined(XP_WIN) 92 // Preload AV dlls so we can enable Binary Signature Policy 93 // to restrict further dll loads. 94 UtilityProcessImpl::LoadLibraryOrCrash(L"mozavcodec.dll"); 95 UtilityProcessImpl::LoadLibraryOrCrash(L"mozavutil.dll"); 96 #endif // defined(MOZ_SANDBOX) && defined(XP_WIN) 97 } 98 99 /* static */ 100 void UtilityMediaServiceParent::WMFPreloadForSandbox() { 101 #if defined(MOZ_SANDBOX) && defined(XP_WIN) 102 // mfplat.dll and mf.dll will be preloaded by 103 // wmf::MediaFoundationInitializer::HasInitialized() 104 105 # if defined(NS_FREE_PERMANENT_DATA) 106 // WMF Shutdown requires this or it will badly crash 107 UtilityProcessImpl::LoadLibraryOrCrash(L"ole32.dll"); 108 # endif // defined(NS_FREE_PERMANENT_DATA) 109 110 auto rv = wmf::MediaFoundationInitializer::HasInitialized(); 111 if (!rv) { 112 NS_WARNING("Failed to init Media Foundation in the Utility process"); 113 return; 114 } 115 #endif // defined(MOZ_SANDBOX) && defined(XP_WIN) 116 } 117 118 void UtilityMediaServiceParent::Start( 119 Endpoint<PUtilityMediaServiceParent>&& aEndpoint) { 120 MOZ_ASSERT(NS_IsMainThread()); 121 122 DebugOnly<bool> ok = std::move(aEndpoint).Bind(this); 123 MOZ_ASSERT(ok); 124 125 #ifdef MOZ_WIDGET_ANDROID 126 if (StaticPrefs::media_utility_android_media_codec_enabled()) { 127 AndroidDecoderModule::SetSupportedMimeTypes(); 128 } 129 #endif 130 131 auto supported = media::MCSInfo::GetSupportFromFactory(); 132 (void)SendUpdateMediaCodecsSupported(GetRemoteMediaInFromKind(mKind), 133 supported); 134 PROFILER_MARKER_UNTYPED("UtilityMediaServiceParent::Start", IPC, 135 MarkerOptions(MarkerTiming::IntervalUntilNowFrom( 136 mUtilityMediaServiceParentStart))); 137 } 138 139 mozilla::ipc::IPCResult 140 UtilityMediaServiceParent::RecvNewContentRemoteMediaManager( 141 Endpoint<PRemoteMediaManagerParent>&& aEndpoint, 142 const ContentParentId& aParentId) { 143 MOZ_ASSERT(NS_IsMainThread()); 144 if (!RemoteMediaManagerParent::CreateForContent(std::move(aEndpoint), 145 aParentId)) { 146 return IPC_FAIL_NO_REASON(this); 147 } 148 return IPC_OK(); 149 } 150 151 #ifdef MOZ_WMF_MEDIA_ENGINE 152 mozilla::ipc::IPCResult UtilityMediaServiceParent::RecvInitVideoBridge( 153 Endpoint<PVideoBridgeChild>&& aEndpoint, 154 const ContentDeviceData& aContentDeviceData) { 155 MOZ_ASSERT(mKind == SandboxingKind::MF_MEDIA_ENGINE_CDM); 156 if (!RemoteMediaManagerParent::CreateVideoBridgeToOtherProcess( 157 std::move(aEndpoint))) { 158 return IPC_FAIL_NO_REASON(this); 159 } 160 161 gfx::gfxConfig::Inherit( 162 { 163 gfx::Feature::HW_COMPOSITING, 164 gfx::Feature::D3D11_COMPOSITING, 165 gfx::Feature::OPENGL_COMPOSITING, 166 }, 167 aContentDeviceData.prefs()); 168 169 if (gfx::gfxConfig::IsEnabled(gfx::Feature::D3D11_COMPOSITING)) { 170 if (auto* devmgr = gfx::DeviceManagerDx::Get()) { 171 devmgr->ImportDeviceInfo(aContentDeviceData.d3d11()); 172 } 173 } 174 175 (void)SendCompleteCreatedVideoBridge(); 176 return IPC_OK(); 177 } 178 #endif 179 180 IPCResult UtilityMediaServiceParent::RecvUpdateVar( 181 const nsTArray<GfxVarUpdate>& aUpdate) { 182 gfx::gfxVars::ApplyUpdate(aUpdate); 183 184 MOZ_ALWAYS_SUCCEEDS(NS_DispatchBackgroundTask( 185 NS_NewRunnableFunction( 186 "UtilityMediaServiceParent::RecvUpdateVar", 187 [self = RefPtr{this}]() { 188 NS_DispatchToMainThread(NS_NewRunnableFunction( 189 "UtilityMediaServiceParent::UpdateMediaCodecsSupported", 190 [self, supported = media::MCSInfo::GetSupportFromFactory( 191 true /* force refresh */)]() { 192 (void)self->SendUpdateMediaCodecsSupported( 193 GetRemoteMediaInFromKind(self->mKind), supported); 194 })); 195 }), 196 nsIEventTarget::DISPATCH_NORMAL)); 197 return IPC_OK(); 198 } 199 200 #ifdef MOZ_WMF_CDM 201 IPCResult UtilityMediaServiceParent::RecvGetKeySystemCapabilities( 202 GetKeySystemCapabilitiesResolver&& aResolver) { 203 MOZ_ASSERT(mKind == SandboxingKind::MF_MEDIA_ENGINE_CDM); 204 MFCDMParent::GetAllKeySystemsCapabilities()->Then( 205 GetCurrentSerialEventTarget(), __func__, 206 [aResolver](CopyableTArray<MFCDMCapabilitiesIPDL>&& aCapabilities) { 207 aResolver(std::move(aCapabilities)); 208 }, 209 [aResolver](nsresult) { 210 aResolver(CopyableTArray<MFCDMCapabilitiesIPDL>()); 211 }); 212 return IPC_OK(); 213 } 214 215 IPCResult UtilityMediaServiceParent::RecvUpdateWidevineL1Path( 216 const nsString& aPath) { 217 MFCDMParent::SetWidevineL1Path(NS_ConvertUTF16toUTF8(aPath).get()); 218 return IPC_OK(); 219 } 220 #endif 221 222 } // namespace mozilla::ipc