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/bind.h" | 12 #include "base/bind.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
16 #include "base/location.h" | 16 #include "base/location.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
20 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
22 #include "base/sys_byteorder.h" | 22 #include "base/sys_byteorder.h" |
23 #include "base/sys_info.h" | 23 #include "base/sys_info.h" |
24 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
25 #include "jni/MediaDrmBridge_jni.h" | 25 #include "jni/MediaDrmBridge_jni.h" |
26 #include "media/base/android/media_client_android.h" | 26 #include "media/base/android/media_client_android.h" |
27 #include "media/base/android/media_drm_bridge_delegate.h" | 27 #include "media/base/android/media_drm_bridge_delegate.h" |
28 #include "media/base/android/media_task_runner.h" | |
29 #include "media/base/cdm_key_information.h" | 28 #include "media/base/cdm_key_information.h" |
30 | 29 |
31 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 30 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
32 | 31 |
33 using base::android::AttachCurrentThread; | 32 using base::android::AttachCurrentThread; |
34 using base::android::ConvertUTF8ToJavaString; | 33 using base::android::ConvertUTF8ToJavaString; |
35 using base::android::ConvertJavaStringToUTF8; | 34 using base::android::ConvertJavaStringToUTF8; |
36 using base::android::JavaByteArrayToByteVector; | 35 using base::android::JavaByteArrayToByteVector; |
37 using base::android::ScopedJavaGlobalRef; | 36 using base::android::ScopedJavaGlobalRef; |
38 using base::android::ScopedJavaLocalRef; | 37 using base::android::ScopedJavaLocalRef; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 case MediaDrmBridge::SECURITY_LEVEL_1: | 206 case MediaDrmBridge::SECURITY_LEVEL_1: |
208 return "L1"; | 207 return "L1"; |
209 case MediaDrmBridge::SECURITY_LEVEL_3: | 208 case MediaDrmBridge::SECURITY_LEVEL_3: |
210 return "L3"; | 209 return "L3"; |
211 } | 210 } |
212 return ""; | 211 return ""; |
213 } | 212 } |
214 | 213 |
215 } // namespace | 214 } // namespace |
216 | 215 |
217 MediaDrmBridge::~MediaDrmBridge() { | |
218 DVLOG(1) << __FUNCTION__; | |
219 | |
220 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | |
221 | |
222 player_tracker_.NotifyCdmUnset(); | |
223 } | |
224 | |
225 void MediaDrmBridge::DeleteOnCorrectThread() { | |
226 DCHECK(task_runner_->BelongsToCurrentThread()); | |
227 DVLOG(1) << __FUNCTION__; | |
228 | |
229 JNIEnv* env = AttachCurrentThread(); | |
230 if (!j_media_drm_.is_null()) | |
231 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | |
232 | |
233 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | |
234 // methods anymore, this is ensured by MediaDrmBridge.java. | |
235 | |
236 // CdmPromiseAdapter must be destroyed on the UI thread. | |
237 cdm_promise_adapter_.reset(); | |
238 | |
239 // Post deletion onto Media thread if we use it. | |
240 if (use_media_thread_) { | |
241 weak_factory_.InvalidateWeakPtrs(); | |
242 GetMediaTaskRunner()->DeleteSoon(FROM_HERE, this); | |
243 } else { | |
244 delete this; | |
245 } | |
246 } | |
247 | |
248 // static | 216 // static |
249 bool MediaDrmBridge::IsAvailable() { | 217 bool MediaDrmBridge::IsAvailable() { |
250 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) | 218 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) |
251 return false; | 219 return false; |
252 | 220 |
253 int32 os_major_version = 0; | 221 int32 os_major_version = 0; |
254 int32 os_minor_version = 0; | 222 int32 os_minor_version = 0; |
255 int32 os_bugfix_version = 0; | 223 int32 os_bugfix_version = 0; |
256 base::SysInfo::OperatingSystemVersionNumbers( | 224 base::SysInfo::OperatingSystemVersionNumbers( |
257 &os_major_version, &os_minor_version, &os_bugfix_version); | 225 &os_major_version, &os_minor_version, &os_bugfix_version); |
(...skipping 21 matching lines...) Expand all Loading... | |
279 DCHECK(!key_system.empty() && !container_mime_type.empty()); | 247 DCHECK(!key_system.empty() && !container_mime_type.empty()); |
280 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); | 248 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
281 } | 249 } |
282 | 250 |
283 // static | 251 // static |
284 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 252 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
285 return g_key_system_manager.Get().GetPlatformKeySystemNames(); | 253 return g_key_system_manager.Get().GetPlatformKeySystemNames(); |
286 } | 254 } |
287 | 255 |
288 // static | 256 // static |
289 ScopedMediaDrmBridgePtr MediaDrmBridge::Create( | 257 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create( |
290 const std::string& key_system, | 258 const std::string& key_system, |
291 const SessionMessageCB& session_message_cb, | 259 const SessionMessageCB& session_message_cb, |
292 const SessionClosedCB& session_closed_cb, | 260 const SessionClosedCB& session_closed_cb, |
293 const LegacySessionErrorCB& legacy_session_error_cb, | 261 const LegacySessionErrorCB& legacy_session_error_cb, |
294 const SessionKeysChangeCB& session_keys_change_cb, | 262 const SessionKeysChangeCB& session_keys_change_cb, |
295 const SessionExpirationUpdateCB& session_expiration_update_cb) { | 263 const SessionExpirationUpdateCB& session_expiration_update_cb) { |
296 DVLOG(1) << __FUNCTION__; | 264 DVLOG(1) << __FUNCTION__; |
297 | 265 |
298 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> media_drm_bridge; | |
299 if (!IsAvailable()) | 266 if (!IsAvailable()) |
300 return media_drm_bridge.Pass(); | 267 return nullptr; |
301 | 268 |
302 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); | 269 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
303 if (scheme_uuid.empty()) | 270 if (scheme_uuid.empty()) |
304 return media_drm_bridge.Pass(); | 271 return nullptr; |
305 | 272 |
306 media_drm_bridge.reset( | 273 scoped_refptr<MediaDrmBridge> media_drm_bridge( |
307 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, | 274 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, |
308 legacy_session_error_cb, session_keys_change_cb, | 275 legacy_session_error_cb, session_keys_change_cb, |
309 session_expiration_update_cb)); | 276 session_expiration_update_cb)); |
310 | 277 |
311 if (media_drm_bridge->j_media_drm_.is_null()) | 278 if (media_drm_bridge->j_media_drm_.is_null()) |
312 media_drm_bridge.reset(); | 279 media_drm_bridge = nullptr; |
313 | 280 |
314 return media_drm_bridge.Pass(); | 281 return media_drm_bridge; |
315 } | 282 } |
316 | 283 |
317 // static | 284 // static |
318 ScopedMediaDrmBridgePtr MediaDrmBridge::CreateWithoutSessionSupport( | 285 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( |
319 const std::string& key_system) { | 286 const std::string& key_system) { |
320 return MediaDrmBridge::Create( | 287 return MediaDrmBridge::Create( |
321 key_system, SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(), | 288 key_system, SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(), |
322 SessionKeysChangeCB(), SessionExpirationUpdateCB()); | 289 SessionKeysChangeCB(), SessionExpirationUpdateCB()); |
323 } | 290 } |
324 | 291 |
325 base::WeakPtr<MediaDrmBridge> MediaDrmBridge::WeakPtr() { | |
326 return weak_factory_.GetWeakPtr(); | |
327 } | |
328 | |
329 void MediaDrmBridge::SetServerCertificate( | 292 void MediaDrmBridge::SetServerCertificate( |
330 const std::vector<uint8_t>& certificate, | 293 const std::vector<uint8_t>& certificate, |
331 scoped_ptr<media::SimpleCdmPromise> promise) { | 294 scoped_ptr<media::SimpleCdmPromise> promise) { |
332 DVLOG(2) << __FUNCTION__; | 295 DVLOG(2) << __FUNCTION__; |
333 | 296 |
334 DCHECK(!certificate.empty()); | 297 DCHECK(!certificate.empty()); |
335 | 298 |
336 JNIEnv* env = AttachCurrentThread(); | 299 JNIEnv* env = AttachCurrentThread(); |
337 ScopedJavaLocalRef<jbyteArray> j_certificate; | 300 ScopedJavaLocalRef<jbyteArray> j_certificate; |
338 if (Java_MediaDrmBridge_setServerCertificate(env, j_media_drm_.obj(), | 301 if (Java_MediaDrmBridge_setServerCertificate(env, j_media_drm_.obj(), |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
445 | 408 |
446 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; | 409 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; |
447 promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported."); | 410 promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported."); |
448 } | 411 } |
449 | 412 |
450 CdmContext* MediaDrmBridge::GetCdmContext() { | 413 CdmContext* MediaDrmBridge::GetCdmContext() { |
451 NOTREACHED(); | 414 NOTREACHED(); |
452 return nullptr; | 415 return nullptr; |
453 } | 416 } |
454 | 417 |
418 void MediaDrmBridge::DeleteOnCorrectThread() const { | |
419 DVLOG(1) << __FUNCTION__; | |
420 | |
421 if (!task_runner_->BelongsToCurrentThread()) { | |
422 // When DeleteSoon returns false, |this| will be leaked, which is okay. | |
423 task_runner_->DeleteSoon(FROM_HERE, this); | |
424 } else { | |
425 delete this; | |
426 } | |
427 } | |
428 | |
455 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, | 429 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, |
456 const base::Closure& cdm_unset_cb) { | 430 const base::Closure& cdm_unset_cb) { |
457 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | 431 // |player_tracker_| can be accessed from any thread. |
458 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); | 432 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); |
459 } | 433 } |
460 | 434 |
461 void MediaDrmBridge::UnregisterPlayer(int registration_id) { | 435 void MediaDrmBridge::UnregisterPlayer(int registration_id) { |
462 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | 436 // |player_tracker_| can be accessed from any thread. |
463 player_tracker_.UnregisterPlayer(registration_id); | 437 player_tracker_.UnregisterPlayer(registration_id); |
464 } | 438 } |
465 | 439 |
466 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { | 440 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { |
467 if (security_level != SECURITY_LEVEL_NONE && | 441 if (security_level != SECURITY_LEVEL_NONE && |
468 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { | 442 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { |
469 NOTREACHED() << "Widevine security level " << security_level | 443 NOTREACHED() << "Widevine security level " << security_level |
470 << "used with another key system"; | 444 << "used with another key system"; |
471 return false; | 445 return false; |
472 } | 446 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 | 494 |
521 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { | 495 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { |
522 DCHECK(task_runner_->BelongsToCurrentThread()); | 496 DCHECK(task_runner_->BelongsToCurrentThread()); |
523 | 497 |
524 JNIEnv* env = AttachCurrentThread(); | 498 JNIEnv* env = AttachCurrentThread(); |
525 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); | 499 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); |
526 } | 500 } |
527 | 501 |
528 void MediaDrmBridge::SetMediaCryptoReadyCB( | 502 void MediaDrmBridge::SetMediaCryptoReadyCB( |
529 const MediaCryptoReadyCB& media_crypto_ready_cb) { | 503 const MediaCryptoReadyCB& media_crypto_ready_cb) { |
530 DCHECK(task_runner_->BelongsToCurrentThread()); | 504 if (!task_runner_->BelongsToCurrentThread()) { |
505 task_runner_->PostTask( | |
506 FROM_HERE, | |
507 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB, | |
508 weak_factory_.GetWeakPtr(), media_crypto_ready_cb)); | |
509 return; | |
510 } | |
511 | |
531 DVLOG(1) << __FUNCTION__; | 512 DVLOG(1) << __FUNCTION__; |
532 | 513 |
533 if (media_crypto_ready_cb.is_null()) { | 514 if (media_crypto_ready_cb.is_null()) { |
534 media_crypto_ready_cb_.Reset(); | 515 media_crypto_ready_cb_.Reset(); |
535 return; | 516 return; |
536 } | 517 } |
537 | 518 |
538 DCHECK(media_crypto_ready_cb_.is_null()); | 519 DCHECK(media_crypto_ready_cb_.is_null()); |
539 | 520 |
540 // |media_crypto_ready_cb| is already bound to the correct thread | 521 // |media_crypto_ready_cb| is already bound to the correct thread |
(...skipping 10 matching lines...) Expand all Loading... | |
551 // only do minimal work and then post tasks to avoid reentrancy issues. | 532 // only do minimal work and then post tasks to avoid reentrancy issues. |
552 | 533 |
553 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject j_media_drm) { | 534 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject j_media_drm) { |
554 DCHECK(task_runner_->BelongsToCurrentThread()); | 535 DCHECK(task_runner_->BelongsToCurrentThread()); |
555 DVLOG(1) << __FUNCTION__; | 536 DVLOG(1) << __FUNCTION__; |
556 | 537 |
557 if (media_crypto_ready_cb_.is_null()) | 538 if (media_crypto_ready_cb_.is_null()) |
558 return; | 539 return; |
559 | 540 |
560 task_runner_->PostTask( | 541 task_runner_->PostTask( |
561 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyMediaCryptoReady, WeakPtr(), | 542 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyMediaCryptoReady, |
543 weak_factory_.GetWeakPtr(), | |
562 base::ResetAndReturn(&media_crypto_ready_cb_))); | 544 base::ResetAndReturn(&media_crypto_ready_cb_))); |
563 } | 545 } |
564 | 546 |
565 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, | 547 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, |
566 jobject j_media_drm, | 548 jobject j_media_drm, |
567 jint j_promise_id) { | 549 jint j_promise_id) { |
568 task_runner_->PostTask(FROM_HERE, base::Bind(&MediaDrmBridge::ResolvePromise, | 550 task_runner_->PostTask(FROM_HERE, |
569 WeakPtr(), j_promise_id)); | 551 base::Bind(&MediaDrmBridge::ResolvePromise, |
552 weak_factory_.GetWeakPtr(), j_promise_id)); | |
570 } | 553 } |
571 | 554 |
572 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, | 555 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, |
573 jobject j_media_drm, | 556 jobject j_media_drm, |
574 jint j_promise_id, | 557 jint j_promise_id, |
575 jbyteArray j_session_id) { | 558 jbyteArray j_session_id) { |
576 task_runner_->PostTask( | 559 task_runner_->PostTask(FROM_HERE, |
577 FROM_HERE, | 560 base::Bind(&MediaDrmBridge::ResolvePromiseWithSession, |
578 base::Bind(&MediaDrmBridge::ResolvePromiseWithSession, WeakPtr(), | 561 weak_factory_.GetWeakPtr(), j_promise_id, |
579 j_promise_id, GetSessionId(env, j_session_id))); | 562 GetSessionId(env, j_session_id))); |
580 } | 563 } |
581 | 564 |
582 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, | 565 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, |
583 jobject j_media_drm, | 566 jobject j_media_drm, |
584 jint j_promise_id, | 567 jint j_promise_id, |
585 jstring j_error_message) { | 568 jstring j_error_message) { |
586 task_runner_->PostTask( | 569 task_runner_->PostTask( |
587 FROM_HERE, | 570 FROM_HERE, |
588 base::Bind(&MediaDrmBridge::RejectPromise, WeakPtr(), j_promise_id, | 571 base::Bind(&MediaDrmBridge::RejectPromise, weak_factory_.GetWeakPtr(), |
589 ConvertJavaStringToUTF8(env, j_error_message))); | 572 j_promise_id, ConvertJavaStringToUTF8(env, j_error_message))); |
590 } | 573 } |
591 | 574 |
592 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, | 575 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, |
593 jobject j_media_drm, | 576 jobject j_media_drm, |
594 jbyteArray j_session_id, | 577 jbyteArray j_session_id, |
595 jint j_message_type, | 578 jint j_message_type, |
596 jbyteArray j_message, | 579 jbyteArray j_message, |
597 jstring j_legacy_destination_url) { | 580 jstring j_legacy_destination_url) { |
598 DVLOG(2) << __FUNCTION__; | 581 DVLOG(2) << __FUNCTION__; |
599 | 582 |
(...skipping 19 matching lines...) Expand all Loading... | |
619 } | 602 } |
620 | 603 |
621 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, | 604 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, |
622 jobject j_media_drm, | 605 jobject j_media_drm, |
623 jbyteArray j_session_id, | 606 jbyteArray j_session_id, |
624 jobjectArray j_keys_info, | 607 jobjectArray j_keys_info, |
625 bool has_additional_usable_key) { | 608 bool has_additional_usable_key) { |
626 DVLOG(2) << __FUNCTION__; | 609 DVLOG(2) << __FUNCTION__; |
627 | 610 |
628 if (has_additional_usable_key) | 611 if (has_additional_usable_key) |
629 NotifyNewKeyOnCorrectThread(); | 612 player_tracker_.NotifyNewKey(); |
630 | 613 |
631 CdmKeysInfo cdm_keys_info; | 614 CdmKeysInfo cdm_keys_info; |
632 | 615 |
633 size_t size = env->GetArrayLength(j_keys_info); | 616 size_t size = env->GetArrayLength(j_keys_info); |
634 DCHECK_GT(size, 0u); | 617 DCHECK_GT(size, 0u); |
635 | 618 |
636 for (size_t i = 0; i < size; ++i) { | 619 for (size_t i = 0; i < size; ++i) { |
637 ScopedJavaLocalRef<jobject> j_key_status( | 620 ScopedJavaLocalRef<jobject> j_key_status( |
638 env, env->GetObjectArrayElement(j_keys_info, i)); | 621 env, env->GetObjectArrayElement(j_keys_info, i)); |
639 | 622 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
720 const SessionKeysChangeCB& session_keys_change_cb, | 703 const SessionKeysChangeCB& session_keys_change_cb, |
721 const SessionExpirationUpdateCB& session_expiration_update_cb) | 704 const SessionExpirationUpdateCB& session_expiration_update_cb) |
722 : scheme_uuid_(scheme_uuid), | 705 : scheme_uuid_(scheme_uuid), |
723 session_message_cb_(session_message_cb), | 706 session_message_cb_(session_message_cb), |
724 session_closed_cb_(session_closed_cb), | 707 session_closed_cb_(session_closed_cb), |
725 legacy_session_error_cb_(legacy_session_error_cb), | 708 legacy_session_error_cb_(legacy_session_error_cb), |
726 session_keys_change_cb_(session_keys_change_cb), | 709 session_keys_change_cb_(session_keys_change_cb), |
727 session_expiration_update_cb_(session_expiration_update_cb), | 710 session_expiration_update_cb_(session_expiration_update_cb), |
728 cdm_promise_adapter_(new CdmPromiseAdapter()), | 711 cdm_promise_adapter_(new CdmPromiseAdapter()), |
729 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 712 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
730 use_media_thread_(UseMediaThreadForMediaPlayback()), | |
731 media_weak_factory_(this), | |
732 weak_factory_(this) { | 713 weak_factory_(this) { |
733 DVLOG(1) << __FUNCTION__; | 714 DVLOG(1) << __FUNCTION__; |
734 | 715 |
735 JNIEnv* env = AttachCurrentThread(); | 716 JNIEnv* env = AttachCurrentThread(); |
736 CHECK(env); | 717 CHECK(env); |
737 | 718 |
738 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 719 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
739 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 720 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
740 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 721 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
741 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); | 722 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); |
742 } | 723 } |
743 | 724 |
725 MediaDrmBridge::~MediaDrmBridge() { | |
726 DCHECK(task_runner_->BelongsToCurrentThread()); | |
727 DVLOG(1) << __FUNCTION__; | |
728 | |
729 JNIEnv* env = AttachCurrentThread(); | |
730 | |
731 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | |
732 // methods anymore, this is ensured by MediaDrmBridge.java. | |
733 if (!j_media_drm_.is_null()) | |
734 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | |
735 | |
736 player_tracker_.NotifyCdmUnset(); | |
Tima Vaisburd
2015/10/29 01:17:53
There seem to be no players to notify, right? If y
xhwang
2015/10/29 03:12:31
The fact that the callback won't fire is an implem
| |
737 } | |
738 | |
744 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 739 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
745 // static | 740 // static |
746 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 741 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
747 DCHECK(IsAvailable()); | 742 DCHECK(IsAvailable()); |
748 return SECURITY_LEVEL_1 == security_level; | 743 return SECURITY_LEVEL_1 == security_level; |
749 } | 744 } |
750 | 745 |
751 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { | 746 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { |
752 JNIEnv* env = AttachCurrentThread(); | 747 JNIEnv* env = AttachCurrentThread(); |
753 ScopedJavaLocalRef<jstring> j_security_level = | 748 ScopedJavaLocalRef<jstring> j_security_level = |
754 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); | 749 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); |
755 std::string security_level_str = | 750 std::string security_level_str = |
756 ConvertJavaStringToUTF8(env, j_security_level.obj()); | 751 ConvertJavaStringToUTF8(env, j_security_level.obj()); |
757 return GetSecurityLevelFromString(security_level_str); | 752 return GetSecurityLevelFromString(security_level_str); |
758 } | 753 } |
759 | 754 |
760 void MediaDrmBridge::NotifyNewKeyOnCorrectThread() { | |
761 // Repost this method onto the Media thread if |use_media_thread_| is true. | |
762 if (use_media_thread_ && !GetMediaTaskRunner()->BelongsToCurrentThread()) { | |
763 GetMediaTaskRunner()->PostTask( | |
764 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyNewKeyOnCorrectThread, | |
765 media_weak_factory_.GetWeakPtr())); | |
766 return; | |
767 } | |
768 | |
769 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | |
770 DVLOG(1) << __FUNCTION__; | |
771 | |
772 player_tracker_.NotifyNewKey(); | |
773 } | |
774 | |
775 void MediaDrmBridge::NotifyMediaCryptoReady(const MediaCryptoReadyCB& cb) { | 755 void MediaDrmBridge::NotifyMediaCryptoReady(const MediaCryptoReadyCB& cb) { |
776 DCHECK(task_runner_->BelongsToCurrentThread()); | 756 DCHECK(task_runner_->BelongsToCurrentThread()); |
777 | 757 |
778 DCHECK(!cb.is_null()); | 758 DCHECK(!cb.is_null()); |
779 DCHECK(!GetMediaCrypto().is_null()); | 759 DCHECK(!GetMediaCrypto().is_null()); |
780 | 760 |
781 // We can use scoped_ptr to pass ScopedJavaGlobalRef with a callback. | 761 // We can use scoped_ptr to pass ScopedJavaGlobalRef with a callback. |
782 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_object_ptr( | 762 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_object_ptr( |
783 new ScopedJavaGlobalRef<jobject>()); | 763 new ScopedJavaGlobalRef<jobject>()); |
784 j_object_ptr->Reset(AttachCurrentThread(), GetMediaCrypto().obj()); | 764 j_object_ptr->Reset(AttachCurrentThread(), GetMediaCrypto().obj()); |
785 | 765 |
786 cb.Run(j_object_ptr.Pass(), IsProtectedSurfaceRequired()); | 766 cb.Run(j_object_ptr.Pass(), IsProtectedSurfaceRequired()); |
787 } | 767 } |
788 | 768 |
789 } // namespace media | 769 } // namespace media |
OLD | NEW |