| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 | 312 |
| 313 // static | 313 // static |
| 314 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 314 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
| 315 if (!MediaDrmBridge::IsAvailable()) | 315 if (!MediaDrmBridge::IsAvailable()) |
| 316 return std::vector<std::string>(); | 316 return std::vector<std::string>(); |
| 317 | 317 |
| 318 return GetKeySystemManager()->GetPlatformKeySystemNames(); | 318 return GetKeySystemManager()->GetPlatformKeySystemNames(); |
| 319 } | 319 } |
| 320 | 320 |
| 321 // static | 321 // static |
| 322 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal( | 322 void MediaDrmBridge::CreateInternal( |
| 323 const std::string& key_system, | 323 const std::vector<uint8_t>& scheme_uuid, |
| 324 const GURL& security_origin, | |
| 325 SecurityLevel security_level, | 324 SecurityLevel security_level, |
| 325 std::unique_ptr<MediaDrmStorageBridge> storage, |
| 326 const CreateFetcherCB& create_fetcher_cb, | 326 const CreateFetcherCB& create_fetcher_cb, |
| 327 const CreateStorageCB& create_storage_cb, | |
| 328 const SessionMessageCB& session_message_cb, | 327 const SessionMessageCB& session_message_cb, |
| 329 const SessionClosedCB& session_closed_cb, | 328 const SessionClosedCB& session_closed_cb, |
| 330 const SessionKeysChangeCB& session_keys_change_cb, | 329 const SessionKeysChangeCB& session_keys_change_cb, |
| 331 const SessionExpirationUpdateCB& session_expiration_update_cb) { | 330 const SessionExpirationUpdateCB& session_expiration_update_cb, |
| 331 CreatedCB created_cb) { |
| 332 // All paths requires the MediaDrmApis. | 332 // All paths requires the MediaDrmApis. |
| 333 DCHECK(AreMediaDrmApisAvailable()); | 333 DCHECK(AreMediaDrmApisAvailable()); |
| 334 | 334 DCHECK(!scheme_uuid.empty()); |
| 335 UUID scheme_uuid = GetKeySystemManager()->GetUUID(key_system); | |
| 336 if (scheme_uuid.empty()) | |
| 337 return nullptr; | |
| 338 | 335 |
| 339 scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge( | 336 scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge( |
| 340 scheme_uuid, security_origin, security_level, create_fetcher_cb, | 337 scheme_uuid, security_level, std::move(storage), create_fetcher_cb, |
| 341 create_storage_cb, session_message_cb, session_closed_cb, | 338 session_message_cb, session_closed_cb, session_keys_change_cb, |
| 342 session_keys_change_cb, session_expiration_update_cb)); | 339 session_expiration_update_cb)); |
| 343 | 340 |
| 344 if (media_drm_bridge->j_media_drm_.is_null()) | 341 if (media_drm_bridge->j_media_drm_.is_null()) |
| 345 media_drm_bridge = nullptr; | 342 media_drm_bridge = nullptr; |
| 346 | 343 |
| 347 return media_drm_bridge; | 344 // Return |media_drm_bridge| asynchronously to make the callback binding |
| 345 // easier. |
| 346 std::move(created_cb).Run(std::move(media_drm_bridge)); |
| 348 } | 347 } |
| 349 | 348 |
| 350 // static | 349 // static |
| 351 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create( | 350 void MediaDrmBridge::Create( |
| 352 const std::string& key_system, | 351 const std::string& key_system, |
| 353 const GURL& security_origin, | 352 const GURL& security_origin, |
| 354 SecurityLevel security_level, | 353 SecurityLevel security_level, |
| 355 const CreateFetcherCB& create_fetcher_cb, | 354 const CreateFetcherCB& create_fetcher_cb, |
| 356 const CreateStorageCB& create_storage_cb, | 355 const CreateStorageCB& create_storage_cb, |
| 357 const SessionMessageCB& session_message_cb, | 356 const SessionMessageCB& session_message_cb, |
| 358 const SessionClosedCB& session_closed_cb, | 357 const SessionClosedCB& session_closed_cb, |
| 359 const SessionKeysChangeCB& session_keys_change_cb, | 358 const SessionKeysChangeCB& session_keys_change_cb, |
| 360 const SessionExpirationUpdateCB& session_expiration_update_cb) { | 359 const SessionExpirationUpdateCB& session_expiration_update_cb, |
| 360 CreatedCB created_cb) { |
| 361 DVLOG(1) << __func__; | 361 DVLOG(1) << __func__; |
| 362 | 362 |
| 363 if (!IsAvailable()) | 363 if (!IsAvailable()) { |
| 364 return nullptr; | 364 std::move(created_cb).Run(nullptr); |
| 365 return; |
| 366 } |
| 365 | 367 |
| 366 return CreateInternal(key_system, security_origin, security_level, | 368 UUID scheme_uuid = GetKeySystemManager()->GetUUID(key_system); |
| 367 create_fetcher_cb, create_storage_cb, | 369 if (scheme_uuid.empty()) { |
| 368 session_message_cb, session_closed_cb, | 370 std::move(created_cb).Run(nullptr); |
| 369 session_keys_change_cb, session_expiration_update_cb); | 371 return; |
| 372 } |
| 373 |
| 374 // MediaDrmStorage may be lazy created in MediaDrmStorageBridge. |
| 375 auto storage = base::MakeUnique<MediaDrmStorageBridge>(); |
| 376 MediaDrmStorageBridge* raw_storage = storage.get(); |
| 377 |
| 378 base::OnceClosure create_media_drm_cb = base::BindOnce( |
| 379 &MediaDrmBridge::CreateInternal, scheme_uuid, security_level, |
| 380 base::Passed(&storage), create_fetcher_cb, session_message_cb, |
| 381 session_closed_cb, session_keys_change_cb, session_expiration_update_cb, |
| 382 base::Passed(&created_cb)); |
| 383 |
| 384 if (IsPersistentLicenseTypeSupported(key_system) && |
| 385 !security_origin.is_empty() && !create_storage_cb.is_null()) { |
| 386 raw_storage->Initialize(url::Origin(security_origin), create_storage_cb, |
| 387 std::move(create_media_drm_cb)); |
| 388 } else { |
| 389 std::move(create_media_drm_cb).Run(); |
| 390 } |
| 370 } | 391 } |
| 371 | 392 |
| 372 // static | 393 // static |
| 373 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( | 394 void MediaDrmBridge::CreateWithoutSessionSupport( |
| 374 const std::string& key_system, | 395 const std::string& key_system, |
| 375 SecurityLevel security_level, | 396 SecurityLevel security_level, |
| 376 const CreateFetcherCB& create_fetcher_cb) { | 397 const CreateFetcherCB& create_fetcher_cb, |
| 398 CreatedCB created_cb) { |
| 377 DVLOG(1) << __func__; | 399 DVLOG(1) << __func__; |
| 378 | 400 |
| 379 // Sessions won't be used so decoding capability is not required. | 401 // Sessions won't be used so decoding capability is not required. |
| 380 if (!AreMediaDrmApisAvailable()) | 402 if (!AreMediaDrmApisAvailable()) { |
| 381 return nullptr; | 403 std::move(created_cb).Run(nullptr); |
| 404 return; |
| 405 } |
| 382 | 406 |
| 383 return MediaDrmBridge::Create( | 407 MediaDrmBridge::Create(key_system, GURL::EmptyGURL(), security_level, |
| 384 key_system, GURL::EmptyGURL(), security_level, create_fetcher_cb, | 408 create_fetcher_cb, CreateStorageCB(), |
| 385 CreateStorageCB(), SessionMessageCB(), SessionClosedCB(), | 409 SessionMessageCB(), SessionClosedCB(), |
| 386 SessionKeysChangeCB(), SessionExpirationUpdateCB()); | 410 SessionKeysChangeCB(), SessionExpirationUpdateCB(), |
| 411 std::move(created_cb)); |
| 387 } | 412 } |
| 388 | 413 |
| 389 void MediaDrmBridge::SetServerCertificate( | 414 void MediaDrmBridge::SetServerCertificate( |
| 390 const std::vector<uint8_t>& certificate, | 415 const std::vector<uint8_t>& certificate, |
| 391 std::unique_ptr<media::SimpleCdmPromise> promise) { | 416 std::unique_ptr<media::SimpleCdmPromise> promise) { |
| 392 DCHECK(task_runner_->BelongsToCurrentThread()); | 417 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 393 DVLOG(2) << __func__ << "(" << certificate.size() << " bytes)"; | 418 DVLOG(2) << __func__ << "(" << certificate.size() << " bytes)"; |
| 394 | 419 |
| 395 DCHECK(!certificate.empty()); | 420 DCHECK(!certificate.empty()); |
| 396 | 421 |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 task_runner_->PostTask( | 819 task_runner_->PostTask( |
| 795 FROM_HERE, | 820 FROM_HERE, |
| 796 base::Bind(base::ResetAndReturn(&reset_credentials_cb_), success)); | 821 base::Bind(base::ResetAndReturn(&reset_credentials_cb_), success)); |
| 797 } | 822 } |
| 798 | 823 |
| 799 //------------------------------------------------------------------------------ | 824 //------------------------------------------------------------------------------ |
| 800 // The following are private methods. | 825 // The following are private methods. |
| 801 | 826 |
| 802 MediaDrmBridge::MediaDrmBridge( | 827 MediaDrmBridge::MediaDrmBridge( |
| 803 const std::vector<uint8_t>& scheme_uuid, | 828 const std::vector<uint8_t>& scheme_uuid, |
| 804 const GURL& security_origin, | |
| 805 SecurityLevel security_level, | 829 SecurityLevel security_level, |
| 830 std::unique_ptr<MediaDrmStorageBridge> storage, |
| 806 const CreateFetcherCB& create_fetcher_cb, | 831 const CreateFetcherCB& create_fetcher_cb, |
| 807 const CreateStorageCB& create_storage_cb, | |
| 808 const SessionMessageCB& session_message_cb, | 832 const SessionMessageCB& session_message_cb, |
| 809 const SessionClosedCB& session_closed_cb, | 833 const SessionClosedCB& session_closed_cb, |
| 810 const SessionKeysChangeCB& session_keys_change_cb, | 834 const SessionKeysChangeCB& session_keys_change_cb, |
| 811 const SessionExpirationUpdateCB& session_expiration_update_cb) | 835 const SessionExpirationUpdateCB& session_expiration_update_cb) |
| 812 : scheme_uuid_(scheme_uuid), | 836 : scheme_uuid_(scheme_uuid), |
| 813 storage_(url::Origin(security_origin), create_storage_cb), | 837 storage_(std::move(storage)), |
| 814 create_fetcher_cb_(create_fetcher_cb), | 838 create_fetcher_cb_(create_fetcher_cb), |
| 815 session_message_cb_(session_message_cb), | 839 session_message_cb_(session_message_cb), |
| 816 session_closed_cb_(session_closed_cb), | 840 session_closed_cb_(session_closed_cb), |
| 817 session_keys_change_cb_(session_keys_change_cb), | 841 session_keys_change_cb_(session_keys_change_cb), |
| 818 session_expiration_update_cb_(session_expiration_update_cb), | 842 session_expiration_update_cb_(session_expiration_update_cb), |
| 819 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 843 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 820 media_drm_bridge_cdm_context_(this), | 844 media_drm_bridge_cdm_context_(this), |
| 821 weak_factory_(this) { | 845 weak_factory_(this) { |
| 822 DVLOG(1) << __func__; | 846 DVLOG(1) << __func__; |
| 823 | 847 |
| 824 DCHECK(!create_fetcher_cb_.is_null()); | 848 DCHECK(storage_); |
| 849 DCHECK(create_fetcher_cb_); |
| 825 | 850 |
| 826 JNIEnv* env = AttachCurrentThread(); | 851 JNIEnv* env = AttachCurrentThread(); |
| 827 CHECK(env); | 852 CHECK(env); |
| 828 | 853 |
| 829 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 854 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
| 830 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 855 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
| 831 | 856 |
| 832 std::string security_level_str = GetSecurityLevelString(security_level); | 857 std::string security_level_str = GetSecurityLevelString(security_level); |
| 833 ScopedJavaLocalRef<jstring> j_security_level = | 858 ScopedJavaLocalRef<jstring> j_security_level = |
| 834 ConvertUTF8ToJavaString(env, security_level_str); | 859 ConvertUTF8ToJavaString(env, security_level_str); |
| 835 | 860 |
| 836 bool use_origin_isolated_storage = | 861 bool use_origin_isolated_storage = |
| 837 // TODO(yucliu): Remove the check once persistent storage is fully | 862 // TODO(yucliu): Remove the check once persistent storage is fully |
| 838 // supported and check if origin is valid. | 863 // supported and check if origin is valid. |
| 839 base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) && | 864 base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) && |
| 840 // MediaDrm implements origin isolated storage on M. | 865 // MediaDrm implements origin isolated storage on M. |
| 841 base::android::BuildInfo::GetInstance()->sdk_int() >= 23; | 866 base::android::BuildInfo::GetInstance()->sdk_int() >= 23 && |
| 867 // origin id can be empty when MediaDrmBridge is created by |
| 868 // CreateWithoutSessionSupport, which is used to reset credentials. |
| 869 !storage_->origin_id().empty(); |
| 842 | 870 |
| 843 // TODO(yucliu): Per EME spec on individualization, implementation should not | 871 // TODO(yucliu): Per EME spec on individualization, implementation should not |
| 844 // expose application-specific information. Considering encode origin before | 872 // expose application-specific information. Considering encode origin before |
| 845 // passing to MediaDrm. | 873 // passing to MediaDrm. |
| 846 ScopedJavaLocalRef<jstring> j_security_origin = ConvertUTF8ToJavaString( | 874 ScopedJavaLocalRef<jstring> j_security_origin = ConvertUTF8ToJavaString( |
| 847 env, use_origin_isolated_storage ? security_origin.spec() : ""); | 875 env, use_origin_isolated_storage ? storage_->origin_id() : ""); |
| 848 | 876 |
| 849 // TODO(yucliu): Use |create_storage_cb_| to create MediaDrmStorage which can | 877 // TODO(yucliu): Use |create_storage_cb_| to create MediaDrmStorage which can |
| 850 // be used by Java side to store/retrieve persistent data. This should only | 878 // be used by Java side to store/retrieve persistent data. This should only |
| 851 // be used when |use_origin_isolated_storage| is true. | 879 // be used when |use_origin_isolated_storage| is true. |
| 852 | 880 |
| 853 // Note: OnMediaCryptoReady() could be called in this call. | 881 // Note: OnMediaCryptoReady() could be called in this call. |
| 854 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 882 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
| 855 env, j_scheme_uuid, j_security_origin, j_security_level, | 883 env, j_scheme_uuid, j_security_origin, j_security_level, |
| 856 reinterpret_cast<intptr_t>(this), reinterpret_cast<intptr_t>(&storage_))); | 884 reinterpret_cast<intptr_t>(this), |
| 885 reinterpret_cast<intptr_t>(storage_.get()))); |
| 857 } | 886 } |
| 858 | 887 |
| 859 MediaDrmBridge::~MediaDrmBridge() { | 888 MediaDrmBridge::~MediaDrmBridge() { |
| 860 DCHECK(task_runner_->BelongsToCurrentThread()); | 889 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 861 DVLOG(1) << __func__; | 890 DVLOG(1) << __func__; |
| 862 | 891 |
| 863 JNIEnv* env = AttachCurrentThread(); | 892 JNIEnv* env = AttachCurrentThread(); |
| 864 | 893 |
| 865 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | 894 // After the call to Java_MediaDrmBridge_destroy() Java won't call native |
| 866 // methods anymore, this is ensured by MediaDrmBridge.java. | 895 // methods anymore, this is ensured by MediaDrmBridge.java. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 } | 968 } |
| 940 | 969 |
| 941 void MediaDrmBridge::OnHasAdditionalUsableKey() { | 970 void MediaDrmBridge::OnHasAdditionalUsableKey() { |
| 942 DCHECK(task_runner_->BelongsToCurrentThread()); | 971 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 943 DVLOG(1) << __func__; | 972 DVLOG(1) << __func__; |
| 944 | 973 |
| 945 player_tracker_.NotifyNewKey(); | 974 player_tracker_.NotifyNewKey(); |
| 946 } | 975 } |
| 947 | 976 |
| 948 } // namespace media | 977 } // namespace media |
| OLD | NEW |