| 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 "content/renderer/media/crypto/key_systems.h" | 5 #include "content/renderer/media/crypto/key_systems.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 #if defined(ENABLE_PEPPER_CDMS) | 52 #if defined(ENABLE_PEPPER_CDMS) |
| 53 std::string GetPepperType(const std::string& concrete_key_system); | 53 std::string GetPepperType(const std::string& concrete_key_system); |
| 54 #elif defined(OS_ANDROID) | 54 #elif defined(OS_ANDROID) |
| 55 std::vector<uint8> GetUUID(const std::string& concrete_key_system); | 55 std::vector<uint8> GetUUID(const std::string& concrete_key_system); |
| 56 #endif | 56 #endif |
| 57 | 57 |
| 58 private: | 58 private: |
| 59 friend struct base::DefaultLazyInstanceTraits<KeySystems>; | 59 friend struct base::DefaultLazyInstanceTraits<KeySystems>; |
| 60 | 60 |
| 61 typedef base::hash_set<std::string> CodecMappings; | 61 typedef base::hash_set<std::string> CodecSet; |
| 62 typedef std::map<std::string, CodecMappings> MimeTypeMappings; | 62 typedef std::map<std::string, CodecSet> MimeTypeMap; |
| 63 | 63 |
| 64 struct KeySystemProperties { | 64 struct KeySystemProperties { |
| 65 KeySystemProperties() : use_aes_decryptor(false) {} | 65 KeySystemProperties() : use_aes_decryptor(false) {} |
| 66 | 66 |
| 67 bool use_aes_decryptor; | 67 bool use_aes_decryptor; |
| 68 #if defined(ENABLE_PEPPER_CDMS) | 68 #if defined(ENABLE_PEPPER_CDMS) |
| 69 std::string pepper_type; | 69 std::string pepper_type; |
| 70 #elif defined(OS_ANDROID) | 70 #elif defined(OS_ANDROID) |
| 71 std::vector<uint8> uuid; | 71 std::vector<uint8> uuid; |
| 72 #endif | 72 #endif |
| 73 MimeTypeMappings types; | 73 MimeTypeMap types; |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 typedef std::map<std::string, KeySystemProperties> KeySystemMappings; | 76 typedef std::map<std::string, KeySystemProperties> KeySystemPropertiesMap; |
| 77 | 77 |
| 78 typedef std::map<std::string, std::string> ParentKeySystemMappings; | 78 typedef std::map<std::string, std::string> ParentKeySystemMap; |
| 79 | 79 |
| 80 KeySystems() {} | 80 KeySystems() {} |
| 81 | 81 |
| 82 bool IsSupportedKeySystemWithContainerAndCodec( | 82 bool IsSupportedKeySystemWithContainerAndCodec( |
| 83 const std::string& mime_type, | 83 const std::string& mime_type, |
| 84 const std::string& codec, | 84 const std::string& codec, |
| 85 const std::string& key_system); | 85 const std::string& key_system); |
| 86 | 86 |
| 87 // Map from key system string to capabilities. | 87 // Map from key system string to capabilities. |
| 88 KeySystemMappings key_system_map_; | 88 KeySystemPropertiesMap concrete_key_system_map_; |
| 89 | 89 |
| 90 // Map from parent key system to the concrete key system that should be used | 90 // Map from parent key system to the concrete key system that should be used |
| 91 // to represent its capabilities. | 91 // to represent its capabilities. |
| 92 ParentKeySystemMappings parent_key_system_map_; | 92 ParentKeySystemMap parent_key_system_map_; |
| 93 | 93 |
| 94 DISALLOW_COPY_AND_ASSIGN(KeySystems); | 94 DISALLOW_COPY_AND_ASSIGN(KeySystems); |
| 95 }; | 95 }; |
| 96 | 96 |
| 97 static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER; | 97 static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER; |
| 98 | 98 |
| 99 KeySystems* KeySystems::GetInstance() { | 99 KeySystems* KeySystems::GetInstance() { |
| 100 KeySystems* key_systems = &g_key_systems.Get(); | 100 KeySystems* key_systems = &g_key_systems.Get(); |
| 101 // TODO(ddorwin): Call out to ContentClient to register key systems. | 101 // TODO(ddorwin): Call out to ContentClient to register key systems. |
| 102 static bool is_registered = false; | 102 static bool is_registered = false; |
| 103 if (!is_registered) { | 103 if (!is_registered) { |
| 104 is_registered = true; // Prevent reentrancy when Add*() is called. | 104 is_registered = true; // Prevent reentrancy when Add*() is called. |
| 105 RegisterKeySystems(); | 105 RegisterKeySystems(); |
| 106 } | 106 } |
| 107 return key_systems; | 107 return key_systems; |
| 108 } | 108 } |
| 109 | 109 |
| 110 // TODO(ddorwin): Change first parameter to |concrete_key_system|. | |
| 111 void KeySystems::AddConcreteSupportedKeySystem( | 110 void KeySystems::AddConcreteSupportedKeySystem( |
| 112 const std::string& key_system, | 111 const std::string& concrete_key_system, |
| 113 bool use_aes_decryptor, | 112 bool use_aes_decryptor, |
| 114 #if defined(ENABLE_PEPPER_CDMS) | 113 #if defined(ENABLE_PEPPER_CDMS) |
| 115 const std::string& pepper_type, | 114 const std::string& pepper_type, |
| 116 #elif defined(OS_ANDROID) | 115 #elif defined(OS_ANDROID) |
| 117 const uint8 uuid[16], | 116 const uint8 uuid[16], |
| 118 #endif | 117 #endif |
| 119 const std::string& parent_key_system) { | 118 const std::string& parent_key_system) { |
| 120 DCHECK(!IsConcreteSupportedKeySystem(key_system)) | 119 DCHECK(!IsConcreteSupportedKeySystem(concrete_key_system)) |
| 121 << "Key system '" << key_system << "' already registered"; | 120 << "Key system '" << concrete_key_system << "' already registered"; |
| 122 | 121 |
| 123 KeySystemProperties properties; | 122 KeySystemProperties properties; |
| 124 properties.use_aes_decryptor = use_aes_decryptor; | 123 properties.use_aes_decryptor = use_aes_decryptor; |
| 125 #if defined(ENABLE_PEPPER_CDMS) | 124 #if defined(ENABLE_PEPPER_CDMS) |
| 126 DCHECK_EQ(use_aes_decryptor, pepper_type.empty()); | 125 DCHECK_EQ(use_aes_decryptor, pepper_type.empty()); |
| 127 properties.pepper_type = pepper_type; | 126 properties.pepper_type = pepper_type; |
| 128 #elif defined(OS_ANDROID) | 127 #elif defined(OS_ANDROID) |
| 129 // Since |uuid| can't be empty, use |use_aes_decryptor|. | 128 // Since |uuid| can't be empty, use |use_aes_decryptor|. |
| 130 if (!use_aes_decryptor) | 129 if (!use_aes_decryptor) |
| 131 properties.uuid.assign(uuid, uuid + 16); | 130 properties.uuid.assign(uuid, uuid + 16); |
| 132 #endif | 131 #endif |
| 133 key_system_map_[key_system] = properties; | 132 concrete_key_system_map_[concrete_key_system] = properties; |
| 134 | 133 |
| 135 if (!parent_key_system.empty()) { | 134 if (!parent_key_system.empty()) { |
| 136 DCHECK(parent_key_system_map_.find(parent_key_system) == | 135 DCHECK(parent_key_system_map_.find(parent_key_system) == |
| 137 parent_key_system_map_.end()) | 136 parent_key_system_map_.end()) |
| 138 << "Parent '" << parent_key_system.c_str() << "' already registered."; | 137 << "Parent '" << parent_key_system.c_str() << "' already registered."; |
| 139 parent_key_system_map_[parent_key_system] = key_system; | 138 parent_key_system_map_[parent_key_system] = concrete_key_system; |
| 140 } | 139 } |
| 141 } | 140 } |
| 142 | 141 |
| 143 // TODO(ddorwin): Change first parameter to |concrete_key_system|. | 142 void KeySystems::AddSupportedType(const std::string& concrete_key_system, |
| 144 void KeySystems::AddSupportedType(const std::string& key_system, | |
| 145 const std::string& mime_type, | 143 const std::string& mime_type, |
| 146 const std::string& codecs_list) { | 144 const std::string& codecs_list) { |
| 147 std::vector<std::string> mime_type_codecs; | 145 std::vector<std::string> mime_type_codecs; |
| 148 net::ParseCodecString(codecs_list, &mime_type_codecs, false); | 146 net::ParseCodecString(codecs_list, &mime_type_codecs, false); |
| 149 | 147 |
| 150 CodecMappings codecs(mime_type_codecs.begin(), mime_type_codecs.end()); | 148 CodecSet codecs(mime_type_codecs.begin(), mime_type_codecs.end()); |
| 151 // Support the MIME type string alone, without codec(s) specified. | 149 // Support the MIME type string alone, without codec(s) specified. |
| 152 codecs.insert(std::string()); | 150 codecs.insert(std::string()); |
| 153 | 151 |
| 154 KeySystemMappings::iterator key_system_iter = | 152 KeySystemPropertiesMap::iterator key_system_iter = |
| 155 key_system_map_.find(key_system); | 153 concrete_key_system_map_.find(concrete_key_system); |
| 156 DCHECK(key_system_iter != key_system_map_.end()); | 154 DCHECK(key_system_iter != concrete_key_system_map_.end()); |
| 157 MimeTypeMappings& mime_types_map = key_system_iter->second.types; | 155 MimeTypeMap& mime_types_map = key_system_iter->second.types; |
| 158 // mime_types_map must not be repeated for a given key system. | 156 // mime_types_map must not be repeated for a given key system. |
| 159 DCHECK(mime_types_map.find(mime_type) == mime_types_map.end()); | 157 DCHECK(mime_types_map.find(mime_type) == mime_types_map.end()); |
| 160 mime_types_map[mime_type] = codecs; | 158 mime_types_map[mime_type] = codecs; |
| 161 } | 159 } |
| 162 | 160 |
| 163 bool KeySystems::IsConcreteSupportedKeySystem(const std::string& key_system) { | 161 bool KeySystems::IsConcreteSupportedKeySystem(const std::string& key_system) { |
| 164 return key_system_map_.find(key_system) != key_system_map_.end(); | 162 return concrete_key_system_map_.find(key_system) != |
| 163 concrete_key_system_map_.end(); |
| 165 } | 164 } |
| 166 | 165 |
| 167 bool KeySystems::IsSupportedKeySystemWithContainerAndCodec( | 166 bool KeySystems::IsSupportedKeySystemWithContainerAndCodec( |
| 168 const std::string& mime_type, | 167 const std::string& mime_type, |
| 169 const std::string& codec, | 168 const std::string& codec, |
| 170 const std::string& key_system) { | 169 const std::string& key_system) { |
| 171 KeySystemMappings::const_iterator key_system_iter = | 170 KeySystemPropertiesMap::const_iterator key_system_iter = |
| 172 key_system_map_.find(key_system); | 171 concrete_key_system_map_.find(key_system); |
| 173 if (key_system_iter == key_system_map_.end()) | 172 if (key_system_iter == concrete_key_system_map_.end()) |
| 174 return false; | 173 return false; |
| 175 | 174 |
| 176 const MimeTypeMappings& mime_types_map = key_system_iter->second.types; | 175 const MimeTypeMap& mime_types_map = key_system_iter->second.types; |
| 177 MimeTypeMappings::const_iterator mime_iter = mime_types_map.find(mime_type); | 176 MimeTypeMap::const_iterator mime_iter = mime_types_map.find(mime_type); |
| 178 if (mime_iter == mime_types_map.end()) | 177 if (mime_iter == mime_types_map.end()) |
| 179 return false; | 178 return false; |
| 180 | 179 |
| 181 const CodecMappings& codecs = mime_iter->second; | 180 const CodecSet& codecs = mime_iter->second; |
| 182 return (codecs.find(codec) != codecs.end()); | 181 return (codecs.find(codec) != codecs.end()); |
| 183 } | 182 } |
| 184 | 183 |
| 185 bool KeySystems::IsSupportedKeySystemWithMediaMimeType( | 184 bool KeySystems::IsSupportedKeySystemWithMediaMimeType( |
| 186 const std::string& mime_type, | 185 const std::string& mime_type, |
| 187 const std::vector<std::string>& codecs, | 186 const std::vector<std::string>& codecs, |
| 188 const std::string& key_system) { | 187 const std::string& key_system) { |
| 189 // If |key_system| is a parent key_system, use its concrete child. | 188 // If |key_system| is a parent key_system, use its concrete child. |
| 190 // Otherwise, use |key_system|. | 189 // Otherwise, use |key_system|. |
| 191 std::string concrete_key_system; | 190 std::string concrete_key_system; |
| 192 ParentKeySystemMappings::iterator parent_key_system_iter = | 191 ParentKeySystemMap::iterator parent_key_system_iter = |
| 193 parent_key_system_map_.find(key_system); | 192 parent_key_system_map_.find(key_system); |
| 194 if (parent_key_system_iter != parent_key_system_map_.end()) | 193 if (parent_key_system_iter != parent_key_system_map_.end()) |
| 195 concrete_key_system = parent_key_system_iter->second; | 194 concrete_key_system = parent_key_system_iter->second; |
| 196 else | 195 else |
| 197 concrete_key_system = key_system; | 196 concrete_key_system = key_system; |
| 198 | 197 |
| 199 // This method is only used by the canPlaytType() path (not the EME methods), | 198 // This method is only used by the canPlaytType() path (not the EME methods), |
| 200 // so we check for suppressed key_systems here. | 199 // so we check for suppressed key_systems here. |
| 201 if(IsCanPlayTypeSuppressed(concrete_key_system)) | 200 if(IsCanPlayTypeSuppressed(concrete_key_system)) |
| 202 return false; | 201 return false; |
| 203 | 202 |
| 204 if (codecs.empty()) { | 203 if (codecs.empty()) { |
| 205 return IsSupportedKeySystemWithContainerAndCodec( | 204 return IsSupportedKeySystemWithContainerAndCodec( |
| 206 mime_type, std::string(), concrete_key_system); | 205 mime_type, std::string(), concrete_key_system); |
| 207 } | 206 } |
| 208 | 207 |
| 209 for (size_t i = 0; i < codecs.size(); ++i) { | 208 for (size_t i = 0; i < codecs.size(); ++i) { |
| 210 if (!IsSupportedKeySystemWithContainerAndCodec( | 209 if (!IsSupportedKeySystemWithContainerAndCodec( |
| 211 mime_type, codecs[i], concrete_key_system)) { | 210 mime_type, codecs[i], concrete_key_system)) { |
| 212 return false; | 211 return false; |
| 213 } | 212 } |
| 214 } | 213 } |
| 215 | 214 |
| 216 return true; | 215 return true; |
| 217 } | 216 } |
| 218 | 217 |
| 219 bool KeySystems::UseAesDecryptor(const std::string& concrete_key_system) { | 218 bool KeySystems::UseAesDecryptor(const std::string& concrete_key_system) { |
| 220 KeySystemMappings::iterator key_system_iter = | 219 KeySystemPropertiesMap::iterator key_system_iter = |
| 221 key_system_map_.find(concrete_key_system); | 220 concrete_key_system_map_.find(concrete_key_system); |
| 222 if (key_system_iter == key_system_map_.end()) { | 221 if (key_system_iter == concrete_key_system_map_.end()) { |
| 223 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; | 222 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; |
| 224 return false; | 223 return false; |
| 225 } | 224 } |
| 226 | 225 |
| 227 return key_system_iter->second.use_aes_decryptor; | 226 return key_system_iter->second.use_aes_decryptor; |
| 228 } | 227 } |
| 229 | 228 |
| 230 #if defined(ENABLE_PEPPER_CDMS) | 229 #if defined(ENABLE_PEPPER_CDMS) |
| 231 std::string KeySystems::GetPepperType(const std::string& concrete_key_system) { | 230 std::string KeySystems::GetPepperType(const std::string& concrete_key_system) { |
| 232 KeySystemMappings::iterator key_system_iter = | 231 KeySystemPropertiesMap::iterator key_system_iter = |
| 233 key_system_map_.find(concrete_key_system); | 232 concrete_key_system_map_.find(concrete_key_system); |
| 234 if (key_system_iter == key_system_map_.end()) { | 233 if (key_system_iter == concrete_key_system_map_.end()) { |
| 235 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; | 234 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; |
| 236 return std::string(); | 235 return std::string(); |
| 237 } | 236 } |
| 238 | 237 |
| 239 const std::string& type = key_system_iter->second.pepper_type; | 238 const std::string& type = key_system_iter->second.pepper_type; |
| 240 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; | 239 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; |
| 241 return type; | 240 return type; |
| 242 } | 241 } |
| 243 #elif defined(OS_ANDROID) | 242 #elif defined(OS_ANDROID) |
| 244 std::vector<uint8> KeySystems::GetUUID(const std::string& concrete_key_system) { | 243 std::vector<uint8> KeySystems::GetUUID(const std::string& concrete_key_system) { |
| 245 KeySystemMappings::iterator key_system_iter = | 244 KeySystemPropertiesMap::iterator key_system_iter = |
| 246 key_system_map_.find(concrete_key_system); | 245 concrete_key_system_map_.find(concrete_key_system); |
| 247 if (key_system_iter == key_system_map_.end()) { | 246 if (key_system_iter == concrete_key_system_map_.end()) { |
| 248 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; | 247 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; |
| 249 return std::vector<uint8>(); | 248 return std::vector<uint8>(); |
| 250 } | 249 } |
| 251 | 250 |
| 252 return key_system_iter->second.uuid; | 251 return key_system_iter->second.uuid; |
| 253 } | 252 } |
| 254 #endif | 253 #endif |
| 255 | 254 |
| 256 //------------------------------------------------------------------------------ | 255 //------------------------------------------------------------------------------ |
| 257 | 256 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 std::string GetPepperType(const std::string& concrete_key_system) { | 305 std::string GetPepperType(const std::string& concrete_key_system) { |
| 307 return KeySystems::GetInstance()->GetPepperType(concrete_key_system); | 306 return KeySystems::GetInstance()->GetPepperType(concrete_key_system); |
| 308 } | 307 } |
| 309 #elif defined(OS_ANDROID) | 308 #elif defined(OS_ANDROID) |
| 310 std::vector<uint8> GetUUID(const std::string& concrete_key_system) { | 309 std::vector<uint8> GetUUID(const std::string& concrete_key_system) { |
| 311 return KeySystems::GetInstance()->GetUUID(concrete_key_system); | 310 return KeySystems::GetInstance()->GetUUID(concrete_key_system); |
| 312 } | 311 } |
| 313 #endif | 312 #endif |
| 314 | 313 |
| 315 } // namespace content | 314 } // namespace content |
| OLD | NEW |