MFCDMParent.h (6587B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef DOM_MEDIA_IPC_MFCDMPARENT_H_ 6 #define DOM_MEDIA_IPC_MFCDMPARENT_H_ 7 8 #include <wrl.h> 9 10 #include "MFCDMExtra.h" 11 #include "MFCDMSession.h" 12 #include "MFPMPHostWrapper.h" 13 #include "RemoteMediaManagerParent.h" 14 #include "mozilla/Assertions.h" 15 #include "mozilla/EventTargetAndLockCapability.h" 16 #include "mozilla/PMFCDMParent.h" 17 #include "mozilla/RefPtr.h" 18 19 namespace mozilla { 20 21 class MFCDMProxy; 22 23 /** 24 * MFCDMParent is a wrapper class for the Media Foundation CDM in the utility 25 * process. 26 * It's responsible to create and manage a CDM and its sessions, and acts as a 27 * proxy to the Media Foundation interfaces 28 * (https://learn.microsoft.com/en-us/windows/win32/api/mfcontentdecryptionmodule/) 29 * by accepting calls from and calling back to MFCDMChild in the content 30 * process. 31 */ 32 class MFCDMParent final : public PMFCDMParent { 33 public: 34 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MFCDMParent); 35 36 MFCDMParent(const nsAString& aKeySystem, RemoteMediaManagerParent* aManager, 37 nsISerialEventTarget* aManagerThread); 38 39 static void SetWidevineL1Path(const char* aPath); 40 41 // Perform clean-up when shutting down the MFCDM process. 42 static void Shutdown(); 43 44 // Return capabilities from all key systems which the media foundation CDM 45 // supports. 46 using CapabilitiesPromise = 47 MozPromise<CopyableTArray<MFCDMCapabilitiesIPDL>, nsresult, true>; 48 static RefPtr<CapabilitiesPromise> GetAllKeySystemsCapabilities(); 49 50 static MFCDMParent* GetCDMById(uint64_t aId) { 51 MOZ_ASSERT(sRegisteredCDMs.Contains(aId)); 52 return sRegisteredCDMs.Get(aId); 53 } 54 uint64_t Id() const { return mId; } 55 56 mozilla::ipc::IPCResult RecvGetCapabilities( 57 const MFCDMCapabilitiesRequest& aRequest, 58 GetCapabilitiesResolver&& aResolver); 59 60 mozilla::ipc::IPCResult RecvInit(const MFCDMInitParamsIPDL& aParams, 61 InitResolver&& aResolver); 62 63 mozilla::ipc::IPCResult RecvCreateSessionAndGenerateRequest( 64 const MFCDMCreateSessionParamsIPDL& aParams, 65 CreateSessionAndGenerateRequestResolver&& aResolver); 66 67 mozilla::ipc::IPCResult RecvLoadSession( 68 const KeySystemConfig::SessionType& aSessionType, 69 const nsString& aSessionId, LoadSessionResolver&& aResolver); 70 71 mozilla::ipc::IPCResult RecvUpdateSession( 72 const nsString& aSessionId, const CopyableTArray<uint8_t>& aResponse, 73 UpdateSessionResolver&& aResolver); 74 75 mozilla::ipc::IPCResult RecvCloseSession(const nsString& aSessionId, 76 UpdateSessionResolver&& aResolver); 77 78 mozilla::ipc::IPCResult RecvRemoveSession(const nsString& aSessionId, 79 UpdateSessionResolver&& aResolver); 80 81 mozilla::ipc::IPCResult RecvSetServerCertificate( 82 const CopyableTArray<uint8_t>& aCertificate, 83 UpdateSessionResolver&& aResolver); 84 85 mozilla::ipc::IPCResult RecvGetStatusForPolicy( 86 const dom::HDCPVersion& aMinHdcpVersion, 87 GetStatusForPolicyResolver&& aResolver); 88 89 // A thread-safe method to access the CDM proxy. Returns nullptr if the CDM 90 // has been shut down. 91 MFCDMProxy* GetMFCDMProxy(); 92 93 void ShutdownCDM(); 94 95 void Destroy(); 96 97 private: 98 ~MFCDMParent(); 99 100 enum class CapabilitesFlag { 101 HarewareDecryption, 102 NeedClearLeadCheck, 103 IsPrivateBrowsing, 104 }; 105 using CapabilitesFlagSet = EnumSet<CapabilitesFlag, uint8_t>; 106 107 static LPCWSTR GetCDMLibraryName(const nsString& aKeySystem); 108 109 static HRESULT GetOrCreateFactory( 110 const nsString& aKeySystem, 111 Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& aFactoryOut); 112 113 static HRESULT LoadFactory( 114 const nsString& aKeySystem, 115 Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& aFactoryOut); 116 117 static void GetCapabilities(const nsString& aKeySystem, 118 const CapabilitesFlagSet& aFlags, 119 IMFContentDecryptionModuleFactory* aFactory, 120 MFCDMCapabilitiesIPDL& aCapabilitiesOut); 121 122 void Register(); 123 void Unregister(); 124 125 void ConnectSessionEvents(MFCDMSession* aSession); 126 127 MFCDMSession* GetSession(const nsString& aSessionId); 128 129 mozilla::Mutex& Mutex() MOZ_RETURN_CAPABILITY(mCDMAccessLock.Lock()) { 130 return mCDMAccessLock.Lock(); 131 } 132 133 nsString mKeySystem; 134 135 const RefPtr<RemoteMediaManagerParent> mManager; 136 const RefPtr<nsISerialEventTarget> mManagerThread; 137 138 MOZ_RUNINIT static inline nsTHashMap<nsUint64HashKey, MFCDMParent*> 139 sRegisteredCDMs; 140 141 static inline uint64_t sNextId = 1; 142 const uint64_t mId; 143 bool mIsInited = false; 144 145 static inline BSTR sWidevineL1Path; 146 147 RefPtr<MFCDMParent> mIPDLSelfRef; 148 Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory> mFactory; 149 Microsoft::WRL::ComPtr<MFPMPHostWrapper> mPMPHostWrapper; 150 151 std::map<nsString, UniquePtr<MFCDMSession>> mSessions; 152 153 MediaEventForwarder<MFCDMKeyMessage> mKeyMessageEvents; 154 MediaEventForwarder<MFCDMKeyStatusChange> mKeyChangeEvents; 155 MediaEventForwarder<MFCDMKeyExpiration> mExpirationEvents; 156 MediaEventForwarder<MFCDMSessionClosedResult> mClosedEvents; 157 158 MediaEventListener mKeyMessageListener; 159 MediaEventListener mKeyChangeListener; 160 MediaEventListener mExpirationListener; 161 MediaEventListener mClosedListener; 162 163 // The mCDM and mCDMProxy members are exclusively modified on the manager 164 // thread, while being read-only on other threads. To ensure thread-safe 165 // access, we employ the EventTargetAndLockCapability mechanism. 166 mozilla::EventTargetAndLockCapability<nsISerialEventTarget, mozilla::Mutex> 167 mCDMAccessLock; 168 Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mCDM 169 MOZ_GUARDED_BY(mCDMAccessLock); 170 RefPtr<MFCDMProxy> mCDMProxy MOZ_GUARDED_BY(mCDMAccessLock); 171 }; 172 173 // A helper class only used in the chrome process to handle CDM related tasks. 174 class MFCDMService { 175 public: 176 // This is used to display CDM capabilites in `about:support`. 177 static void GetAllKeySystemsCapabilities(dom::Promise* aPromise); 178 179 // If Widevine L1 is downloaded after the MFCDM process is created, then we 180 // use this method to update the L1 path and setup L1 permission for the MFCDM 181 // process. 182 static void UpdateWidevineL1Path(nsIFile* aFile); 183 184 private: 185 static RefPtr<GenericNonExclusivePromise> LaunchMFCDMProcessIfNeeded( 186 ipc::SandboxingKind aSandbox); 187 }; 188 189 } // namespace mozilla 190 191 #endif // DOM_MEDIA_IPC_MFCDMPARENT_H_