Bug 1795082 - Part 2/2: Drop post-processing from getURL() r=zombie
[gecko.git] / media / wmf-clearkey / WMFClearKeySession.cpp
blob077665a8ae12404a6b775fe4081eee9f60a1ac1d
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 #include "WMFClearKeySession.h"
7 #include <codecvt>
8 #include <cmath>
9 #include <Mferror.h>
10 #include <winerror.h>
12 #include "WMFClearKeyCDM.h"
13 #include "WMFClearKeyUtils.h"
15 namespace mozilla {
17 using Microsoft::WRL::ComPtr;
19 static cdm::SessionType ToCdmSessionType(MF_MEDIAKEYSESSION_TYPE aSessionType) {
20 switch (aSessionType) {
21 case MF_MEDIAKEYSESSION_TYPE_TEMPORARY:
22 return cdm::SessionType::kTemporary;
23 default:
24 MOZ_ASSERT_UNREACHABLE("Only support temporary type for testing");
25 return cdm::SessionType::kTemporary;
29 static MF_MEDIAKEY_STATUS ToMFKeyStatus(cdm::KeyStatus aStatus) {
30 switch (aStatus) {
31 case cdm::KeyStatus::kUsable:
32 return MF_MEDIAKEY_STATUS_USABLE;
33 case cdm::KeyStatus::kExpired:
34 return MF_MEDIAKEY_STATUS_EXPIRED;
35 case cdm::KeyStatus::kOutputDownscaled:
36 return MF_MEDIAKEY_STATUS_OUTPUT_DOWNSCALED;
37 case cdm::KeyStatus::kStatusPending:
38 return MF_MEDIAKEY_STATUS_STATUS_PENDING;
39 case cdm::KeyStatus::kInternalError:
40 return MF_MEDIAKEY_STATUS_INTERNAL_ERROR;
41 case cdm::KeyStatus::kReleased:
42 return MF_MEDIAKEY_STATUS_RELEASED;
43 case cdm::KeyStatus::kOutputRestricted:
44 return MF_MEDIAKEY_STATUS_OUTPUT_RESTRICTED;
48 HRESULT WMFClearKeySession::RuntimeClassInitialize(
49 MF_MEDIAKEYSESSION_TYPE aSessionType,
50 IMFContentDecryptionModuleSessionCallbacks* aCallbacks,
51 SessionManagerWrapper* aManager) {
52 ENTRY_LOG();
53 MOZ_ASSERT(aCallbacks);
54 MOZ_ASSERT(aManager);
55 mSessionType = ToCdmSessionType(aSessionType);
56 mCallbacks = aCallbacks;
57 mSessionManager = aManager;
58 return S_OK;
61 WMFClearKeySession::~WMFClearKeySession() { ENTRY_LOG(); }
63 STDMETHODIMP WMFClearKeySession::GenerateRequest(LPCWSTR aInitDataType,
64 const BYTE* aInitData,
65 DWORD aInitDataSize) {
66 if (!mSessionManager) {
67 return MF_E_SHUTDOWN;
69 ENTRY_LOG_ARGS("init-type=%ls", aInitDataType);
70 cdm::InitDataType initType;
71 if (wcscmp(aInitDataType, L"cenc") == 0) {
72 initType = cdm::InitDataType::kCenc;
73 } else if (wcscmp(aInitDataType, L"keyids") == 0) {
74 initType = cdm::InitDataType::kKeyIds;
75 } else if (wcscmp(aInitDataType, L"webm") == 0) {
76 initType = cdm::InitDataType::kWebM;
77 } else {
78 return MF_NOT_SUPPORTED_ERR;
80 RETURN_IF_FAILED(mSessionManager->GenerateRequest(
81 initType, aInitData, aInitDataSize, mSessionType, this, mSessionId));
82 MOZ_ASSERT(!mSessionId.empty());
83 ENTRY_LOG_ARGS("created session, sid=%s", mSessionId.c_str());
84 return S_OK;
87 STDMETHODIMP WMFClearKeySession::Load(LPCWSTR session_id, BOOL* loaded) {
88 ENTRY_LOG();
89 // Per step 5, Load can only be called on persistent session, but we only
90 // support temporary session for MF clearkey due to testing reason.
91 // https://rawgit.com/w3c/encrypted-media/V1/index.html#dom-mediakeysession-load
92 return MF_E_NOT_AVAILABLE;
95 STDMETHODIMP WMFClearKeySession::Update(const BYTE* aResponse,
96 DWORD aResponseSize) {
97 ENTRY_LOG();
98 if (!mSessionManager) {
99 return MF_E_SHUTDOWN;
101 RETURN_IF_FAILED(
102 mSessionManager->UpdateSession(mSessionId, aResponse, aResponseSize));
103 return S_OK;
106 STDMETHODIMP WMFClearKeySession::Close() {
107 ENTRY_LOG();
108 // It has been shutdowned and sesssion has been closed.
109 if (!mSessionManager) {
110 return S_OK;
112 RETURN_IF_FAILED(mSessionManager->CloseSession(mSessionId));
113 return S_OK;
116 STDMETHODIMP WMFClearKeySession::Remove() {
117 ENTRY_LOG();
118 // It has been shutdowned and sesssion has been removed.
119 if (!mSessionManager) {
120 return S_OK;
122 RETURN_IF_FAILED(mSessionManager->RemoveSession(mSessionId));
123 return S_OK;
126 STDMETHODIMP WMFClearKeySession::GetSessionId(LPWSTR* aSessionId) {
127 ENTRY_LOG();
128 if (!mSessionManager) {
129 return S_OK;
131 if (mSessionId.empty()) {
132 *aSessionId = (LPWSTR)CoTaskMemAlloc(sizeof(wchar_t));
133 if (*aSessionId != NULL) {
134 **aSessionId = L'\0';
135 return S_OK;
136 } else {
137 return E_OUTOFMEMORY;
141 std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
142 std::wstring wideStr = converter.from_bytes(mSessionId);
143 *aSessionId =
144 (LPWSTR)CoTaskMemAlloc((wideStr.length() + 1) * sizeof(wchar_t));
145 if (*aSessionId != NULL) {
146 wcscpy_s(*aSessionId, wideStr.length() + 1, wideStr.c_str());
147 return S_OK;
148 } else {
149 return E_OUTOFMEMORY;
153 STDMETHODIMP WMFClearKeySession::GetExpiration(double* expiration) {
154 ENTRY_LOG();
155 // This is used for testing, never expires.
156 *expiration = std::nan("1");
157 return S_OK;
160 STDMETHODIMP WMFClearKeySession::GetKeyStatuses(MFMediaKeyStatus** aKeyStatuses,
161 UINT* aKeyStatusesCount) {
162 ENTRY_LOG();
163 *aKeyStatuses = nullptr;
164 *aKeyStatusesCount = 0;
166 const auto keyStatusCount = mKeyInfo.size();
167 if (mSessionId.empty() || keyStatusCount == 0) {
168 ENTRY_LOG_ARGS("No session ID or no key info!");
169 return S_OK;
172 MFMediaKeyStatus* keyStatusArray = nullptr;
173 keyStatusArray = static_cast<MFMediaKeyStatus*>(
174 CoTaskMemAlloc(keyStatusCount * sizeof(MFMediaKeyStatus)));
175 if (!keyStatusArray) {
176 ENTRY_LOG_ARGS("OOM when alloacting keyStatusArray!");
177 return E_OUTOFMEMORY;
179 ZeroMemory(keyStatusArray, keyStatusCount * sizeof(MFMediaKeyStatus));
180 for (UINT idx = 0; idx < keyStatusCount; idx++) {
181 keyStatusArray[idx].cbKeyId = mKeyInfo[idx].mKeyId.size();
182 keyStatusArray[idx].pbKeyId =
183 static_cast<BYTE*>(CoTaskMemAlloc(sizeof(mKeyInfo[idx].mKeyId.size())));
184 if (keyStatusArray[idx].pbKeyId == nullptr) {
185 ENTRY_LOG_ARGS("OOM when alloacting keyStatusArray's pbKeyId!");
186 return E_OUTOFMEMORY;
189 keyStatusArray[idx].eMediaKeyStatus =
190 ToMFKeyStatus(mKeyInfo[idx].mKeyStatus);
191 memcpy(keyStatusArray[idx].pbKeyId, mKeyInfo[idx].mKeyId.data(),
192 mKeyInfo[idx].mKeyId.size());
195 *aKeyStatuses = keyStatusArray;
196 *aKeyStatusesCount = keyStatusCount;
197 ENTRY_LOG_ARGS("return key status!");
198 return S_OK;
201 void WMFClearKeySession::OnKeyMessage(
202 MF_MEDIAKEYSESSION_MESSAGETYPE aMessageType, const BYTE* aMessage,
203 DWORD aMessageSize) {
204 ENTRY_LOG_ARGS("aMessageSize=%lu", aMessageSize);
205 if (!mSessionManager) {
206 return;
208 mCallbacks->KeyMessage(aMessageType, aMessage, aMessageSize, nullptr);
211 void WMFClearKeySession::OnKeyStatusChanged(
212 const cdm::KeyInformation* aKeysInfo, uint32_t aKeysInfoCount) {
213 ENTRY_LOG_ARGS("aKeysInfoCount=%u", aKeysInfoCount);
214 if (!mSessionManager) {
215 return;
217 mKeyInfo.clear();
218 for (uint32_t idx = 0; idx < aKeysInfoCount; idx++) {
219 const cdm::KeyInformation& key = aKeysInfo[idx];
220 mKeyInfo.push_back(KeyInformation{key.key_id, key.key_id_size, key.status});
221 ENTRY_LOG_ARGS("idx=%u, keySize=%u, status=%u", idx, key.key_id_size,
222 key.status);
224 mCallbacks->KeyStatusChanged();
227 void WMFClearKeySession::Shutdown() {
228 ENTRY_LOG();
229 mCallbacks = nullptr;
230 mSessionManager = nullptr;
233 } // namespace mozilla