1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
media / mojo / mojom / content_decryption_module.mojom [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module media.mojom;
import "media/mojo/mojom/decryptor.mojom";
import "media/mojo/mojom/media_types.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
// See media::EmeInitDataType.
[Native]
enum EmeInitDataType;
// See media::CdmSessionType
[Native]
enum CdmSessionType;
// See media::CdmMessageType
[Native]
enum CdmMessageType;
// See media::CdmKeyInformation::KeyStatus
enum CdmKeyStatus {
USABLE,
INTERNAL_ERROR,
EXPIRED,
OUTPUT_RESTRICTED,
OUTPUT_DOWNSCALED,
KEY_STATUS_PENDING,
RELEASED,
};
// See media::HdcpVersion
[Native]
enum HdcpVersion;
// See media::CdmConfig
[Native]
struct CdmConfig;
// Transport layer of media::CdmPromise (see media/base/cdm_promise.h).
// - When |success| is true, the promise is resolved and all other fields should
// be ignored.
// - When |success| is false, the promise is rejected with |exception|,
// |system_code| and |error_message|.
struct CdmPromiseResult {
// See media::CdmPromise::Exception
[Native]
enum Exception;
bool success;
Exception exception;
uint32 system_code;
string error_message;
};
// Transport layer of media::CdmKeyInformation (see
// media/base/cdm_key_information.h). It is used to specify a key_id and it's
// associated status.
struct CdmKeyInformation {
array<uint8> key_id;
CdmKeyStatus status;
uint32 system_code;
};
// An interface that represents a CDM in the Encrypted Media Extensions (EME)
// spec (https://w3c.github.io/encrypted-media/).
// - Process Model: For security reason, the CDM is running in its own process
// as the CDM contains untrusted code and handles arbitrary data. The exact
// process model varies on various platforms. For example, on desktop, the CDM
// runs in a CDM (utility) process. On Android, the CDM runs in the GPU process.
// The client of the CDM is MojoCdm, which runs in the render process.
// - Session ID: Passed as `session_id` in some methods, it is a unique string
// identifier generated by the CDM that can be used to identify CDM sessions.
// A ContentDecryptionModule can manage mutilple sessions per the EME spec. See
// https://www.w3.org/TR/encrypted-media/#session-id.
// - Also see media/base/content_decryption_module.h and media/mojo/README.md.
interface ContentDecryptionModule {
// Sets ContentDecryptionModuleClient. Must be called before any other calls.
// Use associated interface to ensure ordering, e.g. events on the client
// interface and promise fulfillment.
SetClient(pending_associated_remote<ContentDecryptionModuleClient> client);
// Provides a server certificate to be used to encrypt messages to the
// license server.
SetServerCertificate(array<uint8> certificate_data)
=> (CdmPromiseResult result);
// Gets the key status if there's a hypothetical key that requires the
// |min_hdcp_version|. Resolve the |promise| with the |key_status| after the
// operation completes. Reject the |promise| if this operation is not
// supported or unexpected error happened.
GetStatusForPolicy(HdcpVersion min_hdcp_version)
=> (CdmPromiseResult result, CdmKeyStatus key_status);
// Creates a session with the |init_data_type|, |init_data| and |session_type|
// provided. If |result.success| is false, the output |session_id| will be
// empty.
CreateSessionAndGenerateRequest(CdmSessionType session_type,
EmeInitDataType init_data_type,
array<uint8> init_data)
=> (CdmPromiseResult result, string session_id);
// Loads the session associated with |session_id| and |session_type|.
// Combinations of |result.success| and |session_id| means:
// (true, non-empty) : Session successfully loaded.
// (true, empty) : Session not found.
// (false, non-empty): N/A; this combination is not allowed.
// (false, empty) : Unexpected error. See other fields in |result|.
LoadSession(CdmSessionType session_type, string session_id)
=> (CdmPromiseResult result, string session_id);
// Updates a session specified by |session_id| with |response|.
UpdateSession(string session_id, array<uint8> response)
=> (CdmPromiseResult result);
// Closes the session specified by |session_id|.
CloseSession(string session_id) => (CdmPromiseResult result);
// Removes stored session data associated with the active session specified by
// |session_id|.
RemoveSession(string session_id) => (CdmPromiseResult result);
};
// Session callbacks. The implementation is MojoCdm that runs in the render
// process. The caller is the remote CDM (mojom::ContentDecryptionModule). See
// comments above for more details on CDM process model and session ID.
// Also see media/base/content_decryption_module.h and media/mojo/README.md.
interface ContentDecryptionModuleClient {
// Called when the CDM needs to queue a message event to the session object.
// See http://w3c.github.io/encrypted-media/#dom-evt-message
OnSessionMessage(string session_id, CdmMessageType message_type,
array<uint8> message);
// Called when the session specified by |session_id| is closed. Note that the
// CDM may close a session at any point, e.g. in response to `CloseSession()`,
// when the session is no longer needed, or when system resources are lost.
// After `OnSessionClosed()` is called for a `session_id`, no methods in this
// interface should be called with the same `session_id`.
// See http://w3c.github.io/encrypted-media/#session-closed
OnSessionClosed(string session_id, CdmSessionClosedReason reason);
// Called when there has been a change in the keys in the session or their
// status.
// See http://w3c.github.io/encrypted-media/#dom-evt-keystatuseschange
OnSessionKeysChange(string session_id, bool has_additional_usable_key,
array<CdmKeyInformation> keys_info);
// Called when the CDM changes the expiration time of a session.
// See http://w3c.github.io/encrypted-media/#update-expiration
// |new_expiry_time_sec| is the number of seconds since epoch (Jan 1, 1970).
OnSessionExpirationUpdate(string session_id, double new_expiry_time_sec);
};
// Context associated with the remote CDM, mostly to populate media::CdmContext.
struct CdmContext {
// An ID that can be used to locate the CDM at the remote side.
mojo_base.mojom.UnguessableToken cdm_id;
// The remote Decryptor if the CDM implementation provides one.
pending_remote<Decryptor>? decryptor;
// Whether MediaFoundationRenderer is required by the CDM.
[EnableIf=is_win]
bool requires_media_foundation_renderer;
};
// Factory interface used for creating ContentDecryptionModule instances.
interface CdmFactory {
// Creates a CDM based on the `cdm_config` provided. The `key_system` in
// `cdm_config` is a generic term for a decryption mechanism and/or content
// protection provider. It should be a reverse domain name,
// e.g. "com.example.somesystem". However, this call may be initiated by an
// untrusted process (e.g. renderer), so the implementation must fully
// validate `key_system` before creating the CDM. `cdm_config` also specifies
// other properties of the CDM which may influence creation. Upon failure,
// the returned `cdm` and `cdm_context` will be null, and `status`
// will specify the error reason. Upon success, `cdm` and `cdm_context` will
// be valid, and `status` will be CreateCdmStatus::kSuccess.
CreateCdm(CdmConfig cdm_config) =>
(pending_remote<ContentDecryptionModule>? cdm,
CdmContext? cdm_context,
CreateCdmStatus status);
};