| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 set_cdm_context_cb_(set_cdm_context_cb) { | 121 set_cdm_context_cb_(set_cdm_context_cb) { |
| 123 } | 122 } |
| 124 | 123 |
| 125 EncryptedMediaPlayerSupport::~EncryptedMediaPlayerSupport() { | 124 EncryptedMediaPlayerSupport::~EncryptedMediaPlayerSupport() { |
| 126 } | 125 } |
| 127 | 126 |
| 128 WebMediaPlayer::MediaKeyException | 127 WebMediaPlayer::MediaKeyException |
| 129 EncryptedMediaPlayerSupport::GenerateKeyRequest( | 128 EncryptedMediaPlayerSupport::GenerateKeyRequest( |
| 130 blink::WebLocalFrame* frame, | 129 blink::WebLocalFrame* frame, |
| 131 const WebString& key_system, | 130 const WebString& key_system, |
| 131 const std::string& init_data_type, |
| 132 const unsigned char* init_data, | 132 const unsigned char* init_data, |
| 133 unsigned init_data_length) { | 133 unsigned init_data_length) { |
| 134 DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": " | 134 DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": " |
| 135 << std::string(reinterpret_cast<const char*>(init_data), | 135 << std::string(reinterpret_cast<const char*>(init_data), |
| 136 static_cast<size_t>(init_data_length)); | 136 static_cast<size_t>(init_data_length)); |
| 137 | 137 |
| 138 std::string ascii_key_system = | 138 std::string ascii_key_system = |
| 139 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system)); | 139 GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system)); |
| 140 | 140 |
| 141 WebMediaPlayer::MediaKeyException e = | 141 WebMediaPlayer::MediaKeyException e = GenerateKeyRequestInternal( |
| 142 GenerateKeyRequestInternal(frame, ascii_key_system, init_data, | 142 frame, ascii_key_system, init_data_type, init_data, init_data_length); |
| 143 init_data_length); | |
| 144 ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e); | 143 ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e); |
| 145 return e; | 144 return e; |
| 146 } | 145 } |
| 147 | 146 |
| 148 WebMediaPlayer::MediaKeyException | 147 WebMediaPlayer::MediaKeyException |
| 149 EncryptedMediaPlayerSupport::GenerateKeyRequestInternal( | 148 EncryptedMediaPlayerSupport::GenerateKeyRequestInternal( |
| 150 blink::WebLocalFrame* frame, | 149 blink::WebLocalFrame* frame, |
| 151 const std::string& key_system, | 150 const std::string& key_system, |
| 151 const std::string& init_data_type, |
| 152 const unsigned char* init_data, | 152 const unsigned char* init_data, |
| 153 unsigned init_data_length) { | 153 unsigned init_data_length) { |
| 154 if (!IsConcreteSupportedKeySystem(key_system)) | 154 if (!IsConcreteSupportedKeySystem(key_system)) |
| 155 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 155 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 156 | 156 |
| 157 // We do not support run-time switching between key systems for now. | 157 // We do not support run-time switching between key systems for now. |
| 158 if (current_key_system_.empty()) { | 158 if (current_key_system_.empty()) { |
| 159 if (!proxy_decryptor_) { | 159 if (!proxy_decryptor_) { |
| 160 proxy_decryptor_.reset(new ProxyDecryptor( | 160 proxy_decryptor_.reset(new ProxyDecryptor( |
| 161 BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyAdded), | 161 BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyAdded), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 174 base::ResetAndReturn(&set_cdm_context_cb_) | 174 base::ResetAndReturn(&set_cdm_context_cb_) |
| 175 .Run(proxy_decryptor_->GetCdmContext(), | 175 .Run(proxy_decryptor_->GetCdmContext(), |
| 176 base::Bind(&IgnoreCdmAttached)); | 176 base::Bind(&IgnoreCdmAttached)); |
| 177 } | 177 } |
| 178 | 178 |
| 179 current_key_system_ = key_system; | 179 current_key_system_ = key_system; |
| 180 } else if (key_system != current_key_system_) { | 180 } else if (key_system != current_key_system_) { |
| 181 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; | 181 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; |
| 182 } | 182 } |
| 183 | 183 |
| 184 std::string init_data_type = init_data_type_; | 184 std::string local_init_data_type = init_data_type; |
| 185 if (init_data_type.empty()) | 185 if (local_init_data_type.empty()) |
| 186 init_data_type = GuessInitDataType(init_data, init_data_length); | 186 local_init_data_type = GuessInitDataType(init_data, init_data_length); |
| 187 | 187 |
| 188 // TODO(xhwang): We assume all streams are from the same container (thus have | |
| 189 // the same "type") for now. In the future, the "type" should be passed down | |
| 190 // from the application. | |
| 191 if (!proxy_decryptor_->GenerateKeyRequest( | 188 if (!proxy_decryptor_->GenerateKeyRequest( |
| 192 init_data_type, init_data, init_data_length)) { | 189 local_init_data_type, init_data, init_data_length)) { |
| 193 current_key_system_.clear(); | 190 current_key_system_.clear(); |
| 194 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 191 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 195 } | 192 } |
| 196 | 193 |
| 197 return WebMediaPlayer::MediaKeyExceptionNoError; | 194 return WebMediaPlayer::MediaKeyExceptionNoError; |
| 198 } | 195 } |
| 199 | 196 |
| 200 WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupport::AddKey( | 197 WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupport::AddKey( |
| 201 const WebString& key_system, | 198 const WebString& key_system, |
| 202 const unsigned char* key, | 199 const unsigned char* key, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 if (!IsConcreteSupportedKeySystem(key_system)) | 268 if (!IsConcreteSupportedKeySystem(key_system)) |
| 272 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 269 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 273 | 270 |
| 274 if (current_key_system_.empty() || key_system != current_key_system_) | 271 if (current_key_system_.empty() || key_system != current_key_system_) |
| 275 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; | 272 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; |
| 276 | 273 |
| 277 proxy_decryptor_->CancelKeyRequest(session_id); | 274 proxy_decryptor_->CancelKeyRequest(session_id); |
| 278 return WebMediaPlayer::MediaKeyExceptionNoError; | 275 return WebMediaPlayer::MediaKeyExceptionNoError; |
| 279 } | 276 } |
| 280 | 277 |
| 281 Demuxer::NeedKeyCB EncryptedMediaPlayerSupport::CreateNeedKeyCB() { | |
| 282 return BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnNeedKey); | |
| 283 } | |
| 284 | |
| 285 void EncryptedMediaPlayerSupport::OnPipelineDecryptError() { | 278 void EncryptedMediaPlayerSupport::OnPipelineDecryptError() { |
| 286 EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1); | 279 EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1); |
| 287 } | 280 } |
| 288 | 281 |
| 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) { | 282 void EncryptedMediaPlayerSupport::OnKeyAdded(const std::string& session_id) { |
| 310 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); | 283 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); |
| 311 client_->keyAdded( | 284 client_->keyAdded( |
| 312 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), | 285 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), |
| 313 WebString::fromUTF8(session_id)); | 286 WebString::fromUTF8(session_id)); |
| 314 } | 287 } |
| 315 | 288 |
| 316 void EncryptedMediaPlayerSupport::OnKeyError(const std::string& session_id, | 289 void EncryptedMediaPlayerSupport::OnKeyError(const std::string& session_id, |
| 317 MediaKeys::KeyError error_code, | 290 MediaKeys::KeyError error_code, |
| 318 uint32 system_code) { | 291 uint32 system_code) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 342 | 315 |
| 343 client_->keyMessage( | 316 client_->keyMessage( |
| 344 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), | 317 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), |
| 345 WebString::fromUTF8(session_id), | 318 WebString::fromUTF8(session_id), |
| 346 message.empty() ? NULL : &message[0], | 319 message.empty() ? NULL : &message[0], |
| 347 base::saturated_cast<unsigned int>(message.size()), | 320 base::saturated_cast<unsigned int>(message.size()), |
| 348 destination_url); | 321 destination_url); |
| 349 } | 322 } |
| 350 | 323 |
| 351 } // namespace media | 324 } // namespace media |
| OLD | NEW |