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 "base/android/build_info.h" | 7 #include "base/android/build_info.h" |
8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "jni/MediaDrmBridge_jni.h" | 15 #include "jni/MediaDrmBridge_jni.h" |
16 #include "media/base/android/media_player_manager.h" | 16 #include "media/base/android/media_player_manager.h" |
17 | 17 |
| 18 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
| 19 |
18 using base::android::AttachCurrentThread; | 20 using base::android::AttachCurrentThread; |
19 using base::android::ConvertUTF8ToJavaString; | 21 using base::android::ConvertUTF8ToJavaString; |
20 using base::android::ConvertJavaStringToUTF8; | 22 using base::android::ConvertJavaStringToUTF8; |
21 using base::android::JavaByteArrayToByteVector; | 23 using base::android::JavaByteArrayToByteVector; |
22 using base::android::ScopedJavaLocalRef; | 24 using base::android::ScopedJavaLocalRef; |
23 | 25 |
24 namespace media { | 26 namespace media { |
25 | 27 |
26 static uint32 ReadUint32(const uint8_t* data) { | 28 static uint32 ReadUint32(const uint8_t* data) { |
27 uint32 value = 0; | 29 uint32 value = 0; |
(...skipping 15 matching lines...) Expand all Loading... |
43 // | 45 // |
44 // PSSH { | 46 // PSSH { |
45 // uint32 Size | 47 // uint32 Size |
46 // uint32 Type | 48 // uint32 Type |
47 // uint64 LargeSize # Field is only present if value(Size) == 1. | 49 // uint64 LargeSize # Field is only present if value(Size) == 1. |
48 // uint32 VersionAndFlags | 50 // uint32 VersionAndFlags |
49 // uint8[16] SystemId | 51 // uint8[16] SystemId |
50 // uint32 DataSize | 52 // uint32 DataSize |
51 // uint8[DataSize] Data | 53 // uint8[DataSize] Data |
52 // } | 54 // } |
53 static const int kBoxHeaderSize = 8; // Box's header contains Size and Type. | 55 const int kBoxHeaderSize = 8; // Box's header contains Size and Type. |
54 static const int kBoxLargeSizeSize = 8; | 56 const int kBoxLargeSizeSize = 8; |
55 static const int kPsshVersionFlagSize = 4; | 57 const int kPsshVersionFlagSize = 4; |
56 static const int kPsshSystemIdSize = 16; | 58 const int kPsshSystemIdSize = 16; |
57 static const int kPsshDataSizeSize = 4; | 59 const int kPsshDataSizeSize = 4; |
58 static const uint32 kTencType = 0x74656e63; | 60 const uint32 kTencType = 0x74656e63; |
59 static const uint32 kPsshType = 0x70737368; | 61 const uint32 kPsshType = 0x70737368; |
| 62 const uint8 kWidevineUuid[16] = { |
| 63 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
| 64 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
| 65 |
| 66 static std::vector<uint8> GetUUID(const std::string& key_system) { |
| 67 // For security reasons, we only do exact string comparisons here - we don't |
| 68 // try to parse the |key_system| in any way. |
| 69 if (key_system == kWidevineKeySystem) { |
| 70 return std::vector<uint8>(kWidevineUuid, |
| 71 kWidevineUuid + arraysize(kWidevineUuid)); |
| 72 } |
| 73 return std::vector<uint8>(); |
| 74 } |
60 | 75 |
61 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the | 76 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the |
62 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is | 77 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is |
63 // found and successfully parsed. Returns false otherwise. | 78 // found and successfully parsed. Returns false otherwise. |
64 // Notes: | 79 // Notes: |
65 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box | 80 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box |
66 // will be set in |pssh_data|. | 81 // will be set in |pssh_data|. |
67 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. | 82 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. |
68 static bool GetPsshData(const uint8* data, int data_size, | 83 static bool GetPsshData(const uint8* data, int data_size, |
69 const std::vector<uint8>& uuid, | 84 const std::vector<uint8>& uuid, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 // static | 183 // static |
169 bool MediaDrmBridge::IsAvailable() { | 184 bool MediaDrmBridge::IsAvailable() { |
170 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; | 185 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; |
171 } | 186 } |
172 | 187 |
173 // static | 188 // static |
174 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 189 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
175 return SECURITY_LEVEL_1 == security_level; | 190 return SECURITY_LEVEL_1 == security_level; |
176 } | 191 } |
177 | 192 |
178 bool MediaDrmBridge::IsSecurityLevelSupported( | 193 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, |
179 const std::vector<uint8>& scheme_uuid, | 194 SecurityLevel security_level) { |
180 SecurityLevel security_level) { | |
181 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in | 195 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in |
182 // creation time of MediaDrmBridge. | 196 // creation time of MediaDrmBridge. |
183 scoped_ptr<MediaDrmBridge> media_drm_bridge = | 197 scoped_ptr<MediaDrmBridge> media_drm_bridge = |
184 MediaDrmBridge::Create(0, scheme_uuid, GURL(), NULL); | 198 MediaDrmBridge::Create(0, key_system, GURL(), NULL); |
185 if (!media_drm_bridge) | 199 if (!media_drm_bridge) |
186 return false; | 200 return false; |
187 | 201 |
188 return media_drm_bridge->SetSecurityLevel(security_level); | 202 return media_drm_bridge->SetSecurityLevel(security_level); |
189 } | 203 } |
190 | 204 |
191 bool MediaDrmBridge::IsCryptoSchemeSupported( | 205 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
192 const std::vector<uint8>& scheme_uuid, | 206 const std::string& key_system, |
193 const std::string& container_mime_type) { | 207 const std::string& container_mime_type) { |
| 208 std::vector<uint8> scheme_uuid = GetUUID(key_system); |
| 209 if (scheme_uuid.empty()) |
| 210 return false; |
| 211 |
194 JNIEnv* env = AttachCurrentThread(); | 212 JNIEnv* env = AttachCurrentThread(); |
195 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 213 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
196 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 214 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
197 ScopedJavaLocalRef<jstring> j_container_mime_type = | 215 ScopedJavaLocalRef<jstring> j_container_mime_type = |
198 ConvertUTF8ToJavaString(env, container_mime_type); | 216 ConvertUTF8ToJavaString(env, container_mime_type); |
199 return Java_MediaDrmBridge_isCryptoSchemeSupported( | 217 return Java_MediaDrmBridge_isCryptoSchemeSupported( |
200 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | 218 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); |
201 } | 219 } |
202 | 220 |
203 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 221 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
(...skipping 17 matching lines...) Expand all Loading... |
221 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); | 239 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); |
222 } | 240 } |
223 | 241 |
224 MediaDrmBridge::~MediaDrmBridge() { | 242 MediaDrmBridge::~MediaDrmBridge() { |
225 JNIEnv* env = AttachCurrentThread(); | 243 JNIEnv* env = AttachCurrentThread(); |
226 if (!j_media_drm_.is_null()) | 244 if (!j_media_drm_.is_null()) |
227 Java_MediaDrmBridge_release(env, j_media_drm_.obj()); | 245 Java_MediaDrmBridge_release(env, j_media_drm_.obj()); |
228 } | 246 } |
229 | 247 |
230 // static | 248 // static |
231 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( | 249 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, |
232 int cdm_id, | 250 const std::string& key_system, |
233 const std::vector<uint8>& scheme_uuid, | 251 const GURL& frame_url, |
234 const GURL& frame_url, | 252 MediaPlayerManager* manager) { |
235 MediaPlayerManager* manager) { | |
236 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 253 scoped_ptr<MediaDrmBridge> media_drm_bridge; |
| 254 if (!IsAvailable()) |
| 255 return media_drm_bridge.Pass(); |
237 | 256 |
238 if (IsAvailable() && !scheme_uuid.empty()) { | 257 std::vector<uint8> scheme_uuid = GetUUID(key_system); |
239 // TODO(qinmin): check whether the uuid is valid. | 258 if (scheme_uuid.empty()) |
240 media_drm_bridge.reset( | 259 return media_drm_bridge.Pass(); |
241 new MediaDrmBridge(cdm_id, scheme_uuid, frame_url, manager)); | 260 |
242 if (media_drm_bridge->j_media_drm_.is_null()) | 261 media_drm_bridge.reset( |
243 media_drm_bridge.reset(); | 262 new MediaDrmBridge(cdm_id, scheme_uuid, frame_url, manager)); |
244 } | 263 if (media_drm_bridge->j_media_drm_.is_null()) |
| 264 media_drm_bridge.reset(); |
245 | 265 |
246 return media_drm_bridge.Pass(); | 266 return media_drm_bridge.Pass(); |
247 } | 267 } |
248 | 268 |
249 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { | 269 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { |
250 JNIEnv* env = AttachCurrentThread(); | 270 JNIEnv* env = AttachCurrentThread(); |
251 | 271 |
252 std::string security_level_str = GetSecurityLevelString(security_level); | 272 std::string security_level_str = GetSecurityLevelString(security_level); |
253 if (security_level_str.empty()) | 273 if (security_level_str.empty()) |
254 return false; | 274 return false; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 JNIEnv* env = AttachCurrentThread(); | 416 JNIEnv* env = AttachCurrentThread(); |
397 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 417 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
398 } | 418 } |
399 | 419 |
400 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 420 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
401 JNIEnv* env, jobject, bool success) { | 421 JNIEnv* env, jobject, bool success) { |
402 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 422 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
403 } | 423 } |
404 | 424 |
405 } // namespace media | 425 } // namespace media |
OLD | NEW |