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 "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/threading/thread_checker.h" | 14 #include "base/threading/thread_checker.h" |
15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "media/base/key_system_info.h" | 17 #include "media/base/key_system_info.h" |
18 #include "media/base/key_systems_support_uma.h" | |
19 #include "media/base/media_client.h" | 18 #include "media/base/media_client.h" |
20 #include "media/cdm/key_system_names.h" | 19 #include "media/cdm/key_system_names.h" |
21 #include "third_party/widevine/cdm/widevine_cdm_common.h" | 20 #include "third_party/widevine/cdm/widevine_cdm_common.h" |
22 | 21 |
23 namespace media { | 22 namespace media { |
24 | 23 |
25 const char kClearKeyKeySystem[] = "org.w3.clearkey"; | 24 const char kClearKeyKeySystem[] = "org.w3.clearkey"; |
26 const char kPrefixedClearKeyKeySystem[] = "webkit-org.w3.clearkey"; | |
27 const char kUnsupportedClearKeyKeySystem[] = "unsupported-org.w3.clearkey"; | |
28 | 25 |
29 // These names are used by UMA. Do not change them! | 26 // These names are used by UMA. Do not change them! |
30 const char kClearKeyKeySystemNameForUMA[] = "ClearKey"; | 27 const char kClearKeyKeySystemNameForUMA[] = "ClearKey"; |
31 const char kUnknownKeySystemNameForUMA[] = "Unknown"; | 28 const char kUnknownKeySystemNameForUMA[] = "Unknown"; |
32 | 29 |
33 struct NamedCodec { | 30 struct NamedCodec { |
34 const char* name; | 31 const char* name; |
35 EmeCodec type; | 32 EmeCodec type; |
36 }; | 33 }; |
37 | 34 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 return EmeRobustness::SW_SECURE_DECODE; | 70 return EmeRobustness::SW_SECURE_DECODE; |
74 if (robustness == "HW_SECURE_CRYPTO") | 71 if (robustness == "HW_SECURE_CRYPTO") |
75 return EmeRobustness::HW_SECURE_CRYPTO; | 72 return EmeRobustness::HW_SECURE_CRYPTO; |
76 if (robustness == "HW_SECURE_DECODE") | 73 if (robustness == "HW_SECURE_DECODE") |
77 return EmeRobustness::HW_SECURE_DECODE; | 74 return EmeRobustness::HW_SECURE_DECODE; |
78 if (robustness == "HW_SECURE_ALL") | 75 if (robustness == "HW_SECURE_ALL") |
79 return EmeRobustness::HW_SECURE_ALL; | 76 return EmeRobustness::HW_SECURE_ALL; |
80 return EmeRobustness::INVALID; | 77 return EmeRobustness::INVALID; |
81 } | 78 } |
82 | 79 |
| 80 // TODO(ddorwin): Remove reference to "concrete" key systems. crbug.com/249976. |
83 static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { | 81 static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { |
84 KeySystemInfo info; | 82 KeySystemInfo info; |
85 info.key_system = kClearKeyKeySystem; | 83 info.key_system = kClearKeyKeySystem; |
86 | 84 |
87 // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec: | 85 // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec: |
88 // http://developer.android.com/guide/appendix/media-formats.html | 86 // http://developer.android.com/guide/appendix/media-formats.html |
89 // VP9 support is device dependent. | 87 // VP9 support is device dependent. |
90 | 88 |
91 info.supported_init_data_types = | 89 info.supported_init_data_types = |
92 kInitDataTypeMaskWebM | kInitDataTypeMaskKeyIds; | 90 kInitDataTypeMaskWebM | kInitDataTypeMaskKeyIds; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 } | 169 } |
172 | 170 |
173 class KeySystemsImpl : public KeySystems { | 171 class KeySystemsImpl : public KeySystems { |
174 public: | 172 public: |
175 static KeySystemsImpl* GetInstance(); | 173 static KeySystemsImpl* GetInstance(); |
176 | 174 |
177 void UpdateIfNeeded(); | 175 void UpdateIfNeeded(); |
178 | 176 |
179 bool IsConcreteSupportedKeySystem(const std::string& key_system) const; | 177 bool IsConcreteSupportedKeySystem(const std::string& key_system) const; |
180 | 178 |
181 bool PrefixedIsSupportedKeySystemWithMediaMimeType( | |
182 const std::string& mime_type, | |
183 const std::vector<std::string>& codecs, | |
184 const std::string& key_system); | |
185 | |
186 std::string GetKeySystemNameForUMA(const std::string& key_system) const; | 179 std::string GetKeySystemNameForUMA(const std::string& key_system) const; |
187 | 180 |
188 bool UseAesDecryptor(const std::string& concrete_key_system) const; | 181 bool UseAesDecryptor(const std::string& concrete_key_system) const; |
189 | 182 |
190 #if defined(ENABLE_PEPPER_CDMS) | 183 #if defined(ENABLE_PEPPER_CDMS) |
191 std::string GetPepperType(const std::string& concrete_key_system) const; | 184 std::string GetPepperType(const std::string& concrete_key_system) const; |
192 #endif | 185 #endif |
193 | 186 |
194 void AddContainerMask(const std::string& container, uint32_t mask); | 187 void AddContainerMask(const std::string& container, uint32_t mask); |
195 void AddCodecMask(EmeMediaType media_type, | 188 void AddCodecMask(EmeMediaType media_type, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 typedef base::hash_map<std::string, EmeCodec> CodecsMap; | 237 typedef base::hash_map<std::string, EmeCodec> CodecsMap; |
245 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; | 238 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; |
246 typedef base::hash_map<std::string, std::string> KeySystemNameForUMAMap; | 239 typedef base::hash_map<std::string, std::string> KeySystemNameForUMAMap; |
247 | 240 |
248 // TODO(sandersd): Separate container enum from codec mask value. | 241 // TODO(sandersd): Separate container enum from codec mask value. |
249 // http://crbug.com/417440 | 242 // http://crbug.com/417440 |
250 SupportedCodecs GetCodecMaskForContainer( | 243 SupportedCodecs GetCodecMaskForContainer( |
251 const std::string& container) const; | 244 const std::string& container) const; |
252 EmeCodec GetCodecForString(const std::string& codec) const; | 245 EmeCodec GetCodecForString(const std::string& codec) const; |
253 | 246 |
254 const std::string& PrefixedGetConcreteKeySystemNameFor( | |
255 const std::string& key_system) const; | |
256 | |
257 // Returns whether a |container| type is supported by checking | 247 // Returns whether a |container| type is supported by checking |
258 // |key_system_supported_codecs|. | 248 // |key_system_supported_codecs|. |
259 // TODO(xhwang): Update this to actually check initDataType support. | 249 // TODO(xhwang): Update this to actually check initDataType support. |
260 bool IsSupportedContainer(const std::string& container, | 250 bool IsSupportedContainer(const std::string& container, |
261 SupportedCodecs key_system_supported_codecs) const; | 251 SupportedCodecs key_system_supported_codecs) const; |
262 | 252 |
263 // Returns true if all |codecs| are supported in |container| by checking | 253 // Returns true if all |codecs| are supported in |container| by checking |
264 // |key_system_supported_codecs|. | 254 // |key_system_supported_codecs|. |
265 bool IsSupportedContainerAndCodecs( | 255 bool IsSupportedContainerAndCodecs( |
266 const std::string& container, | 256 const std::string& container, |
267 const std::vector<std::string>& codecs, | 257 const std::vector<std::string>& codecs, |
268 SupportedCodecs key_system_supported_codecs) const; | 258 SupportedCodecs key_system_supported_codecs) const; |
269 | 259 |
270 // Map from key system string to capabilities. | 260 // Map from key system string to capabilities. |
271 KeySystemInfoMap concrete_key_system_map_; | 261 KeySystemInfoMap concrete_key_system_map_; |
272 | 262 |
273 // Map from parent key system to the concrete key system that should be used | 263 // Map from parent key system to the concrete key system that should be used |
274 // to represent its capabilities. | 264 // to represent its capabilities. |
275 ParentKeySystemMap parent_key_system_map_; | 265 ParentKeySystemMap parent_key_system_map_; |
276 | 266 |
277 KeySystemsSupportUMA key_systems_support_uma_; | |
278 | |
279 ContainerCodecsMap container_to_codec_mask_map_; | 267 ContainerCodecsMap container_to_codec_mask_map_; |
280 CodecsMap codec_string_map_; | 268 CodecsMap codec_string_map_; |
281 KeySystemNameForUMAMap key_system_name_for_uma_map_; | 269 KeySystemNameForUMAMap key_system_name_for_uma_map_; |
282 | 270 |
283 SupportedCodecs audio_codec_mask_; | 271 SupportedCodecs audio_codec_mask_; |
284 SupportedCodecs video_codec_mask_; | 272 SupportedCodecs video_codec_mask_; |
285 | 273 |
286 // Makes sure all methods are called from the same thread. | 274 // Makes sure all methods are called from the same thread. |
287 base::ThreadChecker thread_checker_; | 275 base::ThreadChecker thread_checker_; |
288 | 276 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 return EME_CODEC_NONE; | 320 return EME_CODEC_NONE; |
333 } | 321 } |
334 | 322 |
335 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { | 323 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { |
336 CodecsMap::const_iterator iter = codec_string_map_.find(codec); | 324 CodecsMap::const_iterator iter = codec_string_map_.find(codec); |
337 if (iter != codec_string_map_.end()) | 325 if (iter != codec_string_map_.end()) |
338 return iter->second; | 326 return iter->second; |
339 return EME_CODEC_NONE; | 327 return EME_CODEC_NONE; |
340 } | 328 } |
341 | 329 |
342 const std::string& KeySystemsImpl::PrefixedGetConcreteKeySystemNameFor( | |
343 const std::string& key_system) const { | |
344 ParentKeySystemMap::const_iterator iter = | |
345 parent_key_system_map_.find(key_system); | |
346 if (iter != parent_key_system_map_.end()) | |
347 return iter->second; | |
348 return key_system; | |
349 } | |
350 | |
351 void KeySystemsImpl::InitializeUMAInfo() { | 330 void KeySystemsImpl::InitializeUMAInfo() { |
352 DCHECK(thread_checker_.CalledOnValidThread()); | 331 DCHECK(thread_checker_.CalledOnValidThread()); |
353 DCHECK(key_system_name_for_uma_map_.empty()); | 332 DCHECK(key_system_name_for_uma_map_.empty()); |
354 | 333 |
355 std::vector<KeySystemInfoForUMA> key_systems_info_for_uma; | 334 std::vector<KeySystemInfoForUMA> key_systems_info_for_uma; |
356 if (GetMediaClient()) | 335 if (GetMediaClient()) |
357 GetMediaClient()->AddKeySystemsInfoForUMA(&key_systems_info_for_uma); | 336 GetMediaClient()->AddKeySystemsInfoForUMA(&key_systems_info_for_uma); |
358 | 337 |
359 for (const KeySystemInfoForUMA& info : key_systems_info_for_uma) { | 338 for (const KeySystemInfoForUMA& info : key_systems_info_for_uma) { |
360 key_system_name_for_uma_map_[info.key_system] = | 339 key_system_name_for_uma_map_[info.key_system] = |
361 info.key_system_name_for_uma; | 340 info.key_system_name_for_uma; |
362 if (info.reports_key_system_support_to_uma) | |
363 key_systems_support_uma_.AddKeySystemToReport(info.key_system); | |
364 } | 341 } |
365 | 342 |
366 // Clear Key is always supported. | 343 // Clear Key is always supported. |
367 key_system_name_for_uma_map_[kClearKeyKeySystem] = | 344 key_system_name_for_uma_map_[kClearKeyKeySystem] = |
368 kClearKeyKeySystemNameForUMA; | 345 kClearKeyKeySystemNameForUMA; |
369 } | 346 } |
370 | 347 |
371 void KeySystemsImpl::UpdateIfNeeded() { | 348 void KeySystemsImpl::UpdateIfNeeded() { |
372 if (GetMediaClient() && GetMediaClient()->IsKeySystemsUpdateNeeded()) | 349 if (GetMediaClient() && GetMediaClient()->IsKeySystemsUpdateNeeded()) |
373 UpdateSupportedKeySystems(); | 350 UpdateSupportedKeySystems(); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } | 496 } |
520 | 497 |
521 return true; | 498 return true; |
522 } | 499 } |
523 | 500 |
524 bool KeySystemsImpl::IsSupportedInitDataType( | 501 bool KeySystemsImpl::IsSupportedInitDataType( |
525 const std::string& key_system, | 502 const std::string& key_system, |
526 EmeInitDataType init_data_type) const { | 503 EmeInitDataType init_data_type) const { |
527 DCHECK(thread_checker_.CalledOnValidThread()); | 504 DCHECK(thread_checker_.CalledOnValidThread()); |
528 | 505 |
529 // Locate |key_system|. Only concrete key systems are supported in unprefixed. | 506 // Locate |key_system|. Only concrete key systems are supported. |
530 KeySystemInfoMap::const_iterator key_system_iter = | 507 KeySystemInfoMap::const_iterator key_system_iter = |
531 concrete_key_system_map_.find(key_system); | 508 concrete_key_system_map_.find(key_system); |
532 if (key_system_iter == concrete_key_system_map_.end()) { | 509 if (key_system_iter == concrete_key_system_map_.end()) { |
533 NOTREACHED(); | 510 NOTREACHED(); |
534 return false; | 511 return false; |
535 } | 512 } |
536 | 513 |
537 // Check |init_data_type|. | 514 // Check |init_data_type|. |
538 InitDataTypeMask available_init_data_types = | 515 InitDataTypeMask available_init_data_types = |
539 key_system_iter->second.supported_init_data_types; | 516 key_system_iter->second.supported_init_data_types; |
540 switch (init_data_type) { | 517 switch (init_data_type) { |
541 case EmeInitDataType::UNKNOWN: | 518 case EmeInitDataType::UNKNOWN: |
542 return false; | 519 return false; |
543 case EmeInitDataType::WEBM: | 520 case EmeInitDataType::WEBM: |
544 return (available_init_data_types & kInitDataTypeMaskWebM) != 0; | 521 return (available_init_data_types & kInitDataTypeMaskWebM) != 0; |
545 case EmeInitDataType::CENC: | 522 case EmeInitDataType::CENC: |
546 return (available_init_data_types & kInitDataTypeMaskCenc) != 0; | 523 return (available_init_data_types & kInitDataTypeMaskCenc) != 0; |
547 case EmeInitDataType::KEYIDS: | 524 case EmeInitDataType::KEYIDS: |
548 return (available_init_data_types & kInitDataTypeMaskKeyIds) != 0; | 525 return (available_init_data_types & kInitDataTypeMaskKeyIds) != 0; |
549 } | 526 } |
550 NOTREACHED(); | 527 NOTREACHED(); |
551 return false; | 528 return false; |
552 } | 529 } |
553 | 530 |
554 bool KeySystemsImpl::PrefixedIsSupportedKeySystemWithMediaMimeType( | |
555 const std::string& mime_type, | |
556 const std::vector<std::string>& codecs, | |
557 const std::string& key_system) { | |
558 DCHECK(thread_checker_.CalledOnValidThread()); | |
559 | |
560 const std::string& concrete_key_system = | |
561 PrefixedGetConcreteKeySystemNameFor(key_system); | |
562 | |
563 bool has_type = !mime_type.empty(); | |
564 | |
565 key_systems_support_uma_.ReportKeySystemQuery(key_system, has_type); | |
566 | |
567 // Check key system support. | |
568 KeySystemInfoMap::const_iterator key_system_iter = | |
569 concrete_key_system_map_.find(concrete_key_system); | |
570 if (key_system_iter == concrete_key_system_map_.end()) | |
571 return false; | |
572 | |
573 key_systems_support_uma_.ReportKeySystemSupport(key_system, false); | |
574 | |
575 if (!has_type) { | |
576 DCHECK(codecs.empty()); | |
577 return true; | |
578 } | |
579 | |
580 SupportedCodecs key_system_supported_codecs = | |
581 key_system_iter->second.supported_codecs; | |
582 | |
583 if (!IsSupportedContainer(mime_type, key_system_supported_codecs)) | |
584 return false; | |
585 | |
586 if (!codecs.empty() && | |
587 !IsSupportedContainerAndCodecs( | |
588 mime_type, codecs, key_system_supported_codecs)) { | |
589 return false; | |
590 } | |
591 | |
592 key_systems_support_uma_.ReportKeySystemSupport(key_system, true); | |
593 | |
594 return true; | |
595 } | |
596 | |
597 std::string KeySystemsImpl::GetKeySystemNameForUMA( | 531 std::string KeySystemsImpl::GetKeySystemNameForUMA( |
598 const std::string& key_system) const { | 532 const std::string& key_system) const { |
599 DCHECK(thread_checker_.CalledOnValidThread()); | 533 DCHECK(thread_checker_.CalledOnValidThread()); |
600 | 534 |
601 KeySystemNameForUMAMap::const_iterator iter = | 535 KeySystemNameForUMAMap::const_iterator iter = |
602 key_system_name_for_uma_map_.find(key_system); | 536 key_system_name_for_uma_map_.find(key_system); |
603 if (iter == key_system_name_for_uma_map_.end()) | 537 if (iter == key_system_name_for_uma_map_.end()) |
604 return kUnknownKeySystemNameForUMA; | 538 return kUnknownKeySystemNameForUMA; |
605 | 539 |
606 return iter->second; | 540 return iter->second; |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 } | 801 } |
868 return key_system_iter->second.distinctive_identifier_support; | 802 return key_system_iter->second.distinctive_identifier_support; |
869 } | 803 } |
870 | 804 |
871 KeySystems* KeySystems::GetInstance() { | 805 KeySystems* KeySystems::GetInstance() { |
872 return KeySystemsImpl::GetInstance(); | 806 return KeySystemsImpl::GetInstance(); |
873 } | 807 } |
874 | 808 |
875 //------------------------------------------------------------------------------ | 809 //------------------------------------------------------------------------------ |
876 | 810 |
877 std::string GetUnprefixedKeySystemName(const std::string& key_system) { | |
878 if (key_system == kClearKeyKeySystem) | |
879 return kUnsupportedClearKeyKeySystem; | |
880 | |
881 if (key_system == kPrefixedClearKeyKeySystem) | |
882 return kClearKeyKeySystem; | |
883 | |
884 return key_system; | |
885 } | |
886 | |
887 std::string GetPrefixedKeySystemName(const std::string& key_system) { | |
888 DCHECK_NE(key_system, kPrefixedClearKeyKeySystem); | |
889 | |
890 if (key_system == kClearKeyKeySystem) | |
891 return kPrefixedClearKeyKeySystem; | |
892 | |
893 return key_system; | |
894 } | |
895 | |
896 bool PrefixedIsSupportedConcreteKeySystem(const std::string& key_system) { | |
897 return KeySystemsImpl::GetInstance()->IsConcreteSupportedKeySystem( | |
898 key_system); | |
899 } | |
900 | |
901 bool IsSupportedKeySystemWithInitDataType(const std::string& key_system, | 811 bool IsSupportedKeySystemWithInitDataType(const std::string& key_system, |
902 EmeInitDataType init_data_type) { | 812 EmeInitDataType init_data_type) { |
903 return KeySystemsImpl::GetInstance()->IsSupportedInitDataType(key_system, | 813 return KeySystemsImpl::GetInstance()->IsSupportedInitDataType(key_system, |
904 init_data_type); | 814 init_data_type); |
905 } | 815 } |
906 | 816 |
907 bool PrefixedIsSupportedKeySystemWithMediaMimeType( | |
908 const std::string& mime_type, | |
909 const std::vector<std::string>& codecs, | |
910 const std::string& key_system) { | |
911 return KeySystemsImpl::GetInstance() | |
912 ->PrefixedIsSupportedKeySystemWithMediaMimeType(mime_type, codecs, | |
913 key_system); | |
914 } | |
915 | |
916 std::string GetKeySystemNameForUMA(const std::string& key_system) { | 817 std::string GetKeySystemNameForUMA(const std::string& key_system) { |
917 return KeySystemsImpl::GetInstance()->GetKeySystemNameForUMA(key_system); | 818 return KeySystemsImpl::GetInstance()->GetKeySystemNameForUMA(key_system); |
918 } | 819 } |
919 | 820 |
920 bool CanUseAesDecryptor(const std::string& concrete_key_system) { | 821 bool CanUseAesDecryptor(const std::string& concrete_key_system) { |
921 return KeySystemsImpl::GetInstance()->UseAesDecryptor(concrete_key_system); | 822 return KeySystemsImpl::GetInstance()->UseAesDecryptor(concrete_key_system); |
922 } | 823 } |
923 | 824 |
924 #if defined(ENABLE_PEPPER_CDMS) | 825 #if defined(ENABLE_PEPPER_CDMS) |
925 std::string GetPepperType(const std::string& concrete_key_system) { | 826 std::string GetPepperType(const std::string& concrete_key_system) { |
(...skipping 12 matching lines...) Expand all Loading... |
938 KeySystemsImpl::GetInstance()->AddContainerMask(container, mask); | 839 KeySystemsImpl::GetInstance()->AddContainerMask(container, mask); |
939 } | 840 } |
940 | 841 |
941 MEDIA_EXPORT void AddCodecMask(EmeMediaType media_type, | 842 MEDIA_EXPORT void AddCodecMask(EmeMediaType media_type, |
942 const std::string& codec, | 843 const std::string& codec, |
943 uint32_t mask) { | 844 uint32_t mask) { |
944 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); | 845 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); |
945 } | 846 } |
946 | 847 |
947 } // namespace media | 848 } // namespace media |
OLD | NEW |