| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/base/key_systems.h" | 5 #include "media/base/key_systems.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 // for real key system names. Use is discouraged. | 162 // for real key system names. Use is discouraged. |
| 163 const char kExcludedPrefix[] = "x-"; | 163 const char kExcludedPrefix[] = "x-"; |
| 164 return base::StartsWith(key_system, kExcludedPrefix, | 164 return base::StartsWith(key_system, kExcludedPrefix, |
| 165 base::CompareCase::SENSITIVE); | 165 base::CompareCase::SENSITIVE); |
| 166 } | 166 } |
| 167 | 167 |
| 168 class KeySystemsImpl : public KeySystems { | 168 class KeySystemsImpl : public KeySystems { |
| 169 public: | 169 public: |
| 170 static KeySystemsImpl* GetInstance(); | 170 static KeySystemsImpl* GetInstance(); |
| 171 | 171 |
| 172 void UpdateIfNeeded(); | |
| 173 | |
| 174 std::string GetKeySystemNameForUMA(const std::string& key_system) const; | 172 std::string GetKeySystemNameForUMA(const std::string& key_system) const; |
| 175 | 173 |
| 176 bool UseAesDecryptor(const std::string& key_system) const; | 174 bool UseAesDecryptor(const std::string& key_system) const; |
| 177 | 175 |
| 178 #if BUILDFLAG(ENABLE_PEPPER_CDMS) | 176 #if BUILDFLAG(ENABLE_PEPPER_CDMS) |
| 179 std::string GetPepperType(const std::string& key_system) const; | 177 std::string GetPepperType(const std::string& key_system) const; |
| 180 #endif | 178 #endif |
| 181 | 179 |
| 182 // These two functions are for testing purpose only. | 180 // These two functions are for testing purpose only. |
| 183 void AddCodecMask(EmeMediaType media_type, | 181 void AddCodecMask(EmeMediaType media_type, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 225 |
| 228 void RegisterMimeType(const std::string& mime_type, EmeCodec codecs_mask); | 226 void RegisterMimeType(const std::string& mime_type, EmeCodec codecs_mask); |
| 229 bool IsValidMimeTypeCodecsCombination(const std::string& mime_type, | 227 bool IsValidMimeTypeCodecsCombination(const std::string& mime_type, |
| 230 SupportedCodecs codecs_mask) const; | 228 SupportedCodecs codecs_mask) const; |
| 231 | 229 |
| 232 typedef base::hash_map<std::string, std::unique_ptr<KeySystemProperties>> | 230 typedef base::hash_map<std::string, std::unique_ptr<KeySystemProperties>> |
| 233 KeySystemPropertiesMap; | 231 KeySystemPropertiesMap; |
| 234 typedef base::hash_map<std::string, SupportedCodecs> MimeTypeCodecsMap; | 232 typedef base::hash_map<std::string, SupportedCodecs> MimeTypeCodecsMap; |
| 235 typedef base::hash_map<std::string, EmeCodec> CodecsMap; | 233 typedef base::hash_map<std::string, EmeCodec> CodecsMap; |
| 236 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; | 234 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; |
| 237 typedef base::hash_map<std::string, std::string> KeySystemNameForUMAMap; | |
| 238 | 235 |
| 239 // TODO(sandersd): Separate container enum from codec mask value. | 236 // TODO(sandersd): Separate container enum from codec mask value. |
| 240 // http://crbug.com/417440 | 237 // http://crbug.com/417440 |
| 241 // Potentially pass EmeMediaType and a container enum. | 238 // Potentially pass EmeMediaType and a container enum. |
| 242 SupportedCodecs GetCodecMaskForMimeType( | 239 SupportedCodecs GetCodecMaskForMimeType( |
| 243 const std::string& container_mime_type) const; | 240 const std::string& container_mime_type) const; |
| 244 EmeCodec GetCodecForString(const std::string& codec) const; | 241 EmeCodec GetCodecForString(const std::string& codec) const; |
| 245 | 242 |
| 246 // Map from key system string to KeySystemProperties instance. | 243 // Map from key system string to KeySystemProperties instance. |
| 247 KeySystemPropertiesMap key_system_properties_map_; | 244 KeySystemPropertiesMap key_system_properties_map_; |
| 248 | 245 |
| 249 // This member should only be modified by RegisterMimeType(). | 246 // This member should only be modified by RegisterMimeType(). |
| 250 MimeTypeCodecsMap mime_type_to_codec_mask_map_; | 247 MimeTypeCodecsMap mime_type_to_codec_mask_map_; |
| 251 CodecsMap codec_string_map_; | 248 CodecsMap codec_string_map_; |
| 252 KeySystemNameForUMAMap key_system_name_for_uma_map_; | |
| 253 | 249 |
| 254 SupportedCodecs audio_codec_mask_; | 250 SupportedCodecs audio_codec_mask_; |
| 255 SupportedCodecs video_codec_mask_; | 251 SupportedCodecs video_codec_mask_; |
| 256 | 252 |
| 257 // Makes sure all methods are called from the same thread. | 253 // Makes sure all methods are called from the same thread. |
| 258 base::ThreadChecker thread_checker_; | 254 base::ThreadChecker thread_checker_; |
| 259 | 255 |
| 260 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); | 256 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); |
| 261 }; | 257 }; |
| 262 | 258 |
| 263 KeySystemsImpl* KeySystemsImpl::GetInstance() { | 259 KeySystemsImpl* KeySystemsImpl::GetInstance() { |
| 264 static KeySystemsImpl* key_systems = new KeySystemsImpl(); | 260 static KeySystemsImpl* key_systems = new KeySystemsImpl(); |
| 265 key_systems->UpdateIfNeeded(); | |
| 266 return key_systems; | 261 return key_systems; |
| 267 } | 262 } |
| 268 | 263 |
| 269 // Because we use a thread-safe static, the key systems info must be populated | 264 // Because we use a thread-safe static, the key systems info must be populated |
| 270 // when the instance is constructed. | 265 // when the instance is constructed. |
| 271 KeySystemsImpl::KeySystemsImpl() | 266 KeySystemsImpl::KeySystemsImpl() |
| 272 : audio_codec_mask_(EME_CODEC_AUDIO_ALL), | 267 : audio_codec_mask_(EME_CODEC_AUDIO_ALL), |
| 273 video_codec_mask_(EME_CODEC_VIDEO_ALL) { | 268 video_codec_mask_(EME_CODEC_VIDEO_ALL) { |
| 274 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { | 269 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { |
| 275 const std::string& name = kCodecStrings[i].name; | 270 const std::string& name = kCodecStrings[i].name; |
| 276 DCHECK(!codec_string_map_.count(name)); | 271 DCHECK(!codec_string_map_.count(name)); |
| 277 codec_string_map_[name] = kCodecStrings[i].type; | 272 codec_string_map_[name] = kCodecStrings[i].type; |
| 278 } | 273 } |
| 279 for (size_t i = 0; i < arraysize(kMimeTypeToCodecMasks); ++i) { | 274 for (size_t i = 0; i < arraysize(kMimeTypeToCodecMasks); ++i) { |
| 280 RegisterMimeType(kMimeTypeToCodecMasks[i].name, | 275 RegisterMimeType(kMimeTypeToCodecMasks[i].name, |
| 281 kMimeTypeToCodecMasks[i].type); | 276 kMimeTypeToCodecMasks[i].type); |
| 282 } | 277 } |
| 283 | 278 |
| 284 InitializeUMAInfo(); | |
| 285 | |
| 286 // Always update supported key systems during construction. | 279 // Always update supported key systems during construction. |
| 287 UpdateSupportedKeySystems(); | 280 UpdateSupportedKeySystems(); |
| 288 } | 281 } |
| 289 | 282 |
| 290 KeySystemsImpl::~KeySystemsImpl() { | 283 KeySystemsImpl::~KeySystemsImpl() { |
| 291 } | 284 } |
| 292 | 285 |
| 293 SupportedCodecs KeySystemsImpl::GetCodecMaskForMimeType( | 286 SupportedCodecs KeySystemsImpl::GetCodecMaskForMimeType( |
| 294 const std::string& container_mime_type) const { | 287 const std::string& container_mime_type) const { |
| 295 MimeTypeCodecsMap::const_iterator iter = | 288 MimeTypeCodecsMap::const_iterator iter = |
| 296 mime_type_to_codec_mask_map_.find(container_mime_type); | 289 mime_type_to_codec_mask_map_.find(container_mime_type); |
| 297 if (iter == mime_type_to_codec_mask_map_.end()) | 290 if (iter == mime_type_to_codec_mask_map_.end()) |
| 298 return EME_CODEC_NONE; | 291 return EME_CODEC_NONE; |
| 299 | 292 |
| 300 DCHECK(IsValidMimeTypeCodecsCombination(container_mime_type, iter->second)); | 293 DCHECK(IsValidMimeTypeCodecsCombination(container_mime_type, iter->second)); |
| 301 return iter->second; | 294 return iter->second; |
| 302 } | 295 } |
| 303 | 296 |
| 304 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { | 297 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { |
| 305 CodecsMap::const_iterator iter = codec_string_map_.find(codec); | 298 CodecsMap::const_iterator iter = codec_string_map_.find(codec); |
| 306 if (iter != codec_string_map_.end()) | 299 if (iter != codec_string_map_.end()) |
| 307 return iter->second; | 300 return iter->second; |
| 308 return EME_CODEC_NONE; | 301 return EME_CODEC_NONE; |
| 309 } | 302 } |
| 310 | 303 |
| 311 void KeySystemsImpl::InitializeUMAInfo() { | |
| 312 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 313 DCHECK(key_system_name_for_uma_map_.empty()); | |
| 314 | |
| 315 std::vector<KeySystemInfoForUMA> key_systems_info_for_uma; | |
| 316 if (GetMediaClient()) | |
| 317 GetMediaClient()->AddKeySystemsInfoForUMA(&key_systems_info_for_uma); | |
| 318 | |
| 319 for (const KeySystemInfoForUMA& info : key_systems_info_for_uma) { | |
| 320 key_system_name_for_uma_map_[info.key_system] = | |
| 321 info.key_system_name_for_uma; | |
| 322 } | |
| 323 | |
| 324 // Clear Key is always supported. | |
| 325 key_system_name_for_uma_map_[kClearKeyKeySystem] = | |
| 326 kClearKeyKeySystemNameForUMA; | |
| 327 } | |
| 328 | |
| 329 void KeySystemsImpl::UpdateIfNeeded() { | |
| 330 if (GetMediaClient() && GetMediaClient()->IsKeySystemsUpdateNeeded()) | |
| 331 UpdateSupportedKeySystems(); | |
| 332 } | |
| 333 | |
| 334 void KeySystemsImpl::UpdateSupportedKeySystems() { | 304 void KeySystemsImpl::UpdateSupportedKeySystems() { |
| 335 DCHECK(thread_checker_.CalledOnValidThread()); | 305 DCHECK(thread_checker_.CalledOnValidThread()); |
| 336 key_system_properties_map_.clear(); | 306 key_system_properties_map_.clear(); |
| 337 | 307 |
| 338 std::vector<std::unique_ptr<KeySystemProperties>> key_systems_properties; | 308 std::vector<std::unique_ptr<KeySystemProperties>> key_systems_properties; |
| 339 | 309 |
| 340 // Add key systems supported by the MediaClient implementation. | 310 // Add key systems supported by the MediaClient implementation. |
| 341 if (GetMediaClient()) | 311 if (GetMediaClient()) { |
| 342 GetMediaClient()->AddSupportedKeySystems(&key_systems_properties); | 312 GetMediaClient()->AddSupportedKeySystems(&key_systems_properties); |
| 313 } else { |
| 314 DVLOG(1) << __func__ << " No media client to provide key systems"; |
| 315 } |
| 343 | 316 |
| 344 // Clear Key is always supported. | 317 // Clear Key is always supported. |
| 345 key_systems_properties.emplace_back(new ClearKeyProperties()); | 318 key_systems_properties.emplace_back(new ClearKeyProperties()); |
| 346 | 319 |
| 347 AddSupportedKeySystems(&key_systems_properties); | 320 AddSupportedKeySystems(&key_systems_properties); |
| 348 } | 321 } |
| 349 | 322 |
| 350 // Returns whether distinctive identifiers and persistent state can be reliably | 323 // Returns whether distinctive identifiers and persistent state can be reliably |
| 351 // blocked for |properties| (and therefore be safely configurable). | 324 // blocked for |properties| (and therefore be safely configurable). |
| 352 static bool CanBlock(const KeySystemProperties& properties) { | 325 static bool CanBlock(const KeySystemProperties& properties) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 | 409 |
| 437 #if defined(OS_ANDROID) | 410 #if defined(OS_ANDROID) |
| 438 // Ensure that the renderer can access the decoders necessary to use the | 411 // Ensure that the renderer can access the decoders necessary to use the |
| 439 // key system. | 412 // key system. |
| 440 if (!properties->UseAesDecryptor() && !HasPlatformDecoderSupport()) { | 413 if (!properties->UseAesDecryptor() && !HasPlatformDecoderSupport()) { |
| 441 DLOG(WARNING) << properties->GetKeySystemName() << " not registered"; | 414 DLOG(WARNING) << properties->GetKeySystemName() << " not registered"; |
| 442 continue; | 415 continue; |
| 443 } | 416 } |
| 444 #endif // defined(OS_ANDROID) | 417 #endif // defined(OS_ANDROID) |
| 445 | 418 |
| 419 DVLOG(1) << __func__ |
| 420 << " Adding key system:" << properties->GetKeySystemName(); |
| 446 key_system_properties_map_[properties->GetKeySystemName()] = | 421 key_system_properties_map_[properties->GetKeySystemName()] = |
| 447 std::move(properties); | 422 std::move(properties); |
| 448 } | 423 } |
| 449 } | 424 } |
| 450 | 425 |
| 451 // Adds the MIME type with the codec mask after verifying the validity. | 426 // Adds the MIME type with the codec mask after verifying the validity. |
| 452 // Only this function should modify |mime_type_to_codec_mask_map_|. | 427 // Only this function should modify |mime_type_to_codec_mask_map_|. |
| 453 void KeySystemsImpl::RegisterMimeType(const std::string& mime_type, | 428 void KeySystemsImpl::RegisterMimeType(const std::string& mime_type, |
| 454 EmeCodec codecs_mask) { | 429 EmeCodec codecs_mask) { |
| 455 DCHECK(thread_checker_.CalledOnValidThread()); | 430 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 NOTREACHED(); | 462 NOTREACHED(); |
| 488 return false; | 463 return false; |
| 489 } | 464 } |
| 490 return key_system_iter->second->IsSupportedInitDataType(init_data_type); | 465 return key_system_iter->second->IsSupportedInitDataType(init_data_type); |
| 491 } | 466 } |
| 492 | 467 |
| 493 std::string KeySystemsImpl::GetKeySystemNameForUMA( | 468 std::string KeySystemsImpl::GetKeySystemNameForUMA( |
| 494 const std::string& key_system) const { | 469 const std::string& key_system) const { |
| 495 DCHECK(thread_checker_.CalledOnValidThread()); | 470 DCHECK(thread_checker_.CalledOnValidThread()); |
| 496 | 471 |
| 497 KeySystemNameForUMAMap::const_iterator iter = | 472 // Here we maintain a short list of known key systems to facilitate UMA |
| 498 key_system_name_for_uma_map_.find(key_system); | 473 // reporting. Mentioned key systems are not necessarily supported by |
| 499 if (iter == key_system_name_for_uma_map_.end()) | 474 // the current platform. |
| 500 return kUnknownKeySystemNameForUMA; | 475 if (key_system == kWidevineKeySystem) |
| 476 return kWidevineKeySystemNameForUMA; |
| 501 | 477 |
| 502 return iter->second; | 478 if (key_system == kClearKeyKeySystem) |
| 479 return kClearKeyKeySystemNameForUMA; |
| 480 |
| 481 return kUnknownKeySystemNameForUMA; |
| 503 } | 482 } |
| 504 | 483 |
| 505 bool KeySystemsImpl::UseAesDecryptor(const std::string& key_system) const { | 484 bool KeySystemsImpl::UseAesDecryptor(const std::string& key_system) const { |
| 506 DCHECK(thread_checker_.CalledOnValidThread()); | 485 DCHECK(thread_checker_.CalledOnValidThread()); |
| 507 | 486 |
| 508 KeySystemPropertiesMap::const_iterator key_system_iter = | 487 KeySystemPropertiesMap::const_iterator key_system_iter = |
| 509 key_system_properties_map_.find(key_system); | 488 key_system_properties_map_.find(key_system); |
| 510 if (key_system_iter == key_system_properties_map_.end()) { | 489 if (key_system_iter == key_system_properties_map_.end()) { |
| 511 DLOG(ERROR) << key_system << " is not a known system"; | 490 DLOG(ERROR) << key_system << " is not a known system"; |
| 512 return false; | 491 return false; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 uint32_t mask) { | 709 uint32_t mask) { |
| 731 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); | 710 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); |
| 732 } | 711 } |
| 733 | 712 |
| 734 MEDIA_EXPORT void AddMimeTypeCodecMask(const std::string& mime_type, | 713 MEDIA_EXPORT void AddMimeTypeCodecMask(const std::string& mime_type, |
| 735 uint32_t mask) { | 714 uint32_t mask) { |
| 736 KeySystemsImpl::GetInstance()->AddMimeTypeCodecMask(mime_type, mask); | 715 KeySystemsImpl::GetInstance()->AddMimeTypeCodecMask(mime_type, mask); |
| 737 } | 716 } |
| 738 | 717 |
| 739 } // namespace media | 718 } // namespace media |
| OLD | NEW |