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

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

Powered by Google App Engine
This is Rietveld 408576698