Coverage Report

Created: 2018-09-25 14:53

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