Line data Source code
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 file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "ChromiumCDMProxy.h"
8 : #include "mozilla/dom/MediaKeySession.h"
9 : #include "GMPUtils.h"
10 : #include "nsPrintfCString.h"
11 : #include "GMPService.h"
12 :
13 : namespace mozilla {
14 :
15 0 : ChromiumCDMProxy::ChromiumCDMProxy(dom::MediaKeys* aKeys,
16 : const nsAString& aKeySystem,
17 : GMPCrashHelper* aCrashHelper,
18 : bool aDistinctiveIdentifierRequired,
19 : bool aPersistentStateRequired,
20 0 : nsIEventTarget* aMainThread)
21 : : CDMProxy(aKeys,
22 : aKeySystem,
23 : aDistinctiveIdentifierRequired,
24 : aPersistentStateRequired,
25 : aMainThread)
26 : , mCrashHelper(aCrashHelper)
27 : , mCDMMutex("ChromiumCDMProxy")
28 0 : , mGMPThread(GetGMPAbstractThread())
29 : {
30 0 : MOZ_ASSERT(NS_IsMainThread());
31 0 : MOZ_COUNT_CTOR(ChromiumCDMProxy);
32 0 : }
33 :
34 0 : ChromiumCDMProxy::~ChromiumCDMProxy()
35 : {
36 0 : MOZ_COUNT_DTOR(ChromiumCDMProxy);
37 0 : }
38 :
39 : void
40 0 : ChromiumCDMProxy::Init(PromiseId aPromiseId,
41 : const nsAString& aOrigin,
42 : const nsAString& aTopLevelOrigin,
43 : const nsAString& aGMPName)
44 : {
45 0 : MOZ_ASSERT(NS_IsMainThread());
46 0 : NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
47 :
48 0 : EME_LOG(
49 : "ChromiumCDMProxy::Init (pid=%u, origin=%s, topLevelOrigin=%s, gmp=%s)",
50 : aPromiseId,
51 : NS_ConvertUTF16toUTF8(aOrigin).get(),
52 : NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
53 : NS_ConvertUTF16toUTF8(aGMPName).get());
54 :
55 0 : if (!mGMPThread) {
56 0 : RejectPromise(
57 : aPromiseId,
58 : NS_ERROR_DOM_INVALID_STATE_ERR,
59 0 : NS_LITERAL_CSTRING("Couldn't get GMP thread ChromiumCDMProxy::Init"));
60 0 : return;
61 : }
62 :
63 0 : if (aGMPName.IsEmpty()) {
64 : RejectPromise(aPromiseId,
65 : NS_ERROR_DOM_INVALID_STATE_ERR,
66 0 : nsPrintfCString("Unknown GMP for keysystem '%s'",
67 0 : NS_ConvertUTF16toUTF8(mKeySystem).get()));
68 0 : return;
69 : }
70 :
71 0 : gmp::NodeId nodeId(aOrigin, aTopLevelOrigin, aGMPName);
72 0 : RefPtr<AbstractThread> thread = mGMPThread;
73 0 : RefPtr<GMPCrashHelper> helper(mCrashHelper);
74 0 : RefPtr<ChromiumCDMProxy> self(this);
75 0 : nsCString keySystem = NS_ConvertUTF16toUTF8(mKeySystem);
76 0 : RefPtr<Runnable> task(NS_NewRunnableFunction(
77 : "ChromiumCDMProxy::Init",
78 0 : [self, nodeId, helper, aPromiseId, thread, keySystem]() -> void {
79 0 : MOZ_ASSERT(self->IsOnOwnerThread());
80 :
81 : RefPtr<gmp::GeckoMediaPluginService> service =
82 0 : gmp::GeckoMediaPluginService::GetGeckoMediaPluginService();
83 0 : if (!service) {
84 0 : self->RejectPromise(
85 : aPromiseId,
86 : NS_ERROR_DOM_INVALID_STATE_ERR,
87 0 : NS_LITERAL_CSTRING(
88 0 : "Couldn't get GeckoMediaPluginService in ChromiumCDMProxy::Init"));
89 0 : return;
90 : }
91 : RefPtr<gmp::GetCDMParentPromise> promise =
92 0 : service->GetCDM(nodeId, { keySystem }, helper);
93 : promise->Then(
94 : thread,
95 : __func__,
96 0 : [self, aPromiseId](RefPtr<gmp::ChromiumCDMParent> cdm) {
97 0 : if (!cdm->Init(self,
98 0 : self->mDistinctiveIdentifierRequired,
99 0 : self->mPersistentStateRequired)) {
100 0 : self->RejectPromise(aPromiseId,
101 : NS_ERROR_FAILURE,
102 0 : NS_LITERAL_CSTRING("GetCDM failed."));
103 0 : return;
104 : }
105 : {
106 0 : MutexAutoLock lock(self->mCDMMutex);
107 0 : self->mCDM = cdm;
108 : }
109 0 : self->OnCDMCreated(aPromiseId);
110 : },
111 0 : [self, aPromiseId](nsresult rv) {
112 0 : self->RejectPromise(
113 0 : aPromiseId, NS_ERROR_FAILURE, NS_LITERAL_CSTRING("GetCDM failed."));
114 0 : });
115 0 : }));
116 :
117 0 : mGMPThread->Dispatch(task.forget());
118 : }
119 :
120 : void
121 0 : ChromiumCDMProxy::OnCDMCreated(uint32_t aPromiseId)
122 : {
123 0 : EME_LOG("ChromiumCDMProxy::OnCDMCreated(pid=%u) isMainThread=%d this=%p",
124 : aPromiseId,
125 : NS_IsMainThread(),
126 : this);
127 :
128 0 : if (!NS_IsMainThread()) {
129 0 : mMainThread->Dispatch(
130 0 : NewRunnableMethod<PromiseId>("ChromiumCDMProxy::OnCDMCreated",
131 : this,
132 : &ChromiumCDMProxy::OnCDMCreated,
133 : aPromiseId),
134 0 : NS_DISPATCH_NORMAL);
135 0 : return;
136 : }
137 0 : MOZ_ASSERT(NS_IsMainThread());
138 0 : if (mKeys.IsNull()) {
139 0 : return;
140 : }
141 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
142 : // This should only be called once the CDM has been created.
143 0 : MOZ_ASSERT(cdm);
144 0 : if (cdm) {
145 0 : mKeys->OnCDMCreated(aPromiseId, cdm->PluginId());
146 : } else {
147 : // No CDM? Shouldn't be possible, but reject the promise anyway...
148 0 : mKeys->RejectPromise(aPromiseId,
149 : NS_ERROR_DOM_INVALID_STATE_ERR,
150 0 : NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
151 : }
152 : }
153 :
154 : #ifdef DEBUG
155 : bool
156 0 : ChromiumCDMProxy::IsOnOwnerThread()
157 : {
158 0 : return mGMPThread->IsCurrentThreadIn();
159 : }
160 : #endif
161 :
162 : static uint32_t
163 0 : ToCDMSessionType(dom::MediaKeySessionType aSessionType)
164 : {
165 0 : switch (aSessionType) {
166 : case dom::MediaKeySessionType::Temporary:
167 0 : return static_cast<uint32_t>(cdm::kTemporary);
168 : case dom::MediaKeySessionType::Persistent_license:
169 0 : return static_cast<uint32_t>(cdm::kPersistentLicense);
170 : default:
171 0 : return static_cast<uint32_t>(cdm::kTemporary);
172 : };
173 : };
174 :
175 : static uint32_t
176 0 : ToCDMInitDataType(const nsAString& aInitDataType)
177 : {
178 0 : if (aInitDataType.EqualsLiteral("cenc")) {
179 0 : return static_cast<uint32_t>(cdm::kCenc);
180 : }
181 0 : if (aInitDataType.EqualsLiteral("webm")) {
182 0 : return static_cast<uint32_t>(cdm::kWebM);
183 : }
184 0 : if (aInitDataType.EqualsLiteral("keyids")) {
185 0 : return static_cast<uint32_t>(cdm::kKeyIds);
186 : }
187 0 : return static_cast<uint32_t>(cdm::kCenc);
188 : }
189 :
190 : void
191 0 : ChromiumCDMProxy::CreateSession(uint32_t aCreateSessionToken,
192 : dom::MediaKeySessionType aSessionType,
193 : PromiseId aPromiseId,
194 : const nsAString& aInitDataType,
195 : nsTArray<uint8_t>& aInitData)
196 : {
197 0 : MOZ_ASSERT(NS_IsMainThread());
198 0 : EME_LOG("ChromiumCDMProxy::CreateSession(token=%u, type=%d, pid=%u) "
199 : "initDataLen=%zu",
200 : aCreateSessionToken,
201 : (int)aSessionType,
202 : aPromiseId,
203 : aInitData.Length());
204 :
205 0 : uint32_t sessionType = ToCDMSessionType(aSessionType);
206 0 : uint32_t initDataType = ToCDMInitDataType(aInitDataType);
207 :
208 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
209 0 : if (!cdm) {
210 0 : RejectPromise(aPromiseId,
211 : NS_ERROR_DOM_INVALID_STATE_ERR,
212 0 : NS_LITERAL_CSTRING("Null CDM in CreateSession"));
213 0 : return;
214 : }
215 :
216 0 : mGMPThread->Dispatch(NewRunnableMethod<uint32_t,
217 : uint32_t,
218 : uint32_t,
219 : uint32_t,
220 0 : nsTArray<uint8_t>>(
221 : "gmp::ChromiumCDMParent::CreateSession",
222 : cdm,
223 : &gmp::ChromiumCDMParent::CreateSession,
224 : aCreateSessionToken,
225 : sessionType,
226 : initDataType,
227 : aPromiseId,
228 0 : Move(aInitData)));
229 : }
230 :
231 : void
232 0 : ChromiumCDMProxy::LoadSession(PromiseId aPromiseId,
233 : dom::MediaKeySessionType aSessionType,
234 : const nsAString& aSessionId)
235 : {
236 0 : MOZ_ASSERT(NS_IsMainThread());
237 :
238 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
239 0 : if (!cdm) {
240 0 : RejectPromise(aPromiseId,
241 : NS_ERROR_DOM_INVALID_STATE_ERR,
242 0 : NS_LITERAL_CSTRING("Null CDM in LoadSession"));
243 0 : return;
244 : }
245 :
246 0 : mGMPThread->Dispatch(NewRunnableMethod<uint32_t, uint32_t, nsString>(
247 : "gmp::ChromiumCDMParent::LoadSession",
248 : cdm,
249 : &gmp::ChromiumCDMParent::LoadSession,
250 : aPromiseId,
251 0 : ToCDMSessionType(aSessionType),
252 0 : aSessionId));
253 : }
254 :
255 : void
256 0 : ChromiumCDMProxy::SetServerCertificate(PromiseId aPromiseId,
257 : nsTArray<uint8_t>& aCert)
258 : {
259 0 : MOZ_ASSERT(NS_IsMainThread());
260 0 : EME_LOG("ChromiumCDMProxy::SetServerCertificate(pid=%u) certLen=%zu",
261 : aPromiseId,
262 : aCert.Length());
263 :
264 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
265 0 : if (!cdm) {
266 0 : RejectPromise(aPromiseId,
267 : NS_ERROR_DOM_INVALID_STATE_ERR,
268 0 : NS_LITERAL_CSTRING("Null CDM in SetServerCertificate"));
269 0 : return;
270 : }
271 :
272 0 : mGMPThread->Dispatch(NewRunnableMethod<uint32_t, nsTArray<uint8_t>>(
273 : "gmp::ChromiumCDMParent::SetServerCertificate",
274 : cdm,
275 : &gmp::ChromiumCDMParent::SetServerCertificate,
276 : aPromiseId,
277 0 : Move(aCert)));
278 : }
279 :
280 : void
281 0 : ChromiumCDMProxy::UpdateSession(const nsAString& aSessionId,
282 : PromiseId aPromiseId,
283 : nsTArray<uint8_t>& aResponse)
284 : {
285 0 : MOZ_ASSERT(NS_IsMainThread());
286 0 : EME_LOG("ChromiumCDMProxy::UpdateSession(sid='%s', pid=%u) responseLen=%zu",
287 : NS_ConvertUTF16toUTF8(aSessionId).get(),
288 : aPromiseId,
289 : aResponse.Length());
290 :
291 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
292 0 : if (!cdm) {
293 0 : RejectPromise(aPromiseId,
294 : NS_ERROR_DOM_INVALID_STATE_ERR,
295 0 : NS_LITERAL_CSTRING("Null CDM in UpdateSession"));
296 0 : return;
297 : }
298 0 : mGMPThread->Dispatch(
299 0 : NewRunnableMethod<nsCString, uint32_t, nsTArray<uint8_t>>(
300 : "gmp::ChromiumCDMParent::UpdateSession",
301 : cdm,
302 : &gmp::ChromiumCDMParent::UpdateSession,
303 0 : NS_ConvertUTF16toUTF8(aSessionId),
304 : aPromiseId,
305 0 : Move(aResponse)));
306 : }
307 :
308 : void
309 0 : ChromiumCDMProxy::CloseSession(const nsAString& aSessionId,
310 : PromiseId aPromiseId)
311 : {
312 0 : MOZ_ASSERT(NS_IsMainThread());
313 0 : EME_LOG("ChromiumCDMProxy::CloseSession(sid='%s', pid=%u)",
314 : NS_ConvertUTF16toUTF8(aSessionId).get(),
315 : aPromiseId);
316 :
317 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
318 0 : if (!cdm) {
319 0 : RejectPromise(aPromiseId,
320 : NS_ERROR_DOM_INVALID_STATE_ERR,
321 0 : NS_LITERAL_CSTRING("Null CDM in CloseSession"));
322 0 : return;
323 : }
324 0 : mGMPThread->Dispatch(NewRunnableMethod<nsCString, uint32_t>(
325 : "gmp::ChromiumCDMParent::CloseSession",
326 : cdm,
327 : &gmp::ChromiumCDMParent::CloseSession,
328 0 : NS_ConvertUTF16toUTF8(aSessionId),
329 0 : aPromiseId));
330 : }
331 :
332 : void
333 0 : ChromiumCDMProxy::RemoveSession(const nsAString& aSessionId,
334 : PromiseId aPromiseId)
335 : {
336 0 : MOZ_ASSERT(NS_IsMainThread());
337 0 : EME_LOG("ChromiumCDMProxy::RemoveSession(sid='%s', pid=%u)",
338 : NS_ConvertUTF16toUTF8(aSessionId).get(),
339 : aPromiseId);
340 :
341 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
342 0 : if (!cdm) {
343 0 : RejectPromise(aPromiseId,
344 : NS_ERROR_DOM_INVALID_STATE_ERR,
345 0 : NS_LITERAL_CSTRING("Null CDM in RemoveSession"));
346 0 : return;
347 : }
348 0 : mGMPThread->Dispatch(NewRunnableMethod<nsCString, uint32_t>(
349 : "gmp::ChromiumCDMParent::RemoveSession",
350 : cdm,
351 : &gmp::ChromiumCDMParent::RemoveSession,
352 0 : NS_ConvertUTF16toUTF8(aSessionId),
353 0 : aPromiseId));
354 : }
355 :
356 : void
357 0 : ChromiumCDMProxy::Shutdown()
358 : {
359 0 : MOZ_ASSERT(NS_IsMainThread());
360 0 : EME_LOG("ChromiumCDMProxy::Shutdown()");
361 0 : mKeys.Clear();
362 0 : RefPtr<gmp::ChromiumCDMParent> cdm;
363 : {
364 0 : MutexAutoLock lock(mCDMMutex);
365 0 : cdm.swap(mCDM);
366 : }
367 0 : if (cdm) {
368 : // We need to keep this proxy alive until the parent has finished its
369 : // Shutdown (as it may still try to use the proxy until then).
370 0 : RefPtr<ChromiumCDMProxy> self(this);
371 0 : nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction(
372 0 : "ChromiumCDMProxy::Shutdown", [self, cdm]() { cdm->Shutdown(); });
373 0 : mGMPThread->Dispatch(task.forget());
374 : }
375 0 : }
376 :
377 : void
378 0 : ChromiumCDMProxy::RejectPromise(PromiseId aId,
379 : nsresult aCode,
380 : const nsCString& aReason)
381 : {
382 0 : if (!NS_IsMainThread()) {
383 0 : nsCOMPtr<nsIRunnable> task;
384 0 : task = NewRunnableMethod<PromiseId, nsresult, nsCString>(
385 : "ChromiumCDMProxy::RejectPromise",
386 : this,
387 : &ChromiumCDMProxy::RejectPromise,
388 : aId,
389 : aCode,
390 0 : aReason);
391 0 : NS_DispatchToMainThread(task);
392 0 : return;
393 : }
394 0 : EME_LOG("ChromiumCDMProxy::RejectPromise(pid=%u, code=0x%x, reason='%s')",
395 : aId,
396 : static_cast<uint32_t>(aCode),
397 : aReason.get());
398 0 : if (!mKeys.IsNull()) {
399 0 : mKeys->RejectPromise(aId, aCode, aReason);
400 : }
401 : }
402 :
403 : void
404 0 : ChromiumCDMProxy::ResolvePromise(PromiseId aId)
405 : {
406 0 : if (!NS_IsMainThread()) {
407 0 : nsCOMPtr<nsIRunnable> task;
408 0 : task = NewRunnableMethod<PromiseId>("ChromiumCDMProxy::ResolvePromise",
409 : this,
410 : &ChromiumCDMProxy::ResolvePromise,
411 0 : aId);
412 0 : NS_DispatchToMainThread(task);
413 0 : return;
414 : }
415 :
416 0 : EME_LOG("ChromiumCDMProxy::ResolvePromise(pid=%u)", aId);
417 0 : if (!mKeys.IsNull()) {
418 0 : mKeys->ResolvePromise(aId);
419 : } else {
420 0 : NS_WARNING("ChromiumCDMProxy unable to resolve promise!");
421 : }
422 : }
423 :
424 : const nsCString&
425 0 : ChromiumCDMProxy::GetNodeId() const
426 : {
427 0 : return mNodeId;
428 : }
429 :
430 : void
431 0 : ChromiumCDMProxy::OnSetSessionId(uint32_t aCreateSessionToken,
432 : const nsAString& aSessionId)
433 : {
434 0 : MOZ_ASSERT(NS_IsMainThread());
435 0 : EME_LOG("ChromiumCDMProxy::OnSetSessionId(token=%u, sid='%s')",
436 : aCreateSessionToken,
437 : NS_ConvertUTF16toUTF8(aSessionId).get());
438 :
439 0 : if (mKeys.IsNull()) {
440 0 : return;
441 : }
442 : RefPtr<dom::MediaKeySession> session(
443 0 : mKeys->GetPendingSession(aCreateSessionToken));
444 0 : if (session) {
445 0 : session->SetSessionId(aSessionId);
446 : }
447 : }
448 :
449 : void
450 0 : ChromiumCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId,
451 : bool aSuccess)
452 : {
453 0 : MOZ_ASSERT(NS_IsMainThread());
454 0 : if (mKeys.IsNull()) {
455 0 : return;
456 : }
457 0 : mKeys->OnSessionLoaded(aPromiseId, aSuccess);
458 : }
459 :
460 : void
461 0 : ChromiumCDMProxy::OnSessionMessage(const nsAString& aSessionId,
462 : dom::MediaKeyMessageType aMessageType,
463 : nsTArray<uint8_t>& aMessage)
464 : {
465 0 : MOZ_ASSERT(NS_IsMainThread());
466 0 : if (mKeys.IsNull()) {
467 0 : return;
468 : }
469 0 : RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
470 0 : if (session) {
471 0 : session->DispatchKeyMessage(aMessageType, aMessage);
472 : }
473 : }
474 :
475 : void
476 0 : ChromiumCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId)
477 : {
478 0 : MOZ_ASSERT(NS_IsMainThread());
479 0 : if (mKeys.IsNull()) {
480 0 : return;
481 : }
482 0 : RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
483 0 : if (session) {
484 0 : session->DispatchKeyStatusesChange();
485 : }
486 : }
487 :
488 : void
489 0 : ChromiumCDMProxy::OnExpirationChange(const nsAString& aSessionId,
490 : GMPTimestamp aExpiryTime)
491 : {
492 0 : MOZ_ASSERT(NS_IsMainThread());
493 0 : if (mKeys.IsNull()) {
494 0 : return;
495 : }
496 0 : RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
497 0 : if (session) {
498 : // Expiry of 0 is interpreted as "never expire". See bug 1345341.
499 0 : double t = (aExpiryTime == 0) ? std::numeric_limits<double>::quiet_NaN()
500 0 : : static_cast<double>(aExpiryTime);
501 0 : session->SetExpiration(t);
502 : }
503 : }
504 :
505 : void
506 0 : ChromiumCDMProxy::OnSessionClosed(const nsAString& aSessionId)
507 : {
508 0 : MOZ_ASSERT(NS_IsMainThread());
509 :
510 0 : bool keyStatusesChange = false;
511 : {
512 0 : CDMCaps::AutoLock caps(Capabilites());
513 0 : keyStatusesChange = caps.RemoveKeysForSession(nsString(aSessionId));
514 : }
515 0 : if (keyStatusesChange) {
516 0 : OnKeyStatusesChange(aSessionId);
517 : }
518 0 : if (mKeys.IsNull()) {
519 0 : return;
520 : }
521 0 : RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
522 0 : if (session) {
523 0 : session->OnClosed();
524 : }
525 : }
526 :
527 : void
528 0 : ChromiumCDMProxy::OnDecrypted(uint32_t aId,
529 : DecryptStatus aResult,
530 : const nsTArray<uint8_t>& aDecryptedData)
531 : {
532 0 : }
533 :
534 : void
535 0 : ChromiumCDMProxy::OnSessionError(const nsAString& aSessionId,
536 : nsresult aException,
537 : uint32_t aSystemCode,
538 : const nsAString& aMsg)
539 : {
540 0 : MOZ_ASSERT(NS_IsMainThread());
541 0 : if (mKeys.IsNull()) {
542 0 : return;
543 : }
544 0 : RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
545 0 : if (session) {
546 0 : session->DispatchKeyError(aSystemCode);
547 : }
548 0 : LogToConsole(aMsg);
549 : }
550 :
551 : void
552 0 : ChromiumCDMProxy::OnRejectPromise(uint32_t aPromiseId,
553 : nsresult aDOMException,
554 : const nsCString& aMsg)
555 : {
556 0 : MOZ_ASSERT(NS_IsMainThread());
557 0 : RejectPromise(aPromiseId, aDOMException, aMsg);
558 0 : }
559 :
560 : const nsString&
561 0 : ChromiumCDMProxy::KeySystem() const
562 : {
563 0 : return mKeySystem;
564 : }
565 :
566 : CDMCaps&
567 0 : ChromiumCDMProxy::Capabilites()
568 : {
569 0 : return mCapabilites;
570 : }
571 :
572 : RefPtr<DecryptPromise>
573 0 : ChromiumCDMProxy::Decrypt(MediaRawData* aSample)
574 : {
575 0 : RefPtr<gmp::ChromiumCDMParent> cdm = GetCDMParent();
576 0 : if (!cdm) {
577 0 : return DecryptPromise::CreateAndReject(DecryptResult(eme::AbortedErr, aSample),
578 0 : __func__);
579 : }
580 0 : RefPtr<MediaRawData> sample = aSample;
581 : return InvokeAsync(
582 0 : mGMPThread, __func__, [cdm, sample]() { return cdm->Decrypt(sample); });
583 : }
584 :
585 : void
586 0 : ChromiumCDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
587 : nsTArray<nsCString>& aSessionIds)
588 : {
589 0 : CDMCaps::AutoLock caps(Capabilites());
590 0 : caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
591 0 : }
592 :
593 : void
594 0 : ChromiumCDMProxy::Terminated()
595 : {
596 0 : if (!mKeys.IsNull()) {
597 0 : mKeys->Terminated();
598 : }
599 0 : }
600 :
601 : already_AddRefed<gmp::ChromiumCDMParent>
602 0 : ChromiumCDMProxy::GetCDMParent()
603 : {
604 0 : MutexAutoLock lock(mCDMMutex);
605 0 : RefPtr<gmp::ChromiumCDMParent> cdm = mCDM;
606 0 : return cdm.forget();
607 : }
608 :
609 : } // namespace mozilla
|