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 3// found in the LICENSE file. 4 5#include "content/renderer/media/crypto/key_systems.h" 6 7#include <map> 8 9#include "base/lazy_instance.h" 10#include "base/logging.h" 11#include "base/strings/string_util.h" 12#include "content/renderer/media/crypto/key_systems_info.h" 13#include "net/base/mime_util.h" 14#include "third_party/WebKit/public/platform/WebCString.h" 15#include "third_party/WebKit/public/platform/WebString.h" 16 17namespace content { 18 19// Convert a WebString to ASCII, falling back on an empty string in the case 20// of a non-ASCII string. 21static std::string ToASCIIOrEmpty(const WebKit::WebString& string) { 22 return IsStringASCII(string) ? UTF16ToASCII(string) : std::string(); 23} 24 25class KeySystems { 26 public: 27 bool IsSupportedKeySystem(const std::string& key_system); 28 29 bool IsSupportedKeySystemWithMediaMimeType( 30 const std::string& mime_type, 31 const std::vector<std::string>& codecs, 32 const std::string& key_system); 33 34 private: 35 friend struct base::DefaultLazyInstanceTraits<KeySystems>; 36 37 typedef base::hash_set<std::string> CodecMappings; 38 typedef std::map<std::string, CodecMappings> MimeTypeMappings; 39 typedef std::map<std::string, MimeTypeMappings> KeySystemMappings; 40 41 KeySystems(); 42 43 bool IsSupportedKeySystemWithContainerAndCodec( 44 const std::string& mime_type, 45 const std::string& codec, 46 const std::string& key_system); 47 48 KeySystemMappings key_system_map_; 49 50 DISALLOW_COPY_AND_ASSIGN(KeySystems); 51}; 52 53static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER; 54 55KeySystems::KeySystems() { 56 // Initialize the supported media type/key system combinations. 57 for (int i = 0; i < kNumSupportedFormatKeySystemCombinations; ++i) { 58 const MediaFormatAndKeySystem& combination = 59 kSupportedFormatKeySystemCombinations[i]; 60 std::vector<std::string> mime_type_codecs; 61 net::ParseCodecString(combination.codecs_list, 62 &mime_type_codecs, 63 false); 64 65 CodecMappings codecs; 66 for (size_t j = 0; j < mime_type_codecs.size(); ++j) 67 codecs.insert(mime_type_codecs[j]); 68 // Support the MIME type string alone, without codec(s) specified. 69 codecs.insert(std::string()); 70 71 // Key systems can be repeated, so there may already be an entry. 72 KeySystemMappings::iterator key_system_iter = 73 key_system_map_.find(combination.key_system); 74 if (key_system_iter == key_system_map_.end()) { 75 MimeTypeMappings mime_types_map; 76 mime_types_map[combination.mime_type] = codecs; 77 key_system_map_[combination.key_system] = mime_types_map; 78 } else { 79 MimeTypeMappings& mime_types_map = key_system_iter->second; 80 // mime_types_map may not be repeated for a given key system. 81 DCHECK(mime_types_map.find(combination.mime_type) == 82 mime_types_map.end()); 83 mime_types_map[combination.mime_type] = codecs; 84 } 85 } 86} 87 88bool KeySystems::IsSupportedKeySystem(const std::string& key_system) { 89 bool is_supported = key_system_map_.find(key_system) != key_system_map_.end(); 90 return is_supported && IsSystemCompatible(key_system); 91} 92 93bool KeySystems::IsSupportedKeySystemWithContainerAndCodec( 94 const std::string& mime_type, 95 const std::string& codec, 96 const std::string& key_system) { 97 KeySystemMappings::const_iterator key_system_iter = 98 key_system_map_.find(key_system); 99 if (key_system_iter == key_system_map_.end()) 100 return false; 101 102 const MimeTypeMappings& mime_types_map = key_system_iter->second; 103 MimeTypeMappings::const_iterator mime_iter = mime_types_map.find(mime_type); 104 if (mime_iter == mime_types_map.end()) 105 return false; 106 107 const CodecMappings& codecs = mime_iter->second; 108 return (codecs.find(codec) != codecs.end()) && IsSystemCompatible(key_system); 109} 110 111bool KeySystems::IsSupportedKeySystemWithMediaMimeType( 112 const std::string& mime_type, 113 const std::vector<std::string>& codecs, 114 const std::string& key_system) { 115 // This method is only used by the canPlaytType() path (not the EME methods), 116 // so we check for suppressed key_systems here. 117 if(IsCanPlayTypeSuppressed(key_system)) 118 return false; 119 120 if (codecs.empty()) 121 return IsSupportedKeySystemWithContainerAndCodec( 122 mime_type, std::string(), key_system); 123 124 for (size_t i = 0; i < codecs.size(); ++i) { 125 if (!IsSupportedKeySystemWithContainerAndCodec( 126 mime_type, codecs[i], key_system)) 127 return false; 128 } 129 130 return true; 131} 132 133bool IsSupportedKeySystem(const WebKit::WebString& key_system) { 134 return g_key_systems.Get().IsSupportedKeySystem(ToASCIIOrEmpty(key_system)); 135} 136 137bool IsSupportedKeySystemWithMediaMimeType( 138 const std::string& mime_type, 139 const std::vector<std::string>& codecs, 140 const std::string& key_system) { 141 return g_key_systems.Get().IsSupportedKeySystemWithMediaMimeType( 142 mime_type, codecs, key_system); 143} 144 145std::string KeySystemNameForUMA(const WebKit::WebString& key_system) { 146 return KeySystemNameForUMAInternal(key_system); 147} 148 149bool CanUseAesDecryptor(const std::string& key_system) { 150 return CanUseBuiltInAesDecryptor(key_system); 151} 152 153#if defined(ENABLE_PEPPER_CDMS) 154std::string GetPepperType(const std::string& key_system) { 155 for (int i = 0; i < kNumKeySystemToPepperTypeMapping; ++i) { 156 if (kKeySystemToPepperTypeMapping[i].key_system == key_system) 157 return kKeySystemToPepperTypeMapping[i].type; 158 } 159 160 return std::string(); 161} 162#endif // defined(ENABLE_PEPPER_CDMS) 163 164#if defined(OS_ANDROID) 165std::vector<uint8> GetUUID(const std::string& key_system) { 166 for (int i = 0; i < kNumKeySystemToUUIDMapping; ++i) { 167 if (kKeySystemToUUIDMapping[i].key_system == key_system) 168 return std::vector<uint8>(kKeySystemToUUIDMapping[i].uuid, 169 kKeySystemToUUIDMapping[i].uuid + 16); 170 } 171 return std::vector<uint8>(); 172} 173#endif // defined(OS_ANDROID) 174 175} // namespace content 176