| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/blink/encrypted_media_player_support.h" | 5 #include "media/blink/encrypted_media_player_support.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/numerics/safe_conversions.h" | 12 #include "base/numerics/safe_conversions.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "media/base/bind_to_current_loop.h" | 16 #include "media/base/bind_to_current_loop.h" |
| 17 #include "media/base/key_systems.h" | 17 #include "media/base/key_systems.h" |
| 18 #include "media/blink/webcontentdecryptionmodule_impl.h" | 18 #include "media/blink/webcontentdecryptionmodule_impl.h" |
| 19 #include "third_party/WebKit/public/platform/WebContentDecryptionModule.h" | 19 #include "third_party/WebKit/public/platform/WebContentDecryptionModule.h" |
| 20 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" | 20 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" |
| 21 #include "third_party/WebKit/public/web/WebDocument.h" | 21 #include "third_party/WebKit/public/web/WebDocument.h" |
| 22 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 22 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 23 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" | |
| 24 | 23 |
| 25 using blink::WebMediaPlayer; | 24 using blink::WebMediaPlayer; |
| 26 using blink::WebMediaPlayerClient; | 25 using blink::WebMediaPlayerClient; |
| 27 using blink::WebString; | 26 using blink::WebString; |
| 28 | 27 |
| 29 namespace media { | 28 namespace media { |
| 30 | 29 |
| 31 #define BIND_TO_RENDER_LOOP(function) \ | 30 #define BIND_TO_RENDER_LOOP(function) \ |
| 32 (BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) | 31 (BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) |
| 33 | 32 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 const WebString& key_system, | 130 const WebString& key_system, |
| 132 const unsigned char* init_data, | 131 const unsigned char* init_data, |
| 133 unsigned init_data_length) { | 132 unsigned init_data_length) { |
| 134 DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": " | 133 DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": " |
| 135 << std::string(reinterpret_cast<const char*>(init_data), | 134 << std::string(reinterpret_cast<const char*>(init_data), |
| 136 static_cast<size_t>(init_data_length)); | 135 static_cast<size_t>(init_data_length)); |
| 137 | 136 |
| 138 std::string ascii_key_system = | 137 std::string ascii_key_system = |
| 139 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system)); | 138 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system)); |
| 140 | 139 |
| 141 WebMediaPlayer::MediaKeyException e = | 140 WebMediaPlayer::MediaKeyException e = GenerateKeyRequestInternal( |
| 142 GenerateKeyRequestInternal(frame, ascii_key_system, init_data, | 141 frame, ascii_key_system, init_data, init_data_length); |
| 143 init_data_length); | |
| 144 ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e); | 142 ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e); |
| 145 return e; | 143 return e; |
| 146 } | 144 } |
| 147 | 145 |
| 148 WebMediaPlayer::MediaKeyException | 146 WebMediaPlayer::MediaKeyException |
| 149 EncryptedMediaPlayerSupport::GenerateKeyRequestInternal( | 147 EncryptedMediaPlayerSupport::GenerateKeyRequestInternal( |
| 150 blink::WebLocalFrame* frame, | 148 blink::WebLocalFrame* frame, |
| 151 const std::string& key_system, | 149 const std::string& key_system, |
| 152 const unsigned char* init_data, | 150 const unsigned char* init_data, |
| 153 unsigned init_data_length) { | 151 unsigned init_data_length) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 178 | 176 |
| 179 current_key_system_ = key_system; | 177 current_key_system_ = key_system; |
| 180 } else if (key_system != current_key_system_) { | 178 } else if (key_system != current_key_system_) { |
| 181 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; | 179 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; |
| 182 } | 180 } |
| 183 | 181 |
| 184 std::string init_data_type = init_data_type_; | 182 std::string init_data_type = init_data_type_; |
| 185 if (init_data_type.empty()) | 183 if (init_data_type.empty()) |
| 186 init_data_type = GuessInitDataType(init_data, init_data_length); | 184 init_data_type = GuessInitDataType(init_data, init_data_length); |
| 187 | 185 |
| 188 // TODO(xhwang): We assume all streams are from the same container (thus have | 186 if (!proxy_decryptor_->GenerateKeyRequest(init_data_type, init_data, |
| 189 // the same "type") for now. In the future, the "type" should be passed down | 187 init_data_length)) { |
| 190 // from the application. | |
| 191 if (!proxy_decryptor_->GenerateKeyRequest( | |
| 192 init_data_type, init_data, init_data_length)) { | |
| 193 current_key_system_.clear(); | 188 current_key_system_.clear(); |
| 194 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 189 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 195 } | 190 } |
| 196 | 191 |
| 197 return WebMediaPlayer::MediaKeyExceptionNoError; | 192 return WebMediaPlayer::MediaKeyExceptionNoError; |
| 198 } | 193 } |
| 199 | 194 |
| 200 WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupport::AddKey( | 195 WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupport::AddKey( |
| 201 const WebString& key_system, | 196 const WebString& key_system, |
| 202 const unsigned char* key, | 197 const unsigned char* key, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 if (!IsConcreteSupportedKeySystem(key_system)) | 266 if (!IsConcreteSupportedKeySystem(key_system)) |
| 272 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 267 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 273 | 268 |
| 274 if (current_key_system_.empty() || key_system != current_key_system_) | 269 if (current_key_system_.empty() || key_system != current_key_system_) |
| 275 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; | 270 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; |
| 276 | 271 |
| 277 proxy_decryptor_->CancelKeyRequest(session_id); | 272 proxy_decryptor_->CancelKeyRequest(session_id); |
| 278 return WebMediaPlayer::MediaKeyExceptionNoError; | 273 return WebMediaPlayer::MediaKeyExceptionNoError; |
| 279 } | 274 } |
| 280 | 275 |
| 281 Demuxer::NeedKeyCB EncryptedMediaPlayerSupport::CreateNeedKeyCB() { | 276 void EncryptedMediaPlayerSupport::SetInitDataType( |
| 282 return BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnNeedKey); | 277 const std::string& init_data_type) { |
| 278 DCHECK(!init_data_type.empty()); |
| 279 DLOG_IF(WARNING, |
| 280 !init_data_type_.empty() && init_data_type != init_data_type_) |
| 281 << "Mixed init data type not supported. The new type is ignored."; |
| 282 if (init_data_type_.empty()) |
| 283 init_data_type_ = init_data_type; |
| 283 } | 284 } |
| 284 | 285 |
| 285 void EncryptedMediaPlayerSupport::OnPipelineDecryptError() { | 286 void EncryptedMediaPlayerSupport::OnPipelineDecryptError() { |
| 286 EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1); | 287 EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1); |
| 287 } | 288 } |
| 288 | 289 |
| 289 void EncryptedMediaPlayerSupport::OnNeedKey( | |
| 290 const std::string& type, | |
| 291 const std::vector<uint8>& init_data) { | |
| 292 // Do not fire NeedKey event if encrypted media is not enabled. | |
| 293 if (!blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled() && | |
| 294 !blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) { | |
| 295 return; | |
| 296 } | |
| 297 | |
| 298 UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1); | |
| 299 | |
| 300 DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_); | |
| 301 if (init_data_type_.empty()) | |
| 302 init_data_type_ = type; | |
| 303 | |
| 304 const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0]; | |
| 305 client_->encrypted(WebString::fromUTF8(type), init_data_ptr, | |
| 306 base::saturated_cast<unsigned int>(init_data.size())); | |
| 307 } | |
| 308 | |
| 309 void EncryptedMediaPlayerSupport::OnKeyAdded(const std::string& session_id) { | 290 void EncryptedMediaPlayerSupport::OnKeyAdded(const std::string& session_id) { |
| 310 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); | 291 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); |
| 311 client_->keyAdded( | 292 client_->keyAdded( |
| 312 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), | 293 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), |
| 313 WebString::fromUTF8(session_id)); | 294 WebString::fromUTF8(session_id)); |
| 314 } | 295 } |
| 315 | 296 |
| 316 void EncryptedMediaPlayerSupport::OnKeyError(const std::string& session_id, | 297 void EncryptedMediaPlayerSupport::OnKeyError(const std::string& session_id, |
| 317 MediaKeys::KeyError error_code, | 298 MediaKeys::KeyError error_code, |
| 318 uint32 system_code) { | 299 uint32 system_code) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 342 | 323 |
| 343 client_->keyMessage( | 324 client_->keyMessage( |
| 344 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), | 325 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), |
| 345 WebString::fromUTF8(session_id), | 326 WebString::fromUTF8(session_id), |
| 346 message.empty() ? NULL : &message[0], | 327 message.empty() ? NULL : &message[0], |
| 347 base::saturated_cast<unsigned int>(message.size()), | 328 base::saturated_cast<unsigned int>(message.size()), |
| 348 destination_url); | 329 destination_url); |
| 349 } | 330 } |
| 350 | 331 |
| 351 } // namespace media | 332 } // namespace media |
| OLD | NEW |