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/location.h" | 13 #include "base/location.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
17 #include "jni/MediaDrmBridge_jni.h" | 17 #include "jni/MediaDrmBridge_jni.h" |
18 #include "media/base/android/media_player_manager.h" | |
19 | 18 |
20 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 19 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
21 | 20 |
22 using base::android::AttachCurrentThread; | 21 using base::android::AttachCurrentThread; |
23 using base::android::ConvertUTF8ToJavaString; | 22 using base::android::ConvertUTF8ToJavaString; |
24 using base::android::ConvertJavaStringToUTF8; | 23 using base::android::ConvertJavaStringToUTF8; |
25 using base::android::JavaByteArrayToByteVector; | 24 using base::android::JavaByteArrayToByteVector; |
26 using base::android::ScopedJavaLocalRef; | 25 using base::android::ScopedJavaLocalRef; |
27 | 26 |
28 namespace media { | 27 namespace media { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 DCHECK(IsAvailable()); | 215 DCHECK(IsAvailable()); |
217 return SECURITY_LEVEL_1 == security_level; | 216 return SECURITY_LEVEL_1 == security_level; |
218 } | 217 } |
219 | 218 |
220 // static | 219 // static |
221 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, | 220 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, |
222 SecurityLevel security_level) { | 221 SecurityLevel security_level) { |
223 if (!IsAvailable()) | 222 if (!IsAvailable()) |
224 return false; | 223 return false; |
225 | 224 |
226 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in | |
227 // creation time of MediaDrmBridge. | |
228 scoped_ptr<MediaDrmBridge> media_drm_bridge = | 225 scoped_ptr<MediaDrmBridge> media_drm_bridge = |
229 MediaDrmBridge::Create(0, key_system, GURL(), NULL); | 226 MediaDrmBridge::Create(key_system); |
230 if (!media_drm_bridge) | 227 if (!media_drm_bridge) |
231 return false; | 228 return false; |
232 | 229 |
233 return media_drm_bridge->SetSecurityLevel(security_level); | 230 return media_drm_bridge->SetSecurityLevel(security_level); |
234 } | 231 } |
235 | 232 |
236 // static | 233 // static |
237 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 234 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
238 DCHECK(!key_system.empty()); | 235 DCHECK(!key_system.empty()); |
239 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 236 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
240 } | 237 } |
241 | 238 |
242 // static | 239 // static |
243 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 240 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
244 const std::string& key_system, | 241 const std::string& key_system, |
245 const std::string& container_mime_type) { | 242 const std::string& container_mime_type) { |
246 DCHECK(!key_system.empty() && !container_mime_type.empty()); | 243 DCHECK(!key_system.empty() && !container_mime_type.empty()); |
247 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); | 244 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
248 } | 245 } |
249 | 246 |
250 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 247 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
251 return RegisterNativesImpl(env); | 248 return RegisterNativesImpl(env); |
252 } | 249 } |
253 | 250 |
254 MediaDrmBridge::MediaDrmBridge(int cdm_id, | 251 MediaDrmBridge::MediaDrmBridge(const std::vector<uint8>& scheme_uuid, |
255 const std::vector<uint8>& scheme_uuid, | 252 const SessionCreatedCB& session_created_cb, |
256 const GURL& security_origin, | 253 const SessionMessageCB& session_message_cb, |
257 MediaPlayerManager* manager) | 254 const SessionReadyCB& session_ready_cb, |
258 : cdm_id_(cdm_id), | 255 const SessionClosedCB& session_closed_cb, |
259 scheme_uuid_(scheme_uuid), | 256 const SessionErrorCB& session_error_cb) |
260 security_origin_(security_origin), | 257 : scheme_uuid_(scheme_uuid), |
261 manager_(manager) { | 258 session_created_cb_(session_created_cb), |
259 session_message_cb_(session_message_cb), | |
260 session_ready_cb_(session_ready_cb), | |
261 session_closed_cb_(session_closed_cb), | |
262 session_error_cb_(session_error_cb) { | |
262 JNIEnv* env = AttachCurrentThread(); | 263 JNIEnv* env = AttachCurrentThread(); |
263 CHECK(env); | 264 CHECK(env); |
264 | 265 |
265 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 266 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
266 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 267 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
267 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 268 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
268 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); | 269 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); |
269 } | 270 } |
270 | 271 |
271 MediaDrmBridge::~MediaDrmBridge() { | 272 MediaDrmBridge::~MediaDrmBridge() { |
272 JNIEnv* env = AttachCurrentThread(); | 273 JNIEnv* env = AttachCurrentThread(); |
273 if (!j_media_drm_.is_null()) | 274 if (!j_media_drm_.is_null()) |
274 Java_MediaDrmBridge_release(env, j_media_drm_.obj()); | 275 Java_MediaDrmBridge_release(env, j_media_drm_.obj()); |
275 } | 276 } |
276 | 277 |
277 // static | 278 // static |
278 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, | 279 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( |
279 const std::string& key_system, | 280 const std::string& key_system, |
280 const GURL& security_origin, | 281 const SessionCreatedCB& session_created_cb, |
281 MediaPlayerManager* manager) { | 282 const SessionMessageCB& session_message_cb, |
283 const SessionReadyCB& session_ready_cb, | |
284 const SessionClosedCB& session_closed_cb, | |
285 const SessionErrorCB& session_error_cb) { | |
282 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 286 scoped_ptr<MediaDrmBridge> media_drm_bridge; |
283 if (!IsAvailable()) | 287 if (!IsAvailable()) |
284 return media_drm_bridge.Pass(); | 288 return media_drm_bridge.Pass(); |
285 | 289 |
286 std::vector<uint8> scheme_uuid = GetUUID(key_system); | 290 std::vector<uint8> scheme_uuid = GetUUID(key_system); |
287 if (scheme_uuid.empty()) | 291 if (scheme_uuid.empty()) |
288 return media_drm_bridge.Pass(); | 292 return media_drm_bridge.Pass(); |
289 | 293 |
290 media_drm_bridge.reset( | 294 media_drm_bridge.reset(new MediaDrmBridge(scheme_uuid, |
291 new MediaDrmBridge(cdm_id, scheme_uuid, security_origin, manager)); | 295 session_created_cb, |
296 session_message_cb, | |
297 session_ready_cb, | |
298 session_closed_cb, | |
299 session_error_cb)); | |
300 | |
292 if (media_drm_bridge->j_media_drm_.is_null()) | 301 if (media_drm_bridge->j_media_drm_.is_null()) |
293 media_drm_bridge.reset(); | 302 media_drm_bridge.reset(); |
294 | 303 |
295 return media_drm_bridge.Pass(); | 304 return media_drm_bridge.Pass(); |
296 } | 305 } |
297 | 306 |
307 //static | |
308 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( | |
309 const std::string& key_system) { | |
310 return MediaDrmBridge::Create(key_system, | |
311 SessionCreatedCB(), | |
312 SessionMessageCB(), | |
313 SessionReadyCB(), | |
314 SessionClosedCB(), | |
315 SessionErrorCB()); | |
316 } | |
317 | |
298 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { | 318 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { |
299 JNIEnv* env = AttachCurrentThread(); | 319 JNIEnv* env = AttachCurrentThread(); |
300 | 320 |
301 std::string security_level_str = GetSecurityLevelString(security_level); | 321 std::string security_level_str = GetSecurityLevelString(security_level); |
302 if (security_level_str.empty()) | 322 if (security_level_str.empty()) |
303 return false; | 323 return false; |
304 | 324 |
305 ScopedJavaLocalRef<jstring> j_security_level = | 325 ScopedJavaLocalRef<jstring> j_security_level = |
306 ConvertUTF8ToJavaString(env, security_level_str); | 326 ConvertUTF8ToJavaString(env, security_level_str); |
307 return Java_MediaDrmBridge_setSecurityLevel( | 327 return Java_MediaDrmBridge_setSecurityLevel( |
308 env, j_media_drm_.obj(), j_security_level.obj()); | 328 env, j_media_drm_.obj(), j_security_level.obj()); |
309 } | 329 } |
310 | 330 |
311 bool MediaDrmBridge::CreateSession(uint32 session_id, | 331 bool MediaDrmBridge::CreateSession(uint32 session_id, |
312 const std::string& content_type, | 332 const std::string& content_type, |
313 const uint8* init_data, | 333 const uint8* init_data, |
314 int init_data_length) { | 334 int init_data_length) { |
335 DCHECK(!session_created_cb_.is_null()); | |
damienv1
2014/05/12 23:14:26
We should have all these DCHECK in the constructor
ddorwin
2014/05/13 00:59:38
I assume this is to make sure that this is not cal
xhwang
2014/05/14 16:42:06
Done.
| |
336 | |
315 JNIEnv* env = AttachCurrentThread(); | 337 JNIEnv* env = AttachCurrentThread(); |
316 ScopedJavaLocalRef<jbyteArray> j_init_data; | 338 ScopedJavaLocalRef<jbyteArray> j_init_data; |
317 // Caller should always use "video/*" content types. | 339 // Caller should always use "video/*" content types. |
318 DCHECK_EQ(0u, content_type.find("video/")); | 340 DCHECK_EQ(0u, content_type.find("video/")); |
319 | 341 |
320 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as | 342 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as |
321 // the init data when using MP4 container. | 343 // the init data when using MP4 container. |
322 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && | 344 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && |
323 content_type == "video/mp4") { | 345 content_type == "video/mp4") { |
324 std::vector<uint8> pssh_data; | 346 std::vector<uint8> pssh_data; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 if (!media_crypto_ready_cb_.is_null()) | 404 if (!media_crypto_ready_cb_.is_null()) |
383 base::ResetAndReturn(&media_crypto_ready_cb_).Run(); | 405 base::ResetAndReturn(&media_crypto_ready_cb_).Run(); |
384 } | 406 } |
385 | 407 |
386 void MediaDrmBridge::OnSessionCreated(JNIEnv* env, | 408 void MediaDrmBridge::OnSessionCreated(JNIEnv* env, |
387 jobject j_media_drm, | 409 jobject j_media_drm, |
388 jint j_session_id, | 410 jint j_session_id, |
389 jstring j_web_session_id) { | 411 jstring j_web_session_id) { |
390 uint32 session_id = j_session_id; | 412 uint32 session_id = j_session_id; |
391 std::string web_session_id = ConvertJavaStringToUTF8(env, j_web_session_id); | 413 std::string web_session_id = ConvertJavaStringToUTF8(env, j_web_session_id); |
392 manager_->OnSessionCreated(cdm_id_, session_id, web_session_id); | 414 session_created_cb_.Run(session_id, web_session_id); |
393 } | 415 } |
394 | 416 |
395 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, | 417 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, |
396 jobject j_media_drm, | 418 jobject j_media_drm, |
397 jint j_session_id, | 419 jint j_session_id, |
398 jbyteArray j_message, | 420 jbyteArray j_message, |
399 jstring j_destination_url) { | 421 jstring j_destination_url) { |
400 uint32 session_id = j_session_id; | 422 uint32 session_id = j_session_id; |
401 std::vector<uint8> message; | 423 std::vector<uint8> message; |
402 JavaByteArrayToByteVector(env, j_message, &message); | 424 JavaByteArrayToByteVector(env, j_message, &message); |
403 std::string destination_url = ConvertJavaStringToUTF8(env, j_destination_url); | 425 std::string destination_url = ConvertJavaStringToUTF8(env, j_destination_url); |
404 GURL destination_gurl(destination_url); | 426 session_message_cb_.Run(session_id, message, destination_url); |
ddorwin
2014/05/13 00:59:38
Ahh, did you make that GURL->string change because
xhwang
2014/05/14 16:42:06
yes :) I filed a bug to fix this.
| |
405 if (!destination_gurl.is_valid() && !destination_gurl.is_empty()) { | |
406 DLOG(WARNING) << "SessionMessage destination_url is invalid : " | |
407 << destination_gurl.possibly_invalid_spec(); | |
408 destination_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. | |
409 } | |
410 | |
411 manager_->OnSessionMessage(cdm_id_, session_id, message, destination_gurl); | |
412 } | 427 } |
413 | 428 |
414 void MediaDrmBridge::OnSessionReady(JNIEnv* env, | 429 void MediaDrmBridge::OnSessionReady(JNIEnv* env, |
415 jobject j_media_drm, | 430 jobject j_media_drm, |
416 jint j_session_id) { | 431 jint j_session_id) { |
417 uint32 session_id = j_session_id; | 432 uint32 session_id = j_session_id; |
418 manager_->OnSessionReady(cdm_id_, session_id); | 433 session_ready_cb_.Run(session_id); |
419 } | 434 } |
420 | 435 |
421 void MediaDrmBridge::OnSessionClosed(JNIEnv* env, | 436 void MediaDrmBridge::OnSessionClosed(JNIEnv* env, |
422 jobject j_media_drm, | 437 jobject j_media_drm, |
423 jint j_session_id) { | 438 jint j_session_id) { |
424 uint32 session_id = j_session_id; | 439 uint32 session_id = j_session_id; |
425 manager_->OnSessionClosed(cdm_id_, session_id); | 440 session_closed_cb_.Run(session_id); |
426 } | 441 } |
427 | 442 |
428 void MediaDrmBridge::OnSessionError(JNIEnv* env, | 443 void MediaDrmBridge::OnSessionError(JNIEnv* env, |
429 jobject j_media_drm, | 444 jobject j_media_drm, |
430 jint j_session_id) { | 445 jint j_session_id) { |
431 uint32 session_id = j_session_id; | 446 uint32 session_id = j_session_id; |
432 manager_->OnSessionError(cdm_id_, session_id, MediaKeys::kUnknownError, 0); | 447 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); |
433 } | 448 } |
434 | 449 |
435 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { | 450 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { |
436 JNIEnv* env = AttachCurrentThread(); | 451 JNIEnv* env = AttachCurrentThread(); |
437 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); | 452 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); |
438 } | 453 } |
439 | 454 |
440 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { | 455 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { |
441 JNIEnv* env = AttachCurrentThread(); | 456 JNIEnv* env = AttachCurrentThread(); |
442 ScopedJavaLocalRef<jstring> j_security_level = | 457 ScopedJavaLocalRef<jstring> j_security_level = |
(...skipping 14 matching lines...) Expand all Loading... | |
457 JNIEnv* env = AttachCurrentThread(); | 472 JNIEnv* env = AttachCurrentThread(); |
458 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 473 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
459 } | 474 } |
460 | 475 |
461 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 476 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
462 JNIEnv* env, jobject, bool success) { | 477 JNIEnv* env, jobject, bool success) { |
463 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 478 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
464 } | 479 } |
465 | 480 |
466 } // namespace media | 481 } // namespace media |
OLD | NEW |