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) { | |
ddorwin
2014/03/05 22:11:29
I still think it's worth commenting that we only d
xhwang
2014/03/06 18:09:57
Done.
| |
67 if (key_system == kWidevineKeySystem) { | |
68 return std::vector<uint8>(kWidevineUuid, | |
69 kWidevineUuid + arraysize(kWidevineUuid)); | |
70 } | |
71 return std::vector<uint8>(); | |
72 } | |
60 | 73 |
61 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the | 74 // 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 | 75 // "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. | 76 // found and successfully parsed. Returns false otherwise. |
64 // Notes: | 77 // Notes: |
65 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box | 78 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box |
66 // will be set in |pssh_data|. | 79 // will be set in |pssh_data|. |
67 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. | 80 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. |
68 static bool GetPsshData(const uint8* data, int data_size, | 81 static bool GetPsshData(const uint8* data, int data_size, |
69 const std::vector<uint8>& uuid, | 82 const std::vector<uint8>& uuid, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 // static | 181 // static |
169 bool MediaDrmBridge::IsAvailable() { | 182 bool MediaDrmBridge::IsAvailable() { |
170 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; | 183 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; |
171 } | 184 } |
172 | 185 |
173 // static | 186 // static |
174 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 187 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
175 return SECURITY_LEVEL_1 == security_level; | 188 return SECURITY_LEVEL_1 == security_level; |
176 } | 189 } |
177 | 190 |
178 bool MediaDrmBridge::IsSecurityLevelSupported( | 191 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, |
179 const std::vector<uint8>& scheme_uuid, | 192 SecurityLevel security_level) { |
180 SecurityLevel security_level) { | |
181 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in | 193 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in |
182 // creation time of MediaDrmBridge. | 194 // creation time of MediaDrmBridge. |
183 scoped_ptr<MediaDrmBridge> media_drm_bridge = | 195 scoped_ptr<MediaDrmBridge> media_drm_bridge = |
184 MediaDrmBridge::Create(0, scheme_uuid, GURL(), NULL); | 196 MediaDrmBridge::Create(0, key_system, GURL(), NULL); |
185 if (!media_drm_bridge) | 197 if (!media_drm_bridge) |
186 return false; | 198 return false; |
187 | 199 |
188 return media_drm_bridge->SetSecurityLevel(security_level); | 200 return media_drm_bridge->SetSecurityLevel(security_level); |
189 } | 201 } |
190 | 202 |
191 bool MediaDrmBridge::IsCryptoSchemeSupported( | 203 bool MediaDrmBridge::IsKeySystemSupported( |
192 const std::vector<uint8>& scheme_uuid, | 204 const std::string& key_system, |
193 const std::string& container_mime_type) { | 205 const std::string& container_mime_type) { |
206 std::vector<uint8> scheme_uuid = GetUUID(key_system); | |
207 if (scheme_uuid.empty()) | |
208 return false; | |
209 | |
194 JNIEnv* env = AttachCurrentThread(); | 210 JNIEnv* env = AttachCurrentThread(); |
195 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 211 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
196 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 212 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
197 ScopedJavaLocalRef<jstring> j_container_mime_type = | 213 ScopedJavaLocalRef<jstring> j_container_mime_type = |
198 ConvertUTF8ToJavaString(env, container_mime_type); | 214 ConvertUTF8ToJavaString(env, container_mime_type); |
199 return Java_MediaDrmBridge_isCryptoSchemeSupported( | 215 return Java_MediaDrmBridge_isCryptoSchemeSupported( |
200 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | 216 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); |
201 } | 217 } |
202 | 218 |
203 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 219 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
(...skipping 17 matching lines...) Expand all Loading... | |
221 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); | 237 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); |
222 } | 238 } |
223 | 239 |
224 MediaDrmBridge::~MediaDrmBridge() { | 240 MediaDrmBridge::~MediaDrmBridge() { |
225 JNIEnv* env = AttachCurrentThread(); | 241 JNIEnv* env = AttachCurrentThread(); |
226 if (!j_media_drm_.is_null()) | 242 if (!j_media_drm_.is_null()) |
227 Java_MediaDrmBridge_release(env, j_media_drm_.obj()); | 243 Java_MediaDrmBridge_release(env, j_media_drm_.obj()); |
228 } | 244 } |
229 | 245 |
230 // static | 246 // static |
231 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( | 247 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, |
232 int cdm_id, | 248 const std::string& key_system, |
233 const std::vector<uint8>& scheme_uuid, | 249 const GURL& frame_url, |
234 const GURL& frame_url, | 250 MediaPlayerManager* manager) { |
235 MediaPlayerManager* manager) { | |
236 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 251 scoped_ptr<MediaDrmBridge> media_drm_bridge; |
252 if (!IsAvailable()) | |
253 return media_drm_bridge.Pass(); | |
237 | 254 |
238 if (IsAvailable() && !scheme_uuid.empty()) { | 255 std::vector<uint8> scheme_uuid = GetUUID(key_system); |
239 // TODO(qinmin): check whether the uuid is valid. | 256 if (scheme_uuid.empty()) |
240 media_drm_bridge.reset( | 257 return media_drm_bridge.Pass(); |
241 new MediaDrmBridge(cdm_id, scheme_uuid, frame_url, manager)); | 258 |
242 if (media_drm_bridge->j_media_drm_.is_null()) | 259 media_drm_bridge.reset( |
243 media_drm_bridge.reset(); | 260 new MediaDrmBridge(cdm_id, scheme_uuid, frame_url, manager)); |
244 } | 261 if (media_drm_bridge->j_media_drm_.is_null()) |
262 media_drm_bridge.reset(); | |
245 | 263 |
246 return media_drm_bridge.Pass(); | 264 return media_drm_bridge.Pass(); |
247 } | 265 } |
248 | 266 |
249 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { | 267 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { |
250 JNIEnv* env = AttachCurrentThread(); | 268 JNIEnv* env = AttachCurrentThread(); |
251 | 269 |
252 std::string security_level_str = GetSecurityLevelString(security_level); | 270 std::string security_level_str = GetSecurityLevelString(security_level); |
253 if (security_level_str.empty()) | 271 if (security_level_str.empty()) |
254 return false; | 272 return false; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
396 JNIEnv* env = AttachCurrentThread(); | 414 JNIEnv* env = AttachCurrentThread(); |
397 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 415 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
398 } | 416 } |
399 | 417 |
400 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 418 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
401 JNIEnv* env, jobject, bool success) { | 419 JNIEnv* env, jobject, bool success) { |
402 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 420 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
403 } | 421 } |
404 | 422 |
405 } // namespace media | 423 } // namespace media |
OLD | NEW |