OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/android/media_drm_bridge.h" | 5 #include "media/base/android/media_drm_bridge.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
10 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
11 #include "base/android/jni_string.h" | 11 #include "base/android/jni_string.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/lazy_instance.h" | |
13 #include "base/location.h" | 14 #include "base/location.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/message_loop/message_loop_proxy.h" | 16 #include "base/message_loop/message_loop_proxy.h" |
16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
17 #include "jni/MediaDrmBridge_jni.h" | 18 #include "jni/MediaDrmBridge_jni.h" |
18 #include "media/base/android/media_player_manager.h" | 19 #include "media/base/android/media_player_manager.h" |
19 | 20 |
20 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 21 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
21 | 22 |
22 using base::android::AttachCurrentThread; | 23 using base::android::AttachCurrentThread; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 const int kBoxLargeSizeSize = 8; | 59 const int kBoxLargeSizeSize = 8; |
59 const int kPsshVersionFlagSize = 4; | 60 const int kPsshVersionFlagSize = 4; |
60 const int kPsshSystemIdSize = 16; | 61 const int kPsshSystemIdSize = 16; |
61 const int kPsshDataSizeSize = 4; | 62 const int kPsshDataSizeSize = 4; |
62 const uint32 kTencType = 0x74656e63; | 63 const uint32 kTencType = 0x74656e63; |
63 const uint32 kPsshType = 0x70737368; | 64 const uint32 kPsshType = 0x70737368; |
64 const uint8 kWidevineUuid[16] = { | 65 const uint8 kWidevineUuid[16] = { |
65 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, | 66 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
66 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; | 67 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
67 | 68 |
68 static std::vector<uint8> GetUUID(const std::string& key_system) { | 69 typedef std::vector<uint8> UUID; |
xhwang
2014/05/21 17:11:08
nit: Add an empty line after this.
ycheo (away)
2014/05/21 23:35:11
Done.
| |
69 // For security reasons, we only do exact string comparisons here - we don't | 70 class KeySystemUuidManager { |
70 // try to parse the |key_system| in any way. | 71 public: |
71 if (key_system == kWidevineKeySystem) { | 72 KeySystemUuidManager(); |
72 return std::vector<uint8>(kWidevineUuid, | 73 UUID GetUUID(const std::string& key_system); |
73 kWidevineUuid + arraysize(kWidevineUuid)); | 74 void AddMapping(const std::string& key_system, const UUID& uuid); |
74 } | 75 |
75 return std::vector<uint8>(); | 76 private: |
77 typedef base::hash_map<std::string, UUID> KeySystemUuidMap; | |
xhwang
2014/05/21 17:11:08
add include for hash_map
ycheo (away)
2014/05/21 23:35:11
Done.
| |
78 | |
79 KeySystemUuidMap key_system_uuid_map_; | |
80 | |
81 DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager); | |
82 }; | |
83 | |
84 KeySystemUuidManager::KeySystemUuidManager() { | |
85 key_system_uuid_map_[kWidevineKeySystem] = | |
xhwang
2014/05/21 17:11:08
Add a comment that Widevine is always supported.
ycheo (away)
2014/05/21 23:35:11
Done.
| |
86 UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); | |
76 } | 87 } |
77 | 88 |
89 UUID KeySystemUuidManager::GetUUID(const std::string& key_system) { | |
90 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); | |
91 if (it == key_system_uuid_map_.end()) | |
92 return UUID(); | |
93 return it->second; | |
94 } | |
95 | |
96 void KeySystemUuidManager::AddMapping(const std::string& key_system, | |
97 const UUID& uuid) { | |
98 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); | |
99 DCHECK(it == key_system_uuid_map_.end()) | |
100 << "Shouldn't overwrite the existing keysystem"; | |
xhwang
2014/05/21 17:11:08
nit: s/the/an/
nit: s/keysystem/key system/
nit: a
ycheo (away)
2014/05/21 23:35:11
Done.
| |
101 if (it != key_system_uuid_map_.end()) | |
102 return; | |
103 key_system_uuid_map_[key_system] = uuid; | |
104 } | |
105 | |
106 base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager = | |
107 LAZY_INSTANCE_INITIALIZER; | |
108 | |
78 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the | 109 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the |
79 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is | 110 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is |
80 // found and successfully parsed. Returns false otherwise. | 111 // found and successfully parsed. Returns false otherwise. |
81 // Notes: | 112 // Notes: |
82 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box | 113 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box |
83 // will be set in |pssh_data|. | 114 // will be set in |pssh_data|. |
84 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. | 115 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. |
85 static bool GetPsshData(const uint8* data, int data_size, | 116 static bool GetPsshData(const uint8* data, int data_size, |
86 const std::vector<uint8>& uuid, | 117 const UUID& uuid, |
87 std::vector<uint8>* pssh_data) { | 118 std::vector<uint8>* pssh_data) { |
88 const uint8* cur = data; | 119 const uint8* cur = data; |
89 const uint8* data_end = data + data_size; | 120 const uint8* data_end = data + data_size; |
90 int bytes_left = data_size; | 121 int bytes_left = data_size; |
91 | 122 |
92 while (bytes_left > 0) { | 123 while (bytes_left > 0) { |
93 const uint8* box_head = cur; | 124 const uint8* box_head = cur; |
94 | 125 |
95 if (bytes_left < kBoxHeaderSize) | 126 if (bytes_left < kBoxHeaderSize) |
96 return false; | 127 return false; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 // checks |key_system| support if |container_mime_type| is empty. | 217 // checks |key_system| support if |container_mime_type| is empty. |
187 // TODO(xhwang): The |container_mime_type| is not the same as contentType in | 218 // TODO(xhwang): The |container_mime_type| is not the same as contentType in |
188 // the EME spec. Revisit this once the spec issue with initData type is | 219 // the EME spec. Revisit this once the spec issue with initData type is |
189 // resolved. | 220 // resolved. |
190 static bool IsKeySystemSupportedWithTypeImpl( | 221 static bool IsKeySystemSupportedWithTypeImpl( |
191 const std::string& key_system, | 222 const std::string& key_system, |
192 const std::string& container_mime_type) { | 223 const std::string& container_mime_type) { |
193 if (!MediaDrmBridge::IsAvailable()) | 224 if (!MediaDrmBridge::IsAvailable()) |
194 return false; | 225 return false; |
195 | 226 |
196 std::vector<uint8> scheme_uuid = GetUUID(key_system); | 227 UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); |
197 if (scheme_uuid.empty()) | 228 if (scheme_uuid.empty()) |
198 return false; | 229 return false; |
199 | 230 |
200 JNIEnv* env = AttachCurrentThread(); | 231 JNIEnv* env = AttachCurrentThread(); |
201 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 232 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
202 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 233 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
203 ScopedJavaLocalRef<jstring> j_container_mime_type = | 234 ScopedJavaLocalRef<jstring> j_container_mime_type = |
204 ConvertUTF8ToJavaString(env, container_mime_type); | 235 ConvertUTF8ToJavaString(env, container_mime_type); |
205 return Java_MediaDrmBridge_isCryptoSchemeSupported( | 236 return Java_MediaDrmBridge_isCryptoSchemeSupported( |
206 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | 237 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); |
(...skipping 19 matching lines...) Expand all Loading... | |
226 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in | 257 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in |
227 // creation time of MediaDrmBridge. | 258 // creation time of MediaDrmBridge. |
228 scoped_ptr<MediaDrmBridge> media_drm_bridge = | 259 scoped_ptr<MediaDrmBridge> media_drm_bridge = |
229 MediaDrmBridge::Create(0, key_system, GURL(), NULL); | 260 MediaDrmBridge::Create(0, key_system, GURL(), NULL); |
230 if (!media_drm_bridge) | 261 if (!media_drm_bridge) |
231 return false; | 262 return false; |
232 | 263 |
233 return media_drm_bridge->SetSecurityLevel(security_level); | 264 return media_drm_bridge->SetSecurityLevel(security_level); |
234 } | 265 } |
235 | 266 |
267 //static | |
268 void MediaDrmBridge::AddKeySystemUuidMapping(const std::string& key_system, | |
xhwang
2014/05/21 17:11:08
Add a comment that this gives other platforms a ch
ycheo (away)
2014/05/21 23:35:11
Applied this on the header.
| |
269 const std::vector<uint8>& uuid) { | |
270 g_key_system_uuid_manager.Get().AddMapping(key_system, uuid); | |
271 } | |
272 | |
236 // static | 273 // static |
237 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 274 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
238 DCHECK(!key_system.empty()); | 275 DCHECK(!key_system.empty()); |
239 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 276 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
240 } | 277 } |
241 | 278 |
242 // static | 279 // static |
243 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 280 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
244 const std::string& key_system, | 281 const std::string& key_system, |
245 const std::string& container_mime_type) { | 282 const std::string& container_mime_type) { |
(...skipping 30 matching lines...) Expand all Loading... | |
276 | 313 |
277 // static | 314 // static |
278 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, | 315 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, |
279 const std::string& key_system, | 316 const std::string& key_system, |
280 const GURL& security_origin, | 317 const GURL& security_origin, |
281 MediaPlayerManager* manager) { | 318 MediaPlayerManager* manager) { |
282 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 319 scoped_ptr<MediaDrmBridge> media_drm_bridge; |
283 if (!IsAvailable()) | 320 if (!IsAvailable()) |
284 return media_drm_bridge.Pass(); | 321 return media_drm_bridge.Pass(); |
285 | 322 |
286 std::vector<uint8> scheme_uuid = GetUUID(key_system); | 323 UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); |
287 if (scheme_uuid.empty()) | 324 if (scheme_uuid.empty()) |
288 return media_drm_bridge.Pass(); | 325 return media_drm_bridge.Pass(); |
289 | 326 |
290 media_drm_bridge.reset( | 327 media_drm_bridge.reset( |
291 new MediaDrmBridge(cdm_id, scheme_uuid, security_origin, manager)); | 328 new MediaDrmBridge(cdm_id, scheme_uuid, security_origin, manager)); |
292 if (media_drm_bridge->j_media_drm_.is_null()) | 329 if (media_drm_bridge->j_media_drm_.is_null()) |
293 media_drm_bridge.reset(); | 330 media_drm_bridge.reset(); |
294 | 331 |
295 return media_drm_bridge.Pass(); | 332 return media_drm_bridge.Pass(); |
296 } | 333 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 JNIEnv* env = AttachCurrentThread(); | 494 JNIEnv* env = AttachCurrentThread(); |
458 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 495 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
459 } | 496 } |
460 | 497 |
461 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 498 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
462 JNIEnv* env, jobject, bool success) { | 499 JNIEnv* env, jobject, bool success) { |
463 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 500 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
464 } | 501 } |
465 | 502 |
466 } // namespace media | 503 } // namespace media |
OLD | NEW |