Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / media / wmf-clearkey / WMFClearKeyCDM.h
blob765cac36f0a27ea190fc67a2c487662bd6b49e7e
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/. */
5 #ifndef DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDM_H
6 #define DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDM_H
8 #include <mfidl.h>
9 #include <unordered_map>
10 #include <variant>
11 #include <windows.h>
12 #include <windows.media.protection.h>
13 #include <wrl.h>
14 #include <wrl/client.h>
16 #include "ClearKeySessionManager.h"
17 #include "MFCDMExtra.h"
18 #include "WMFClearKeyUtils.h"
19 #include "content_decryption_module.h"
21 namespace mozilla {
23 class SessionManagerWrapper;
24 class WMFClearKeySession;
26 // This our customized MFCDM for supporting clearkey in our testing. It would
27 // use ClearKeySessionManager via SessionManagerWrapper to perform decryption.
28 class WMFClearKeyCDM final
29 : public Microsoft::WRL::RuntimeClass<
30 Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
31 IMFContentDecryptionModule, IMFGetService, IMFShutdown,
32 Microsoft::WRL::FtmBase> {
33 public:
34 WMFClearKeyCDM() = default;
35 ~WMFClearKeyCDM();
36 WMFClearKeyCDM(const WMFClearKeyCDM&) = delete;
37 WMFClearKeyCDM& operator=(const WMFClearKeyCDM&) = delete;
39 HRESULT RuntimeClassInitialize(IPropertyStore* aProperties);
41 // IMFContentDecryptionModule
42 STDMETHODIMP SetContentEnabler(IMFContentEnabler* aContentEnabler,
43 IMFAsyncResult* aResult) override;
44 STDMETHODIMP GetSuspendNotify(IMFCdmSuspendNotify** aNotify) override;
45 STDMETHODIMP SetPMPHostApp(IMFPMPHostApp* aPmpHostApp) override;
46 STDMETHODIMP CreateSession(
47 MF_MEDIAKEYSESSION_TYPE aSessionType,
48 IMFContentDecryptionModuleSessionCallbacks* aCallbacks,
49 IMFContentDecryptionModuleSession** aSession) override;
50 STDMETHODIMP SetServerCertificate(const BYTE* aCertificate,
51 DWORD aCertificateSize) override;
52 STDMETHODIMP CreateTrustedInput(const BYTE* aContentInitData,
53 DWORD aContentInitDataSize,
54 IMFTrustedInput** aTrustedInput) override;
55 STDMETHODIMP GetProtectionSystemIds(GUID** aSystemIds,
56 DWORD* aCount) override;
57 // IMFGetService
58 STDMETHODIMP GetService(REFGUID aGuidService, REFIID aRiid,
59 LPVOID* aPpvObject) override;
61 // IMFShutdown
62 STDMETHODIMP Shutdown() override;
63 STDMETHODIMP GetShutdownStatus(MFSHUTDOWN_STATUS* aStatus) override;
65 private:
66 RefPtr<SessionManagerWrapper> mSessionManager;
67 Microsoft::WRL::ComPtr<
68 ABI::Windows::Media::Protection::IMediaProtectionPMPServer>
69 mPMPServer;
72 // In order to reuse existing Gecko clearkey implementation, we need to
73 // inherit the class `cdm::Host_10`.
74 // TODO : add a way to assert thread usage. It would be used on MF thread pool
75 // and the media supervisor thread pool.
76 class SessionManagerWrapper final : public RefCounted, private cdm::Host_10 {
77 public:
78 explicit SessionManagerWrapper(WMFClearKeyCDM* aCDM);
80 HRESULT GenerateRequest(cdm::InitDataType aInitDataType,
81 const BYTE* aInitData, DWORD aInitDataSize,
82 cdm::SessionType aSessionType,
83 WMFClearKeySession* aSession,
84 std::string& aSessionIdOut);
85 HRESULT UpdateSession(const std::string& aSessionId, const BYTE* aResponse,
86 DWORD aResponseSize);
87 HRESULT CloseSession(const std::string& aSessionId);
88 HRESULT RemoveSession(const std::string& aSessionId);
89 HRESULT Decrypt(const cdm::InputBuffer_2& aBuffer,
90 cdm::DecryptedBlock* aDecryptedBlock);
92 void Shutdown();
93 bool IsShutdown();
95 private:
96 ~SessionManagerWrapper();
97 // cdm::Host_10
98 void OnInitialized(bool aSuccess) override {}
99 void OnResolveKeyStatusPromise(uint32_t aPromiseId,
100 cdm::KeyStatus aKeyStatus) override {}
101 void OnResolveNewSessionPromise(uint32_t aPromiseId, const char* aSessionId,
102 uint32_t aSessionIdSize) override;
103 void OnResolvePromise(uint32_t aPromiseId) override;
104 void OnRejectPromise(uint32_t aPromiseId, cdm::Exception aException,
105 uint32_t aSystemCode, const char* aErrorMessage,
106 uint32_t aErrorMessageSize) override;
107 void OnSessionMessage(const char* aSessionId, uint32_t aSessionIdSize,
108 cdm::MessageType aMessageType, const char* aMessage,
109 uint32_t aMessageSize) override;
110 void OnSessionKeysChange(const char* aSessionId, uint32_t aSessionIdSize,
111 bool aHasAdditionalUsableKey,
112 const cdm::KeyInformation* aKeysInfo,
113 uint32_t aKeysInfoCount) override;
114 void OnExpirationChange(const char* aSessionId, uint32_t aSessionIdSize,
115 cdm::Time aNewExpiryTime) override{
116 // No need to implement this because the session would never expire in
117 // testing.
119 void OnSessionClosed(const char* aSessionId,
120 uint32_t aSessionIdSize) override{
121 // No need to implement this because session doesn't have close callback
122 // or events.
124 cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override {
125 // We don't support this because we only support temporary session.
126 return nullptr;
128 void SendPlatformChallenge(const char* aServiceId, uint32_t aServiceIdSize,
129 const char* aChallenge,
130 uint32_t aChallengeSize) override {}
131 void EnableOutputProtection(uint32_t aDesiredProtectionMask) override {}
132 void QueryOutputProtectionStatus() override{};
133 void OnDeferredInitializationDone(cdm::StreamType aStreamType,
134 cdm::Status aDecoderStatus) override {}
135 void RequestStorageId(uint32_t aVersion) override {}
136 cdm::Buffer* Allocate(uint32_t aCapacity) override;
137 void SetTimer(int64_t aDelayMs, void* aContext) override {}
138 cdm::Time GetCurrentWallTime() override { return 0.0; }
139 friend class SessionManager;
141 Microsoft::WRL::ComPtr<WMFClearKeyCDM> mOwnerCDM;
142 RefPtr<ClearKeySessionManager> mSessionManager;
143 std::unordered_map<std::string, Microsoft::WRL::ComPtr<WMFClearKeySession>>
144 mSessions;
146 // This is a RAII helper class to use ClearKeySessionManager::XXXSession
147 // methods in a sync style, which is what MFCDM is required.
148 // ClearKeySessionManager uses cdm::Host_10's OnResolve/RejectXXX as callback
149 // to report whether those function calls relatd with specific promise id
150 // succeed or not. As we only do temporary session for ClearKey testing, we
151 // don't need to wait to setup the storage so calling those XXXsession
152 // functions are actully a sync process. We guarantee that
153 // ClearKeySessionManager will use OnResolve/Reject methods to notify us
154 // result, right after we calling the session related method.
155 // [How to to use this class, not thread-safe]
156 // 1. create it on the stack
157 // 2. use GetPromiseId() to generate a fake promise id for tracking
158 // 3. in cdm::Host_10's callback function, check promise id to know what
159 // result needs to be set
160 // 4. check result to see if the session method succeed or not
161 class SyncResultChecker final {
162 public:
163 using ResultType = std::variant<const char*, bool>;
164 explicit SyncResultChecker(SessionManagerWrapper& aOwner)
165 : mOwner(aOwner), mIdx(sIdx++), mKeySession(nullptr) {
166 mOwner.mActiveSyncResultChecker.insert({mIdx, this});
168 SyncResultChecker(SessionManagerWrapper& aOwner,
169 WMFClearKeySession* aKeySession)
170 : mOwner(aOwner), mIdx(sIdx++), mKeySession(aKeySession) {
171 mOwner.mActiveSyncResultChecker.insert({mIdx, this});
173 ~SyncResultChecker() { mOwner.mActiveSyncResultChecker.erase(mIdx); }
174 uint32_t GetPromiseId() const { return mIdx; }
175 const ResultType& GetResult() const { return mResult; }
176 WMFClearKeySession* GetKeySession() const { return mKeySession; }
178 private:
179 // Only allow setting result from these callbacks.
180 friend void SessionManagerWrapper::OnResolveNewSessionPromise(uint32_t,
181 const char*,
182 uint32_t);
183 friend void SessionManagerWrapper::OnResolvePromise(uint32_t);
184 friend void SessionManagerWrapper::OnRejectPromise(uint32_t, cdm::Exception,
185 uint32_t, const char*,
186 uint32_t);
187 void SetResultConstChar(const char* aResult) {
188 mResult.emplace<const char*>(aResult);
190 void SetResultBool(bool aResult) { mResult.emplace<bool>(aResult); }
192 static inline uint32_t sIdx = 0;
193 SessionManagerWrapper& mOwner;
194 const uint32_t mIdx;
195 ResultType mResult;
196 WMFClearKeySession* const mKeySession;
198 std::unordered_map<uint32_t, SyncResultChecker*> mActiveSyncResultChecker;
200 // Protect following members.
201 std::mutex mMutex;
202 bool mIsShutdown = false;
205 } // namespace mozilla
207 #endif // DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDM_H