Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/CDMProxy.h
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
#ifndef CDMProxy_h_
8
#define CDMProxy_h_
9
10
#include "mozilla/CDMCaps.h"
11
#include "mozilla/DataMutex.h"
12
#include "mozilla/MozPromise.h"
13
14
#include "mozilla/dom/MediaKeyMessageEvent.h"
15
#include "mozilla/dom/MediaKeys.h"
16
17
#include "nsIThread.h"
18
19
namespace mozilla {
20
class MediaRawData;
21
class ChromiumCDMProxy;
22
23
namespace eme {
24
enum DecryptStatus {
25
  Ok = 0,
26
  GenericErr = 1,
27
  NoKeyErr = 2,
28
  AbortedErr = 3,
29
};
30
}
31
32
using eme::DecryptStatus;
33
34
struct DecryptResult {
35
  DecryptResult(DecryptStatus aStatus, MediaRawData* aSample)
36
    : mStatus(aStatus)
37
    , mSample(aSample)
38
0
  {}
39
  DecryptStatus mStatus;
40
  RefPtr<MediaRawData> mSample;
41
};
42
43
typedef MozPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise;
44
45
class CDMKeyInfo {
46
public:
47
  explicit CDMKeyInfo(const nsTArray<uint8_t>& aKeyId)
48
    : mKeyId(aKeyId)
49
    , mStatus()
50
0
  {}
51
52
  CDMKeyInfo(const nsTArray<uint8_t>& aKeyId,
53
             const dom::Optional<dom::MediaKeyStatus>& aStatus)
54
    : mKeyId(aKeyId)
55
    , mStatus(aStatus.Value())
56
0
  {}
57
58
  // The copy-ctor and copy-assignment operator for Optional<T> are declared as
59
  // delete, so override CDMKeyInfo copy-ctor for nsTArray operations.
60
  CDMKeyInfo(const CDMKeyInfo& aKeyInfo)
61
0
  {
62
0
    mKeyId = aKeyInfo.mKeyId;
63
0
    if (aKeyInfo.mStatus.WasPassed()) {
64
0
      mStatus.Construct(aKeyInfo.mStatus.Value());
65
0
    }
66
0
  }
67
68
  nsTArray<uint8_t> mKeyId;
69
  dom::Optional<dom::MediaKeyStatus> mStatus;
70
};
71
72
// Time is defined as the number of milliseconds since the
73
// Epoch (00:00:00 UTC, January 1, 1970).
74
typedef int64_t UnixTime;
75
76
// Proxies calls CDM, and proxies calls back.
77
// Note: Promises are passed in via a PromiseId, so that the ID can be
78
// passed via IPC to the CDM, which can then signal when to reject or
79
// resolve the promise using its PromiseId.
80
class CDMProxy {
81
protected:
82
  typedef dom::PromiseId PromiseId;
83
  typedef dom::MediaKeySessionType MediaKeySessionType;
84
public:
85
86
  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
87
88
  // Main thread only.
89
  CDMProxy(dom::MediaKeys* aKeys,
90
           const nsAString& aKeySystem,
91
           bool aDistinctiveIdentifierRequired,
92
           bool aPersistentStateRequired,
93
           nsIEventTarget* aMainThread)
94
    : mKeys(aKeys)
95
    , mKeySystem(aKeySystem)
96
    , mCapabilites("CDMProxy::mCDMCaps")
97
    , mDistinctiveIdentifierRequired(aDistinctiveIdentifierRequired)
98
    , mPersistentStateRequired(aPersistentStateRequired)
99
    , mMainThread(aMainThread)
100
0
  {}
101
102
  // Main thread only.
103
  // Loads the CDM corresponding to mKeySystem.
104
  // Calls MediaKeys::OnCDMCreated() when the CDM is created.
105
  virtual void Init(PromiseId aPromiseId,
106
                    const nsAString& aOrigin,
107
                    const nsAString& aTopLevelOrigin,
108
                    const nsAString& aName) = 0;
109
110
0
  virtual void OnSetDecryptorId(uint32_t aId) {}
111
112
  // Main thread only.
113
  // Uses the CDM to create a key session.
114
  // Calls MediaKeys::OnSessionActivated() when session is created.
115
  // Assumes ownership of (std::move()s) aInitData's contents.
116
  virtual void CreateSession(uint32_t aCreateSessionToken,
117
                             MediaKeySessionType aSessionType,
118
                             PromiseId aPromiseId,
119
                             const nsAString& aInitDataType,
120
                             nsTArray<uint8_t>& aInitData) = 0;
121
122
  // Main thread only.
123
  // Uses the CDM to load a presistent session stored on disk.
124
  // Calls MediaKeys::OnSessionActivated() when session is loaded.
125
  virtual void LoadSession(PromiseId aPromiseId,
126
                           dom::MediaKeySessionType aSessionType,
127
                           const nsAString& aSessionId) = 0;
128
129
  // Main thread only.
130
  // Sends a new certificate to the CDM.
131
  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
132
  // processed the request.
133
  // Assumes ownership of (std::move()s) aCert's contents.
134
  virtual void SetServerCertificate(PromiseId aPromiseId,
135
                                    nsTArray<uint8_t>& aCert) = 0;
136
137
  // Main thread only.
138
  // Sends an update to the CDM.
139
  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
140
  // processed the request.
141
  // Assumes ownership of (std::move()s) aResponse's contents.
142
  virtual void UpdateSession(const nsAString& aSessionId,
143
                             PromiseId aPromiseId,
144
                             nsTArray<uint8_t>& aResponse) = 0;
145
146
  // Main thread only.
147
  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
148
  // processed the request.
149
  // If processing this operation results in the session actually closing,
150
  // we also call MediaKeySession::OnClosed(), which in turn calls
151
  // MediaKeys::OnSessionClosed().
152
  virtual void CloseSession(const nsAString& aSessionId,
153
                            PromiseId aPromiseId) = 0;
154
155
  // Main thread only.
156
  // Removes all data for a persisent session.
157
  // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
158
  // processed the request.
159
  virtual void RemoveSession(const nsAString& aSessionId,
160
                             PromiseId aPromiseId) = 0;
161
162
  // Main thread only.
163
  virtual void Shutdown() = 0;
164
165
  // Main thread only.
166
  virtual void Terminated() = 0;
167
168
  // Threadsafe.
169
  virtual const nsCString& GetNodeId() const = 0;
170
171
  // Main thread only.
172
  virtual void OnSetSessionId(uint32_t aCreateSessionToken,
173
                              const nsAString& aSessionId) = 0;
174
175
  // Main thread only.
176
  virtual void OnResolveLoadSessionPromise(uint32_t aPromiseId,
177
                                           bool aSuccess) = 0;
178
179
  // Main thread only.
180
  virtual void OnSessionMessage(const nsAString& aSessionId,
181
                                dom::MediaKeyMessageType aMessageType,
182
                                const nsTArray<uint8_t>& aMessage) = 0;
183
184
  // Main thread only.
185
  virtual void OnExpirationChange(const nsAString& aSessionId,
186
                                  UnixTime aExpiryTime) = 0;
187
188
  // Main thread only.
189
  virtual void OnSessionClosed(const nsAString& aSessionId) = 0;
190
191
  // Main thread only.
192
  virtual void OnSessionError(const nsAString& aSessionId,
193
                              nsresult aException,
194
                              uint32_t aSystemCode,
195
                              const nsAString& aMsg) = 0;
196
197
  // Main thread only.
198
  virtual void OnRejectPromise(uint32_t aPromiseId,
199
                               nsresult aDOMException,
200
                               const nsCString& aMsg) = 0;
201
202
  virtual RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) = 0;
203
204
  // Owner thread only.
205
  virtual void OnDecrypted(uint32_t aId,
206
                           DecryptStatus aResult,
207
                           const nsTArray<uint8_t>& aDecryptedData) = 0;
208
209
  // Reject promise with DOMException corresponding to aExceptionCode.
210
  // Can be called from any thread.
211
  virtual void RejectPromise(PromiseId aId,
212
                             nsresult aExceptionCode,
213
                             const nsCString& aReason) = 0;
214
215
  // Resolves promise with "undefined".
216
  // Can be called from any thread.
217
  virtual void ResolvePromise(PromiseId aId) = 0;
218
219
  // Threadsafe.
220
  virtual const nsString& KeySystem() const = 0;
221
222
  virtual DataMutex<CDMCaps>& Capabilites() = 0;
223
224
  // Main thread only.
225
  virtual void OnKeyStatusesChange(const nsAString& aSessionId) = 0;
226
227
  // Main thread only.
228
  // Calls MediaKeys->ResolvePromiseWithKeyStatus(aPromiseId, aKeyStatus) after
229
  // the CDM has processed the request.
230
  virtual void GetStatusForPolicy(PromiseId aPromiseId,
231
                                  const nsAString& aMinHdcpVersion) = 0;
232
233
#ifdef DEBUG
234
  virtual bool IsOnOwnerThread() = 0;
235
#endif
236
237
0
  virtual uint32_t GetDecryptorId() { return 0; }
238
239
0
  virtual ChromiumCDMProxy* AsChromiumCDMProxy() { return nullptr; }
240
241
protected:
242
0
  virtual ~CDMProxy() {}
243
244
  // Helper to enforce that a raw pointer is only accessed on the main thread.
245
  template<class Type>
246
  class MainThreadOnlyRawPtr {
247
  public:
248
    explicit MainThreadOnlyRawPtr(Type* aPtr)
249
      : mPtr(aPtr)
250
0
    {
251
0
      MOZ_ASSERT(NS_IsMainThread());
252
0
    }
253
254
0
    bool IsNull() const {
255
0
      MOZ_ASSERT(NS_IsMainThread());
256
0
      return !mPtr;
257
0
    }
258
259
0
    void Clear() {
260
0
      MOZ_ASSERT(NS_IsMainThread());
261
0
      mPtr = nullptr;
262
0
    }
263
264
0
    Type* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
265
0
      MOZ_ASSERT(NS_IsMainThread());
266
0
      return mPtr;
267
0
    }
268
  private:
269
    Type* mPtr;
270
  };
271
272
  // Our reference back to the MediaKeys object.
273
  // WARNING: This is a non-owning reference that is cleared by MediaKeys
274
  // destructor. only use on main thread, and always nullcheck before using!
275
  MainThreadOnlyRawPtr<dom::MediaKeys> mKeys;
276
277
  const nsString mKeySystem;
278
279
  // Onwer specified thread. e.g. Gecko Media Plugin thread.
280
  // All interactions with the out-of-process EME plugin must come from this thread.
281
  RefPtr<nsIThread> mOwnerThread;
282
283
  nsCString mNodeId;
284
285
  DataMutex<CDMCaps> mCapabilites;
286
287
  const bool mDistinctiveIdentifierRequired;
288
  const bool mPersistentStateRequired;
289
290
  // The main thread associated with the root document.
291
  const nsCOMPtr<nsIEventTarget> mMainThread;
292
};
293
294
295
} // namespace mozilla
296
297
#endif // CDMProxy_h_