Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(645)

Side by Side Diff: media/blink/encrypted_media_player_support.cc

Issue 1712903002: Remove prefixed EME. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix isRenewalMessage() in browser tests. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/blink/encrypted_media_player_support.h ('k') | media/blink/media_blink.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/blink/encrypted_media_player_support.h"
6
7 #include <stddef.h>
8
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/metrics/histogram.h"
12 #include "base/numerics/safe_conversions.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "media/base/bind_to_current_loop.h"
17 #include "media/base/key_systems.h"
18 #include "media/blink/webcontentdecryptionmodule_impl.h"
19 #include "third_party/WebKit/public/platform/URLConversion.h"
20 #include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
21 #include "third_party/WebKit/public/platform/WebMediaPlayerEncryptedMediaClient. h"
22 #include "third_party/WebKit/public/web/WebDocument.h"
23 #include "third_party/WebKit/public/web/WebLocalFrame.h"
24
25 using blink::WebMediaPlayer;
26 using blink::WebMediaPlayerEncryptedMediaClient;
27 using blink::WebString;
28
29 namespace media {
30
31 #define BIND_TO_RENDER_LOOP(function) \
32 (BindToCurrentLoop(base::Bind(function, AsWeakPtr())))
33
34 #define BIND_TO_RENDER_LOOP1(function, arg1) \
35 (BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1)))
36
37 // Prefix for histograms related to Encrypted Media Extensions.
38 static const char* kMediaEme = "Media.EME.";
39
40 // Convert a WebString to ASCII, falling back on an empty string in the case
41 // of a non-ASCII string.
42 static std::string ToASCIIOrEmpty(const WebString& string) {
43 return base::IsStringASCII(string)
44 ? base::UTF16ToASCII(base::StringPiece16(string))
45 : std::string();
46 }
47
48 // Helper functions to report media EME related stats to UMA. They follow the
49 // convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
50 // UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
51 // that UMA_* macros require the names to be constant throughout the process'
52 // lifetime.
53 static void EmeUMAHistogramEnumeration(const std::string& key_system,
54 const std::string& method,
55 int sample,
56 int boundary_value) {
57 base::LinearHistogram::FactoryGet(
58 kMediaEme + GetKeySystemNameForUMA(key_system) + "." + method,
59 1, boundary_value, boundary_value + 1,
60 base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
61 }
62
63 static void EmeUMAHistogramCounts(const std::string& key_system,
64 const std::string& method,
65 int sample) {
66 // Use the same parameters as UMA_HISTOGRAM_COUNTS.
67 base::Histogram::FactoryGet(
68 kMediaEme + GetKeySystemNameForUMA(key_system) + "." + method,
69 1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
70 }
71
72 // Helper enum for reporting generateKeyRequest/addKey histograms.
73 enum MediaKeyException {
74 kUnknownResultId,
75 kSuccess,
76 kKeySystemNotSupported,
77 kInvalidPlayerState,
78 kMaxMediaKeyException
79 };
80
81 static MediaKeyException MediaKeyExceptionForUMA(
82 WebMediaPlayer::MediaKeyException e) {
83 switch (e) {
84 case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
85 return kKeySystemNotSupported;
86 case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
87 return kInvalidPlayerState;
88 case WebMediaPlayer::MediaKeyExceptionNoError:
89 return kSuccess;
90 default:
91 return kUnknownResultId;
92 }
93 }
94
95 // Helper for converting |key_system| name and exception |e| to a pair of enum
96 // values from above, for reporting to UMA.
97 static void ReportMediaKeyExceptionToUMA(const std::string& method,
98 const std::string& key_system,
99 WebMediaPlayer::MediaKeyException e) {
100 MediaKeyException result_id = MediaKeyExceptionForUMA(e);
101 DCHECK_NE(result_id, kUnknownResultId) << e;
102 EmeUMAHistogramEnumeration(
103 key_system, method, result_id, kMaxMediaKeyException);
104 }
105
106 // Guess the type of |init_data|. This is only used to handle some corner cases
107 // so we keep it as simple as possible without breaking major use cases.
108 static EmeInitDataType GuessInitDataType(const unsigned char* init_data,
109 unsigned init_data_length) {
110 #if defined(USE_PROPRIETARY_CODECS)
111 // Most WebM files use KeyId of 16 bytes. CENC init data is always >16 bytes.
112 if (init_data_length > 16)
113 return EmeInitDataType::CENC;
114 #endif
115
116 return EmeInitDataType::WEBM;
117 }
118
119 EncryptedMediaPlayerSupport::EncryptedMediaPlayerSupport(
120 CdmFactory* cdm_factory,
121 WebMediaPlayerEncryptedMediaClient* client,
122 MediaPermission* media_permission,
123 const CdmContextReadyCB& cdm_context_ready_cb)
124 : cdm_factory_(cdm_factory),
125 client_(client),
126 media_permission_(media_permission),
127 init_data_type_(EmeInitDataType::UNKNOWN),
128 cdm_context_ready_cb_(cdm_context_ready_cb) {
129 }
130
131 EncryptedMediaPlayerSupport::~EncryptedMediaPlayerSupport() {
132 }
133
134 WebMediaPlayer::MediaKeyException
135 EncryptedMediaPlayerSupport::GenerateKeyRequest(
136 blink::WebLocalFrame* frame,
137 const WebString& key_system,
138 const unsigned char* init_data,
139 unsigned init_data_length) {
140 DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": "
141 << std::string(reinterpret_cast<const char*>(init_data),
142 static_cast<size_t>(init_data_length));
143
144 std::string ascii_key_system =
145 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
146
147 WebMediaPlayer::MediaKeyException e = GenerateKeyRequestInternal(
148 frame, ascii_key_system, init_data, init_data_length);
149 ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e);
150 return e;
151 }
152
153 WebMediaPlayer::MediaKeyException
154 EncryptedMediaPlayerSupport::GenerateKeyRequestInternal(
155 blink::WebLocalFrame* frame,
156 const std::string& key_system,
157 const unsigned char* init_data,
158 unsigned init_data_length) {
159 if (!PrefixedIsSupportedConcreteKeySystem(key_system))
160 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
161
162 // |use_hw_secure_codecs| is only supported on Android, and Android (WMPA)
163 // does not use EncryptedMediaPlayerSupport.
164 bool use_hw_secure_codecs = false;
165
166 if (!proxy_decryptor_) {
167 DCHECK(current_key_system_.empty());
168 DCHECK(!cdm_context_ready_cb_.is_null());
169 proxy_decryptor_.reset(new ProxyDecryptor(
170 media_permission_, use_hw_secure_codecs,
171 BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyAdded),
172 BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyError),
173 BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyMessage)));
174
175 GURL security_origin(
176 blink::WebStringToGURL(frame->document().securityOrigin().toString()));
177 proxy_decryptor_->CreateCdm(cdm_factory_, key_system, security_origin,
178 cdm_context_ready_cb_);
179 current_key_system_ = key_system;
180 }
181
182 // We do not support run-time switching between key systems for now.
183 DCHECK(!current_key_system_.empty());
184 if (key_system != current_key_system_)
185 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
186
187 EmeInitDataType init_data_type = init_data_type_;
188 if (init_data_type == EmeInitDataType::UNKNOWN)
189 init_data_type = GuessInitDataType(init_data, init_data_length);
190
191 proxy_decryptor_->GenerateKeyRequest(init_data_type, init_data,
192 init_data_length);
193
194 return WebMediaPlayer::MediaKeyExceptionNoError;
195 }
196
197 WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupport::AddKey(
198 const WebString& key_system,
199 const unsigned char* key,
200 unsigned key_length,
201 const unsigned char* init_data,
202 unsigned init_data_length,
203 const WebString& session_id) {
204 DVLOG(1) << "addKey: " << base::string16(key_system) << ": "
205 << std::string(reinterpret_cast<const char*>(key),
206 static_cast<size_t>(key_length)) << ", "
207 << std::string(reinterpret_cast<const char*>(init_data),
208 static_cast<size_t>(init_data_length)) << " ["
209 << base::string16(session_id) << "]";
210
211 std::string ascii_key_system =
212 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
213 std::string ascii_session_id = ToASCIIOrEmpty(session_id);
214
215 WebMediaPlayer::MediaKeyException e = AddKeyInternal(ascii_key_system,
216 key,
217 key_length,
218 init_data,
219 init_data_length,
220 ascii_session_id);
221 ReportMediaKeyExceptionToUMA("addKey", ascii_key_system, e);
222 return e;
223 }
224
225 WebMediaPlayer::MediaKeyException
226 EncryptedMediaPlayerSupport::AddKeyInternal(
227 const std::string& key_system,
228 const unsigned char* key,
229 unsigned key_length,
230 const unsigned char* init_data,
231 unsigned init_data_length,
232 const std::string& session_id) {
233 DCHECK(key);
234 DCHECK_GT(key_length, 0u);
235
236 if (!PrefixedIsSupportedConcreteKeySystem(key_system))
237 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
238
239 if (current_key_system_.empty() || key_system != current_key_system_)
240 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
241
242 proxy_decryptor_->AddKey(
243 key, key_length, init_data, init_data_length, session_id);
244 return WebMediaPlayer::MediaKeyExceptionNoError;
245 }
246
247 WebMediaPlayer::MediaKeyException
248 EncryptedMediaPlayerSupport::CancelKeyRequest(
249 const WebString& key_system,
250 const WebString& session_id) {
251 DVLOG(1) << "cancelKeyRequest: " << base::string16(key_system) << ": "
252 << " [" << base::string16(session_id) << "]";
253
254 std::string ascii_key_system =
255 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
256 std::string ascii_session_id = ToASCIIOrEmpty(session_id);
257
258 WebMediaPlayer::MediaKeyException e =
259 CancelKeyRequestInternal(ascii_key_system, ascii_session_id);
260 ReportMediaKeyExceptionToUMA("cancelKeyRequest", ascii_key_system, e);
261 return e;
262 }
263
264 WebMediaPlayer::MediaKeyException
265 EncryptedMediaPlayerSupport::CancelKeyRequestInternal(
266 const std::string& key_system,
267 const std::string& session_id) {
268 if (!PrefixedIsSupportedConcreteKeySystem(key_system))
269 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
270
271 if (current_key_system_.empty() || key_system != current_key_system_)
272 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
273
274 proxy_decryptor_->CancelKeyRequest(session_id);
275 return WebMediaPlayer::MediaKeyExceptionNoError;
276 }
277
278 void EncryptedMediaPlayerSupport::SetInitDataType(
279 EmeInitDataType init_data_type) {
280 DCHECK(init_data_type != EmeInitDataType::UNKNOWN);
281 DLOG_IF(WARNING, init_data_type_ != EmeInitDataType::UNKNOWN &&
282 init_data_type != init_data_type_)
283 << "Mixed init data type not supported. The new type is ignored.";
284 if (init_data_type_ == EmeInitDataType::UNKNOWN)
285 init_data_type_ = init_data_type;
286 }
287
288 void EncryptedMediaPlayerSupport::OnKeyAdded(const std::string& session_id) {
289 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1);
290 client_->keyAdded(
291 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
292 WebString::fromUTF8(session_id));
293 }
294
295 void EncryptedMediaPlayerSupport::OnKeyError(const std::string& session_id,
296 MediaKeys::KeyError error_code,
297 uint32_t system_code) {
298 EmeUMAHistogramEnumeration(current_key_system_, "KeyError",
299 error_code, MediaKeys::kMaxKeyError);
300
301 uint16_t short_system_code = 0;
302 if (system_code > std::numeric_limits<uint16_t>::max()) {
303 LOG(WARNING) << "system_code exceeds unsigned short limit.";
304 short_system_code = std::numeric_limits<uint16_t>::max();
305 } else {
306 short_system_code = static_cast<uint16_t>(system_code);
307 }
308
309 client_->keyError(
310 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
311 WebString::fromUTF8(session_id),
312 static_cast<WebMediaPlayerEncryptedMediaClient::MediaKeyErrorCode>(
313 error_code),
314 short_system_code);
315 }
316
317 void EncryptedMediaPlayerSupport::OnKeyMessage(
318 const std::string& session_id,
319 const std::vector<uint8_t>& message,
320 const GURL& destination_url) {
321 DCHECK(destination_url.is_empty() || destination_url.is_valid());
322
323 client_->keyMessage(
324 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
325 WebString::fromUTF8(session_id),
326 message.empty() ? NULL : &message[0],
327 base::saturated_cast<unsigned int>(message.size()),
328 destination_url);
329 }
330
331 } // namespace media
OLDNEW
« no previous file with comments | « media/blink/encrypted_media_player_support.h ('k') | media/blink/media_blink.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698