| 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> |
| 8 |
| 7 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 8 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
| 9 #include "base/android/jni_string.h" | 11 #include "base/android/jni_string.h" |
| 10 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 11 #include "base/location.h" | 13 #include "base/location.h" |
| 12 #include "base/logging.h" | 14 #include "base/logging.h" |
| 13 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 14 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 15 #include "jni/MediaDrmBridge_jni.h" | 17 #include "jni/MediaDrmBridge_jni.h" |
| 16 #include "media/base/android/media_player_manager.h" | 18 #include "media/base/android/media_player_manager.h" |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 case MediaDrmBridge::SECURITY_LEVEL_NONE: | 175 case MediaDrmBridge::SECURITY_LEVEL_NONE: |
| 174 return ""; | 176 return ""; |
| 175 case MediaDrmBridge::SECURITY_LEVEL_1: | 177 case MediaDrmBridge::SECURITY_LEVEL_1: |
| 176 return "L1"; | 178 return "L1"; |
| 177 case MediaDrmBridge::SECURITY_LEVEL_3: | 179 case MediaDrmBridge::SECURITY_LEVEL_3: |
| 178 return "L3"; | 180 return "L3"; |
| 179 } | 181 } |
| 180 return ""; | 182 return ""; |
| 181 } | 183 } |
| 182 | 184 |
| 185 // Checks whether |key_system| is supported with |container_mime_type|. Only |
| 186 // checks |key_system| support if |container_mime_type| is empty. |
| 187 // 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 |
| 189 // resolved. |
| 190 static bool IsKeySystemSupportedWithTypeImpl( |
| 191 const std::string& key_system, |
| 192 const std::string& container_mime_type) { |
| 193 if (!MediaDrmBridge::IsAvailable()) |
| 194 return false; |
| 195 |
| 196 std::vector<uint8> scheme_uuid = GetUUID(key_system); |
| 197 if (scheme_uuid.empty()) |
| 198 return false; |
| 199 |
| 200 JNIEnv* env = AttachCurrentThread(); |
| 201 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
| 202 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
| 203 ScopedJavaLocalRef<jstring> j_container_mime_type = |
| 204 ConvertUTF8ToJavaString(env, container_mime_type); |
| 205 return Java_MediaDrmBridge_isCryptoSchemeSupported( |
| 206 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); |
| 207 } |
| 208 |
| 183 // static | 209 // static |
| 184 bool MediaDrmBridge::IsAvailable() { | 210 bool MediaDrmBridge::IsAvailable() { |
| 185 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; | 211 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; |
| 186 } | 212 } |
| 187 | 213 |
| 188 // static | 214 // static |
| 189 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 215 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
| 190 DCHECK(IsAvailable()); | 216 DCHECK(IsAvailable()); |
| 191 return SECURITY_LEVEL_1 == security_level; | 217 return SECURITY_LEVEL_1 == security_level; |
| 192 } | 218 } |
| 193 | 219 |
| 194 // static | 220 // static |
| 195 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, | 221 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, |
| 196 SecurityLevel security_level) { | 222 SecurityLevel security_level) { |
| 197 if (!IsAvailable()) | 223 if (!IsAvailable()) |
| 198 return false; | 224 return false; |
| 199 | 225 |
| 200 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in | 226 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in |
| 201 // creation time of MediaDrmBridge. | 227 // creation time of MediaDrmBridge. |
| 202 scoped_ptr<MediaDrmBridge> media_drm_bridge = | 228 scoped_ptr<MediaDrmBridge> media_drm_bridge = |
| 203 MediaDrmBridge::Create(0, key_system, GURL(), NULL); | 229 MediaDrmBridge::Create(0, key_system, GURL(), NULL); |
| 204 if (!media_drm_bridge) | 230 if (!media_drm_bridge) |
| 205 return false; | 231 return false; |
| 206 | 232 |
| 207 return media_drm_bridge->SetSecurityLevel(security_level); | 233 return media_drm_bridge->SetSecurityLevel(security_level); |
| 208 } | 234 } |
| 209 | 235 |
| 210 // static | 236 // static |
| 237 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
| 238 DCHECK(!key_system.empty()); |
| 239 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
| 240 } |
| 241 |
| 242 // static |
| 211 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 243 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
| 212 const std::string& key_system, | 244 const std::string& key_system, |
| 213 const std::string& container_mime_type) { | 245 const std::string& container_mime_type) { |
| 214 if (!IsAvailable()) | 246 DCHECK(!key_system.empty() && !container_mime_type.empty()); |
| 215 return false; | 247 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
| 216 | |
| 217 std::vector<uint8> scheme_uuid = GetUUID(key_system); | |
| 218 if (scheme_uuid.empty()) | |
| 219 return false; | |
| 220 | |
| 221 JNIEnv* env = AttachCurrentThread(); | |
| 222 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | |
| 223 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | |
| 224 ScopedJavaLocalRef<jstring> j_container_mime_type = | |
| 225 ConvertUTF8ToJavaString(env, container_mime_type); | |
| 226 return Java_MediaDrmBridge_isCryptoSchemeSupported( | |
| 227 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | |
| 228 } | 248 } |
| 229 | 249 |
| 230 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 250 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
| 231 return RegisterNativesImpl(env); | 251 return RegisterNativesImpl(env); |
| 232 } | 252 } |
| 233 | 253 |
| 234 MediaDrmBridge::MediaDrmBridge(int cdm_id, | 254 MediaDrmBridge::MediaDrmBridge(int cdm_id, |
| 235 const std::vector<uint8>& scheme_uuid, | 255 const std::vector<uint8>& scheme_uuid, |
| 236 const GURL& security_origin, | 256 const GURL& security_origin, |
| 237 MediaPlayerManager* manager) | 257 MediaPlayerManager* manager) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 ScopedJavaLocalRef<jstring> j_security_level = | 305 ScopedJavaLocalRef<jstring> j_security_level = |
| 286 ConvertUTF8ToJavaString(env, security_level_str); | 306 ConvertUTF8ToJavaString(env, security_level_str); |
| 287 return Java_MediaDrmBridge_setSecurityLevel( | 307 return Java_MediaDrmBridge_setSecurityLevel( |
| 288 env, j_media_drm_.obj(), j_security_level.obj()); | 308 env, j_media_drm_.obj(), j_security_level.obj()); |
| 289 } | 309 } |
| 290 | 310 |
| 291 bool MediaDrmBridge::CreateSession(uint32 session_id, | 311 bool MediaDrmBridge::CreateSession(uint32 session_id, |
| 292 const std::string& content_type, | 312 const std::string& content_type, |
| 293 const uint8* init_data, | 313 const uint8* init_data, |
| 294 int init_data_length) { | 314 int init_data_length) { |
| 295 std::vector<uint8> pssh_data; | 315 JNIEnv* env = AttachCurrentThread(); |
| 296 if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) | 316 ScopedJavaLocalRef<jbyteArray> j_init_data; |
| 297 return false; | 317 // Caller should always use "video/*" content types. |
| 318 DCHECK_EQ(0u, content_type.find("video/")); |
| 298 | 319 |
| 299 JNIEnv* env = AttachCurrentThread(); | 320 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as |
| 300 ScopedJavaLocalRef<jbyteArray> j_pssh_data = | 321 // the init data when using MP4 container. |
| 301 base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); | 322 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && |
| 323 content_type == "video/mp4") { |
| 324 std::vector<uint8> pssh_data; |
| 325 if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) |
| 326 return false; |
| 327 j_init_data = |
| 328 base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); |
| 329 } else { |
| 330 j_init_data = |
| 331 base::android::ToJavaByteArray(env, init_data, init_data_length); |
| 332 } |
| 333 |
| 302 ScopedJavaLocalRef<jstring> j_mime = | 334 ScopedJavaLocalRef<jstring> j_mime = |
| 303 ConvertUTF8ToJavaString(env, content_type); | 335 ConvertUTF8ToJavaString(env, content_type); |
| 304 Java_MediaDrmBridge_createSession( | 336 Java_MediaDrmBridge_createSession( |
| 305 env, j_media_drm_.obj(), session_id, j_pssh_data.obj(), j_mime.obj()); | 337 env, j_media_drm_.obj(), session_id, j_init_data.obj(), j_mime.obj()); |
| 306 return true; | 338 return true; |
| 307 } | 339 } |
| 308 | 340 |
| 309 void MediaDrmBridge::LoadSession(uint32 session_id, | 341 void MediaDrmBridge::LoadSession(uint32 session_id, |
| 310 const std::string& web_session_id) { | 342 const std::string& web_session_id) { |
| 311 // MediaDrmBridge doesn't support loading sessions. | 343 // MediaDrmBridge doesn't support loading sessions. |
| 312 NOTREACHED(); | 344 NOTREACHED(); |
| 313 } | 345 } |
| 314 | 346 |
| 315 void MediaDrmBridge::UpdateSession(uint32 session_id, | 347 void MediaDrmBridge::UpdateSession(uint32 session_id, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 JNIEnv* env = AttachCurrentThread(); | 457 JNIEnv* env = AttachCurrentThread(); |
| 426 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 458 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
| 427 } | 459 } |
| 428 | 460 |
| 429 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 461 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
| 430 JNIEnv* env, jobject, bool success) { | 462 JNIEnv* env, jobject, bool success) { |
| 431 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 463 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
| 432 } | 464 } |
| 433 | 465 |
| 434 } // namespace media | 466 } // namespace media |
| OLD | NEW |