Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: content/renderer/media/crypto/key_systems.cc

Issue 23464005: Explicitly register each key system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "content/renderer/media/crypto/key_systems_info.h" 12 #include "content/renderer/media/crypto/key_systems_info.h"
13 #include "net/base/mime_util.h" 13 #include "net/base/mime_util.h"
14 #include "third_party/WebKit/public/platform/WebCString.h" 14 #include "third_party/WebKit/public/platform/WebCString.h"
15 #include "third_party/WebKit/public/platform/WebString.h" 15 #include "third_party/WebKit/public/platform/WebString.h"
16 16
17 namespace content { 17 namespace content {
18 18
19 // Convert a WebString to ASCII, falling back on an empty string in the case 19 // Convert a WebString to ASCII, falling back on an empty string in the case
20 // of a non-ASCII string. 20 // of a non-ASCII string.
21 static std::string ToASCIIOrEmpty(const WebKit::WebString& string) { 21 static std::string ToASCIIOrEmpty(const WebKit::WebString& string) {
22 return IsStringASCII(string) ? UTF16ToASCII(string) : std::string(); 22 return IsStringASCII(string) ? UTF16ToASCII(string) : std::string();
23 } 23 }
24 24
25 class KeySystems { 25 class KeySystems {
26 public: 26 public:
27 bool IsSupportedKeySystem(const std::string& key_system); 27 static KeySystems* GetInstance();
28
29 void AddConcreteSupportedKeySystem(
30 const std::string& key_system,
31 #if defined(ENABLE_PEPPER_CDMS)
32 const std::string& pepper_type,
33 #elif defined(OS_ANDROID)
34 const uint8 uuid[16],
35 #endif // defined(ENABLE_PEPPER_CDMS)
36 bool use_aes_decryptor);
37
38 void AddParentKeySystem(const std::string& parent_key_system,
39 const std::string& concrete_key_system);
40
41 void AddSupportedType(const std::string& key_system,
42 const std::string& mime_type,
43 const std::string& codecs_list);
44
45 bool IsConcreteSupportedKeySystem(const std::string& key_system);
28 46
29 bool IsSupportedKeySystemWithMediaMimeType( 47 bool IsSupportedKeySystemWithMediaMimeType(
30 const std::string& mime_type, 48 const std::string& mime_type,
31 const std::vector<std::string>& codecs, 49 const std::vector<std::string>& codecs,
32 const std::string& key_system); 50 const std::string& key_system);
33 51
52 bool UseAesDecryptor(const std::string& concrete_key_system);
53
54 #if defined(ENABLE_PEPPER_CDMS)
55 std::string GetPepperType(const std::string& concrete_key_system);
56 #endif // defined(ENABLE_PEPPER_CDMS)
57
58 #if defined(OS_ANDROID)
59 std::vector<uint8> GetUUID(const std::string& concrete_key_system);
60 #endif // defined(OS_ANDROID)
61
34 private: 62 private:
35 friend struct base::DefaultLazyInstanceTraits<KeySystems>; 63 friend struct base::DefaultLazyInstanceTraits<KeySystems>;
36 64
37 typedef base::hash_set<std::string> CodecMappings; 65 typedef base::hash_set<std::string> CodecMappings;
38 typedef std::map<std::string, CodecMappings> MimeTypeMappings; 66 typedef std::map<std::string, CodecMappings> MimeTypeMappings;
39 typedef std::map<std::string, MimeTypeMappings> KeySystemMappings;
40 67
41 KeySystems(); 68 struct KeySystemProperties {
69 KeySystemProperties() : use_aes_decryptor(false) {}
70
71 #if defined(ENABLE_PEPPER_CDMS)
72 std::string pepper_type;
73 #elif defined(OS_ANDROID)
74 std::vector<uint8> uuid;
75 #endif // defined(ENABLE_PEPPER_CDMS)
76 bool use_aes_decryptor;
77 MimeTypeMappings types;
78 };
79
80 typedef std::map<std::string, KeySystemProperties> KeySystemMappings;
81
82 typedef std::map<std::string, std::string> ParentKeySystemMappings;
83
84 KeySystems() {}
42 85
43 bool IsSupportedKeySystemWithContainerAndCodec( 86 bool IsSupportedKeySystemWithContainerAndCodec(
44 const std::string& mime_type, 87 const std::string& mime_type,
45 const std::string& codec, 88 const std::string& codec,
46 const std::string& key_system); 89 const std::string& key_system);
47 90
91 // Map from key system string to capabilities.
48 KeySystemMappings key_system_map_; 92 KeySystemMappings key_system_map_;
49 93
94 // Map from parent key system to the concrete key system that should be used
95 // to represent its capabilities.
96 ParentKeySystemMappings parent_key_system_map_;
97
50 DISALLOW_COPY_AND_ASSIGN(KeySystems); 98 DISALLOW_COPY_AND_ASSIGN(KeySystems);
51 }; 99 };
52 100
53 static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER; 101 static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER;
54 102
55 KeySystems::KeySystems() { 103 KeySystems* KeySystems::GetInstance() {
56 // Initialize the supported media type/key system combinations. 104 KeySystems* key_systems = &g_key_systems.Get();
57 for (int i = 0; i < kNumSupportedFormatKeySystemCombinations; ++i) { 105 // TODO(ddorwin): Call out to ContentClient to register key systems.
58 const MediaFormatAndKeySystem& combination = 106 static bool is_registered = false;
59 kSupportedFormatKeySystemCombinations[i]; 107 if (!is_registered) {
60 std::vector<std::string> mime_type_codecs; 108 is_registered = true; // Prevent reentrancy when Add*() is called.
61 net::ParseCodecString(combination.codecs_list, 109 RegisterKeySystems();
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 } 110 }
111 return key_systems;
86 } 112 }
87 113
88 bool KeySystems::IsSupportedKeySystem(const std::string& key_system) { 114 void KeySystems::AddConcreteSupportedKeySystem(
89 bool is_supported = key_system_map_.find(key_system) != key_system_map_.end(); 115 const std::string& key_system,
90 return is_supported && !IsOSIncompatible(key_system); 116 #if defined(ENABLE_PEPPER_CDMS)
117 const std::string& pepper_type,
118 #elif defined(OS_ANDROID)
119 const uint8 uuid[16],
120 #endif // defined(ENABLE_PEPPER_CDMS)
121 bool use_aes_decryptor) {
122 KeySystemMappings::iterator key_system_iter =
123 key_system_map_.find(key_system);
124 DCHECK(key_system_iter == key_system_map_.end())
125 << "Key system already registered";
126
127 KeySystemProperties properties;
128 #if defined(ENABLE_PEPPER_CDMS)
129 properties.pepper_type = pepper_type;
130 #elif defined(OS_ANDROID)
131 properties.uuid.assign(uuid, uuid + 16);
132 #endif // defined(ENABLE_PEPPER_CDMS)
133 properties.use_aes_decryptor = use_aes_decryptor;
134 key_system_map_[key_system] = properties;
135 }
136
137 void KeySystems::AddParentKeySystem(const std::string& parent_key_system,
138 const std::string& concrete_key_system) {
139 DCHECK(key_system_map_.find(concrete_key_system) != key_system_map_.end());
140 parent_key_system_map_[parent_key_system] = concrete_key_system;
141 }
142
143 void KeySystems::AddSupportedType(const std::string& key_system,
144 const std::string& mime_type,
145 const std::string& codecs_list) {
146 std::vector<std::string> mime_type_codecs;
147 net::ParseCodecString(codecs_list,
148 &mime_type_codecs,
149 false);
150
151 CodecMappings codecs;
152 for (size_t j = 0; j < mime_type_codecs.size(); ++j)
153 codecs.insert(mime_type_codecs[j]);
154 // Support the MIME type string alone, without codec(s) specified.
155 codecs.insert(std::string());
156
157 KeySystemMappings::iterator key_system_iter =
158 key_system_map_.find(key_system);
159 DCHECK(key_system_iter != key_system_map_.end());
160 MimeTypeMappings& mime_types_map = key_system_iter->second.types;
161 // mime_types_map may not be repeated for a given key system.
162 DCHECK(mime_types_map.find(mime_type) == mime_types_map.end());
163 mime_types_map[mime_type] = codecs;
164 }
165
166 bool KeySystems::IsConcreteSupportedKeySystem(const std::string& key_system) {
167 return key_system_map_.find(key_system) != key_system_map_.end();
91 } 168 }
92 169
93 bool KeySystems::IsSupportedKeySystemWithContainerAndCodec( 170 bool KeySystems::IsSupportedKeySystemWithContainerAndCodec(
94 const std::string& mime_type, 171 const std::string& mime_type,
95 const std::string& codec, 172 const std::string& codec,
96 const std::string& key_system) { 173 const std::string& key_system) {
97 KeySystemMappings::const_iterator key_system_iter = 174 KeySystemMappings::const_iterator key_system_iter =
98 key_system_map_.find(key_system); 175 key_system_map_.find(key_system);
99 if (key_system_iter == key_system_map_.end()) 176 if (key_system_iter == key_system_map_.end())
100 return false; 177 return false;
101 178
102 const MimeTypeMappings& mime_types_map = key_system_iter->second; 179 const MimeTypeMappings& mime_types_map = key_system_iter->second.types;
103 MimeTypeMappings::const_iterator mime_iter = mime_types_map.find(mime_type); 180 MimeTypeMappings::const_iterator mime_iter = mime_types_map.find(mime_type);
104 if (mime_iter == mime_types_map.end()) 181 if (mime_iter == mime_types_map.end())
105 return false; 182 return false;
106 183
107 const CodecMappings& codecs = mime_iter->second; 184 const CodecMappings& codecs = mime_iter->second;
108 return (codecs.find(codec) != codecs.end()) && !IsOSIncompatible(key_system); 185 return (codecs.find(codec) != codecs.end());
109 } 186 }
110 187
111 bool KeySystems::IsSupportedKeySystemWithMediaMimeType( 188 bool KeySystems::IsSupportedKeySystemWithMediaMimeType(
112 const std::string& mime_type, 189 const std::string& mime_type,
113 const std::vector<std::string>& codecs, 190 const std::vector<std::string>& codecs,
114 const std::string& key_system) { 191 const std::string& key_system) {
192 // If |key_system| is a parent key_system, use its concrete child.
193 // Otherwise, use |key_system|.
194 std::string concrete_key_system;
195 ParentKeySystemMappings::iterator parent_key_system_iter =
196 parent_key_system_map_.find(key_system);
197 if (parent_key_system_iter != parent_key_system_map_.end())
198 concrete_key_system = parent_key_system_iter->second;
199 else
200 concrete_key_system = key_system;
201
115 // This method is only used by the canPlaytType() path (not the EME methods), 202 // This method is only used by the canPlaytType() path (not the EME methods),
116 // so we check for suppressed key_systems here. 203 // so we check for suppressed key_systems here.
117 if(IsCanPlayTypeSuppressed(key_system)) 204 if(IsCanPlayTypeSuppressed(concrete_key_system))
118 return false; 205 return false;
119 206
120 if (codecs.empty()) 207 if (codecs.empty())
121 return IsSupportedKeySystemWithContainerAndCodec( 208 return IsSupportedKeySystemWithContainerAndCodec(
122 mime_type, std::string(), key_system); 209 mime_type, std::string(), concrete_key_system);
123 210
124 for (size_t i = 0; i < codecs.size(); ++i) { 211 for (size_t i = 0; i < codecs.size(); ++i) {
125 if (!IsSupportedKeySystemWithContainerAndCodec( 212 if (!IsSupportedKeySystemWithContainerAndCodec(
126 mime_type, codecs[i], key_system)) 213 mime_type, codecs[i], concrete_key_system))
127 return false; 214 return false;
128 } 215 }
129 216
130 return true; 217 return true;
131 } 218 }
132 219
133 static inline bool IsConcreteSupportedKeySystem(const std::string& key_system) { 220 bool KeySystems::UseAesDecryptor(const std::string& concrete_key_system) {
134 bool result = g_key_systems.Get().IsSupportedKeySystem(key_system); 221 KeySystemMappings::iterator key_system_iter =
135 // Verify the two "Concrete" lists are in sync. 222 key_system_map_.find(concrete_key_system);
136 DCHECK_EQ(result, IsConcreteKeySystem(key_system)); 223 DCHECK(key_system_iter != key_system_map_.end())
137 return result; 224 << concrete_key_system << " is not a known concrete system";
225 return key_system_iter->second.use_aes_decryptor;
226 }
227
228 #if defined(ENABLE_PEPPER_CDMS)
229 std::string KeySystems::GetPepperType(const std::string& concrete_key_system) {
230 KeySystemMappings::iterator key_system_iter =
231 key_system_map_.find(concrete_key_system);
232 DCHECK(key_system_iter != key_system_map_.end())
233 << concrete_key_system << " is not a known concrete system";
234 const std::string& type = key_system_iter->second.pepper_type;
235 DCHECK(!type.empty()) << concrete_key_system << " is not Pepper-based";
236 return type;
237 }
238 #endif // defined(ENABLE_PEPPER_CDMS)
239
240 #if defined(OS_ANDROID)
241 std::vector<uint8> KeySystems::GetUUID(const std::string& concrete_key_system) {
242 KeySystemMappings::iterator key_system_iter =
243 key_system_map_.find(concrete_key_system);
244 DCHECK(key_system_iter != key_system_map_.end())
245 << concrete_key_system << " is not a known concrete system";
246 return key_system_iter->second.uuid;
247 }
248 #endif // defined(OS_ANDROID)
249
250 //------------------------------------------------------------------------------
251
252 void AddConcreteSupportedKeySystem(
253 const std::string& key_system,
254 #if defined(ENABLE_PEPPER_CDMS)
255 const std::string& pepper_type,
256 #elif defined(OS_ANDROID)
257 const uint8 uuid[16],
258 #endif
259 bool use_aes_decryptor) {
260 KeySystems::GetInstance()->AddConcreteSupportedKeySystem(key_system,
261 #if defined(ENABLE_PEPPER_CDMS)
262 pepper_type,
263 #elif defined(OS_ANDROID)
264 uuid,
265 #endif
266 use_aes_decryptor);
267 }
268
269 void AddParentKeySystem(const std::string& parent_key_system,
270 const std::string& concrete_key_system) {
271 KeySystems::GetInstance()->AddParentKeySystem(parent_key_system,
272 concrete_key_system);
273 }
274
275 void AddSupportedType(const std::string& key_system,
276 const std::string& mime_type,
277 const std::string& codecs_list) {
278 KeySystems::GetInstance()->AddSupportedType(key_system,
279 mime_type, codecs_list);
138 } 280 }
139 281
140 bool IsConcreteSupportedKeySystem(const WebKit::WebString& key_system) { 282 bool IsConcreteSupportedKeySystem(const WebKit::WebString& key_system) {
141 return IsConcreteSupportedKeySystem(ToASCIIOrEmpty(key_system)); 283 return KeySystems::GetInstance()->IsConcreteSupportedKeySystem(
284 ToASCIIOrEmpty(key_system));
142 } 285 }
143 286
144 bool IsSupportedKeySystemWithMediaMimeType( 287 bool IsSupportedKeySystemWithMediaMimeType(
145 const std::string& mime_type, 288 const std::string& mime_type,
146 const std::vector<std::string>& codecs, 289 const std::vector<std::string>& codecs,
147 const std::string& key_system) { 290 const std::string& key_system) {
148 std::string concrete_key_system = EnsureConcreteKeySystem(key_system); 291 return KeySystems::GetInstance()->IsSupportedKeySystemWithMediaMimeType(
149 return g_key_systems.Get().IsSupportedKeySystemWithMediaMimeType( 292 mime_type, codecs, key_system);
150 mime_type, codecs, concrete_key_system);
151 } 293 }
152 294
153 std::string KeySystemNameForUMA(const WebKit::WebString& key_system) { 295 std::string KeySystemNameForUMA(const WebKit::WebString& key_system) {
154 return KeySystemNameForUMAInternal(key_system); 296 return KeySystemNameForUMAInternal(key_system);
155 } 297 }
156 298
157 bool CanUseAesDecryptor(const std::string& key_system) { 299 bool CanUseAesDecryptor(const std::string& concrete_key_system) {
158 return CanUseAesDecryptorInternal(key_system); 300 return KeySystems::GetInstance()->UseAesDecryptor(concrete_key_system);
159 } 301 }
160 302
161 #if defined(ENABLE_PEPPER_CDMS) 303 #if defined(ENABLE_PEPPER_CDMS)
162 std::string GetPepperType(const std::string& concrete_key_system) { 304 std::string GetPepperType(const std::string& concrete_key_system) {
163 DCHECK(IsConcreteKeySystem(concrete_key_system)) 305 return KeySystems::GetInstance()->GetPepperType(concrete_key_system);
164 << concrete_key_system << " is not a concrete system";
165 for (int i = 0; i < kNumKeySystemToPepperTypeMapping; ++i) {
166 if (kKeySystemToPepperTypeMapping[i].key_system == concrete_key_system)
167 return kKeySystemToPepperTypeMapping[i].type;
168 }
169
170 return std::string();
171 } 306 }
172 #endif // defined(ENABLE_PEPPER_CDMS) 307 #endif // defined(ENABLE_PEPPER_CDMS)
173 308
174 #if defined(OS_ANDROID) 309 #if defined(OS_ANDROID)
175 std::vector<uint8> GetUUID(const std::string& concrete_key_system) { 310 std::vector<uint8> GetUUID(const std::string& concrete_key_system) {
176 DCHECK(IsConcreteKeySystem(concrete_key_system)) 311 return KeySystems::GetInstance()->GetUUID(concrete_key_system);
177 << concrete_key_system << " is not a concrete system";
178 for (int i = 0; i < kNumKeySystemToUUIDMapping; ++i) {
179 if (kKeySystemToUUIDMapping[i].key_system == concrete_key_system)
180 return std::vector<uint8>(kKeySystemToUUIDMapping[i].uuid,
181 kKeySystemToUUIDMapping[i].uuid + 16);
182 }
183 return std::vector<uint8>();
184 } 312 }
185 #endif // defined(OS_ANDROID) 313 #endif // defined(OS_ANDROID)
186 314
187 } // namespace content 315 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698