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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 case RequestType::REQUEST_TYPE_RENEWAL: | 117 case RequestType::REQUEST_TYPE_RENEWAL: |
118 return ContentDecryptionModule::LICENSE_RENEWAL; | 118 return ContentDecryptionModule::LICENSE_RENEWAL; |
119 case RequestType::REQUEST_TYPE_RELEASE: | 119 case RequestType::REQUEST_TYPE_RELEASE: |
120 return ContentDecryptionModule::LICENSE_RELEASE; | 120 return ContentDecryptionModule::LICENSE_RELEASE; |
121 } | 121 } |
122 | 122 |
123 NOTREACHED(); | 123 NOTREACHED(); |
124 return ContentDecryptionModule::LICENSE_REQUEST; | 124 return ContentDecryptionModule::LICENSE_REQUEST; |
125 } | 125 } |
126 | 126 |
127 CdmKeyInformation::KeyStatus ConvertKeyStatus(KeyStatus key_status) { | 127 CdmKeyInformation::KeyStatus ConvertKeyStatus(KeyStatus key_status, |
128 bool is_key_release) { | |
128 switch (key_status) { | 129 switch (key_status) { |
129 case KeyStatus::KEY_STATUS_USABLE: | 130 case KeyStatus::KEY_STATUS_USABLE: |
130 return CdmKeyInformation::USABLE; | 131 return CdmKeyInformation::USABLE; |
131 case KeyStatus::KEY_STATUS_EXPIRED: | 132 case KeyStatus::KEY_STATUS_EXPIRED: |
132 return CdmKeyInformation::EXPIRED; | 133 return is_key_release ? CdmKeyInformation::RELEASED |
134 : CdmKeyInformation::EXPIRED; | |
133 case KeyStatus::KEY_STATUS_OUTPUT_NOT_ALLOWED: | 135 case KeyStatus::KEY_STATUS_OUTPUT_NOT_ALLOWED: |
134 return CdmKeyInformation::OUTPUT_RESTRICTED; | 136 return CdmKeyInformation::OUTPUT_RESTRICTED; |
135 case KeyStatus::KEY_STATUS_PENDING: | 137 case KeyStatus::KEY_STATUS_PENDING: |
136 // TODO(xhwang): This should probably be renamed to "PENDING". | 138 // TODO(xhwang): This should probably be renamed to "PENDING". |
137 return CdmKeyInformation::KEY_STATUS_PENDING; | 139 return CdmKeyInformation::KEY_STATUS_PENDING; |
138 case KeyStatus::KEY_STATUS_INTERNAL_ERROR: | 140 case KeyStatus::KEY_STATUS_INTERNAL_ERROR: |
139 return CdmKeyInformation::INTERNAL_ERROR; | 141 return CdmKeyInformation::INTERNAL_ERROR; |
140 } | 142 } |
141 | 143 |
142 NOTREACHED(); | 144 NOTREACHED(); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
249 int32_t os_minor_version = 0; | 251 int32_t os_minor_version = 0; |
250 int32_t os_bugfix_version = 0; | 252 int32_t os_bugfix_version = 0; |
251 base::SysInfo::OperatingSystemVersionNumbers( | 253 base::SysInfo::OperatingSystemVersionNumbers( |
252 &os_major_version, &os_minor_version, &os_bugfix_version); | 254 &os_major_version, &os_minor_version, &os_bugfix_version); |
253 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) | 255 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) |
254 return false; | 256 return false; |
255 | 257 |
256 return true; | 258 return true; |
257 } | 259 } |
258 | 260 |
261 bool IsPersistentLicenseTypeSupportedByMediaDrm() { | |
262 return MediaDrmBridge::IsAvailable() && | |
263 base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) && | |
264 base::android::BuildInfo::GetInstance()->sdk_int() >= 23; | |
265 } | |
266 | |
259 } // namespace | 267 } // namespace |
260 | 268 |
261 // MediaDrm is not generally usable without MediaCodec. Thus, both the MediaDrm | 269 // MediaDrm is not generally usable without MediaCodec. Thus, both the MediaDrm |
262 // APIs and MediaCodec APIs must be enabled and not blacklisted. | 270 // APIs and MediaCodec APIs must be enabled and not blacklisted. |
263 // static | 271 // static |
264 bool MediaDrmBridge::IsAvailable() { | 272 bool MediaDrmBridge::IsAvailable() { |
265 return AreMediaDrmApisAvailable() && MediaCodecUtil::IsMediaCodecAvailable(); | 273 return AreMediaDrmApisAvailable() && MediaCodecUtil::IsMediaCodecAvailable(); |
266 } | 274 } |
267 | 275 |
268 // static | 276 // static |
269 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 277 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
270 return RegisterNativesImpl(env); | 278 return RegisterNativesImpl(env); |
271 } | 279 } |
272 | 280 |
273 // static | 281 // static |
274 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 282 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
275 if (!MediaDrmBridge::IsAvailable()) | 283 if (!MediaDrmBridge::IsAvailable()) |
276 return false; | 284 return false; |
277 | 285 |
278 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 286 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
279 } | 287 } |
280 | 288 |
281 // static | 289 // static |
282 bool MediaDrmBridge::IsPersistentLicenseTypeSupported( | 290 bool MediaDrmBridge::IsPersistentLicenseTypeSupported( |
283 const std::string& key_system) { | 291 const std::string& key_system) { |
284 if (!MediaDrmBridge::IsAvailable()) | 292 if (!IsPersistentLicenseTypeSupportedByMediaDrm()) |
285 return false; | 293 return false; |
286 | 294 |
287 if (!base::FeatureList::IsEnabled(kMediaDrmPersistentLicense)) { | |
288 return false; | |
289 } | |
290 | |
291 NOTIMPLEMENTED() << "In development. See http://crbug.com/493521"; | 295 NOTIMPLEMENTED() << "In development. See http://crbug.com/493521"; |
xhwang
2017/04/06 04:41:30
You can move this to a comment on line 263. Then t
yucliu1
2017/04/06 16:47:24
Done.
| |
292 return false; | 296 return false; |
293 } | 297 } |
294 | 298 |
295 // static | 299 // static |
296 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 300 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
297 const std::string& key_system, | 301 const std::string& key_system, |
298 const std::string& container_mime_type) { | 302 const std::string& container_mime_type) { |
299 DCHECK(!container_mime_type.empty()) << "Call IsKeySystemSupported instead"; | 303 DCHECK(!container_mime_type.empty()) << "Call IsKeySystemSupported instead"; |
300 | 304 |
301 if (!MediaDrmBridge::IsAvailable()) | 305 if (!MediaDrmBridge::IsAvailable()) |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 promise_id); | 457 promise_id); |
454 } | 458 } |
455 | 459 |
456 void MediaDrmBridge::LoadSession( | 460 void MediaDrmBridge::LoadSession( |
457 CdmSessionType session_type, | 461 CdmSessionType session_type, |
458 const std::string& session_id, | 462 const std::string& session_id, |
459 std::unique_ptr<media::NewSessionCdmPromise> promise) { | 463 std::unique_ptr<media::NewSessionCdmPromise> promise) { |
460 DCHECK(task_runner_->BelongsToCurrentThread()); | 464 DCHECK(task_runner_->BelongsToCurrentThread()); |
461 DVLOG(2) << __func__; | 465 DVLOG(2) << __func__; |
462 | 466 |
463 DCHECK(base::FeatureList::IsEnabled(kMediaDrmPersistentLicense)); | 467 DCHECK(IsPersistentLicenseTypeSupportedByMediaDrm()); |
464 | 468 |
465 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; | 469 if (session_type != CdmSessionType::PERSISTENT_LICENSE_SESSION) { |
466 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, | 470 promise->reject( |
467 "LoadSession() is not supported."); | 471 CdmPromise::NOT_SUPPORTED_ERROR, 0, |
472 "LoadSession() is only supported for 'persistent-license'."); | |
473 return; | |
474 } | |
475 | |
476 JNIEnv* env = AttachCurrentThread(); | |
477 ScopedJavaLocalRef<jbyteArray> j_session_id = | |
478 StringToJavaBytes(env, session_id); | |
479 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | |
480 Java_MediaDrmBridge_loadSession(env, j_media_drm_, j_session_id, promise_id); | |
468 } | 481 } |
469 | 482 |
470 void MediaDrmBridge::UpdateSession( | 483 void MediaDrmBridge::UpdateSession( |
471 const std::string& session_id, | 484 const std::string& session_id, |
472 const std::vector<uint8_t>& response, | 485 const std::vector<uint8_t>& response, |
473 std::unique_ptr<media::SimpleCdmPromise> promise) { | 486 std::unique_ptr<media::SimpleCdmPromise> promise) { |
474 DCHECK(task_runner_->BelongsToCurrentThread()); | 487 DCHECK(task_runner_->BelongsToCurrentThread()); |
475 DVLOG(2) << __func__; | 488 DVLOG(2) << __func__; |
476 | 489 |
477 JNIEnv* env = AttachCurrentThread(); | 490 JNIEnv* env = AttachCurrentThread(); |
478 ScopedJavaLocalRef<jbyteArray> j_response = | 491 ScopedJavaLocalRef<jbyteArray> j_response = |
479 base::android::ToJavaByteArray(env, response.data(), response.size()); | 492 base::android::ToJavaByteArray(env, response.data(), response.size()); |
480 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( | 493 ScopedJavaLocalRef<jbyteArray> j_session_id = |
481 env, reinterpret_cast<const uint8_t*>(session_id.data()), | 494 StringToJavaBytes(env, session_id); |
482 session_id.size()); | |
483 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 495 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
484 Java_MediaDrmBridge_updateSession(env, j_media_drm_, j_session_id, j_response, | 496 Java_MediaDrmBridge_updateSession(env, j_media_drm_, j_session_id, j_response, |
485 promise_id); | 497 promise_id); |
486 } | 498 } |
487 | 499 |
488 void MediaDrmBridge::CloseSession( | 500 void MediaDrmBridge::CloseSession( |
489 const std::string& session_id, | 501 const std::string& session_id, |
490 std::unique_ptr<media::SimpleCdmPromise> promise) { | 502 std::unique_ptr<media::SimpleCdmPromise> promise) { |
491 DCHECK(task_runner_->BelongsToCurrentThread()); | 503 DCHECK(task_runner_->BelongsToCurrentThread()); |
492 DVLOG(2) << __func__; | 504 DVLOG(2) << __func__; |
493 | 505 |
494 JNIEnv* env = AttachCurrentThread(); | 506 JNIEnv* env = AttachCurrentThread(); |
495 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( | 507 ScopedJavaLocalRef<jbyteArray> j_session_id = |
496 env, reinterpret_cast<const uint8_t*>(session_id.data()), | 508 StringToJavaBytes(env, session_id); |
497 session_id.size()); | |
498 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 509 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
499 Java_MediaDrmBridge_closeSession(env, j_media_drm_, j_session_id, promise_id); | 510 Java_MediaDrmBridge_closeSession(env, j_media_drm_, j_session_id, promise_id); |
500 } | 511 } |
501 | 512 |
502 void MediaDrmBridge::RemoveSession( | 513 void MediaDrmBridge::RemoveSession( |
503 const std::string& session_id, | 514 const std::string& session_id, |
504 std::unique_ptr<media::SimpleCdmPromise> promise) { | 515 std::unique_ptr<media::SimpleCdmPromise> promise) { |
505 DCHECK(task_runner_->BelongsToCurrentThread()); | 516 DCHECK(task_runner_->BelongsToCurrentThread()); |
506 DVLOG(2) << __func__; | 517 DVLOG(2) << __func__; |
507 | 518 |
508 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; | 519 JNIEnv* env = AttachCurrentThread(); |
509 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, | 520 ScopedJavaLocalRef<jbyteArray> j_session_id = |
510 "RemoveSession() is not supported."); | 521 StringToJavaBytes(env, session_id); |
522 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | |
523 Java_MediaDrmBridge_removeSession(env, j_media_drm_, j_session_id, | |
524 promise_id); | |
511 } | 525 } |
512 | 526 |
513 CdmContext* MediaDrmBridge::GetCdmContext() { | 527 CdmContext* MediaDrmBridge::GetCdmContext() { |
514 DVLOG(2) << __func__; | 528 DVLOG(2) << __func__; |
515 | 529 |
516 return &media_drm_bridge_cdm_context_; | 530 return &media_drm_bridge_cdm_context_; |
517 } | 531 } |
518 | 532 |
519 void MediaDrmBridge::DeleteOnCorrectThread() const { | 533 void MediaDrmBridge::DeleteOnCorrectThread() const { |
520 DVLOG(1) << __func__; | 534 DVLOG(1) << __func__; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 DVLOG(2) << __func__; | 705 DVLOG(2) << __func__; |
692 std::string session_id = JavaBytesToString(env, j_session_id); | 706 std::string session_id = JavaBytesToString(env, j_session_id); |
693 task_runner_->PostTask(FROM_HERE, base::Bind(session_closed_cb_, session_id)); | 707 task_runner_->PostTask(FROM_HERE, base::Bind(session_closed_cb_, session_id)); |
694 } | 708 } |
695 | 709 |
696 void MediaDrmBridge::OnSessionKeysChange( | 710 void MediaDrmBridge::OnSessionKeysChange( |
697 JNIEnv* env, | 711 JNIEnv* env, |
698 const JavaParamRef<jobject>& j_media_drm, | 712 const JavaParamRef<jobject>& j_media_drm, |
699 const JavaParamRef<jbyteArray>& j_session_id, | 713 const JavaParamRef<jbyteArray>& j_session_id, |
700 const JavaParamRef<jobjectArray>& j_keys_info, | 714 const JavaParamRef<jobjectArray>& j_keys_info, |
701 bool has_additional_usable_key) { | 715 bool has_additional_usable_key, |
716 bool is_key_release) { | |
702 DVLOG(2) << __func__; | 717 DVLOG(2) << __func__; |
703 | 718 |
704 CdmKeysInfo cdm_keys_info; | 719 CdmKeysInfo cdm_keys_info; |
705 | 720 |
706 size_t size = env->GetArrayLength(j_keys_info); | 721 size_t size = env->GetArrayLength(j_keys_info); |
707 DCHECK_GT(size, 0u); | 722 DCHECK_GT(size, 0u); |
708 | 723 |
709 for (size_t i = 0; i < size; ++i) { | 724 for (size_t i = 0; i < size; ++i) { |
710 ScopedJavaLocalRef<jobject> j_key_status( | 725 ScopedJavaLocalRef<jobject> j_key_status( |
711 env, env->GetObjectArrayElement(j_keys_info, i)); | 726 env, env->GetObjectArrayElement(j_keys_info, i)); |
712 | 727 |
713 ScopedJavaLocalRef<jbyteArray> j_key_id = | 728 ScopedJavaLocalRef<jbyteArray> j_key_id = |
714 Java_KeyStatus_getKeyId(env, j_key_status); | 729 Java_KeyStatus_getKeyId(env, j_key_status); |
715 std::vector<uint8_t> key_id; | 730 std::vector<uint8_t> key_id; |
716 JavaByteArrayToByteVector(env, j_key_id.obj(), &key_id); | 731 JavaByteArrayToByteVector(env, j_key_id.obj(), &key_id); |
717 DCHECK(!key_id.empty()); | 732 DCHECK(!key_id.empty()); |
718 | 733 |
719 jint j_status_code = Java_KeyStatus_getStatusCode(env, j_key_status); | 734 jint j_status_code = Java_KeyStatus_getStatusCode(env, j_key_status); |
720 CdmKeyInformation::KeyStatus key_status = | 735 CdmKeyInformation::KeyStatus key_status = |
721 ConvertKeyStatus(static_cast<KeyStatus>(j_status_code)); | 736 ConvertKeyStatus(static_cast<KeyStatus>(j_status_code), is_key_release); |
722 | 737 |
723 DVLOG(2) << __func__ << "Key status change: " | 738 DVLOG(2) << __func__ << "Key status change: " |
724 << base::HexEncode(&key_id[0], key_id.size()) << ", " | 739 << base::HexEncode(&key_id[0], key_id.size()) << ", " |
725 << key_status; | 740 << key_status; |
726 | 741 |
727 cdm_keys_info.push_back(new CdmKeyInformation(key_id, key_status, 0)); | 742 cdm_keys_info.push_back(new CdmKeyInformation(key_id, key_status, 0)); |
728 } | 743 } |
729 | 744 |
730 task_runner_->PostTask( | 745 task_runner_->PostTask( |
731 FROM_HERE, | 746 FROM_HERE, |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
909 DVLOG(1) << __func__; | 924 DVLOG(1) << __func__; |
910 | 925 |
911 DCHECK(provision_fetcher_) << "No provision request pending."; | 926 DCHECK(provision_fetcher_) << "No provision request pending."; |
912 provision_fetcher_.reset(); | 927 provision_fetcher_.reset(); |
913 | 928 |
914 if (!success) | 929 if (!success) |
915 VLOG(1) << "Device provision failure: can't get server response"; | 930 VLOG(1) << "Device provision failure: can't get server response"; |
916 | 931 |
917 JNIEnv* env = AttachCurrentThread(); | 932 JNIEnv* env = AttachCurrentThread(); |
918 | 933 |
919 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( | 934 ScopedJavaLocalRef<jbyteArray> j_response = StringToJavaBytes(env, response); |
920 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); | |
921 | 935 |
922 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_, success, | 936 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_, success, |
923 j_response); | 937 j_response); |
924 } | 938 } |
925 | 939 |
926 void MediaDrmBridge::OnHasAdditionalUsableKey() { | 940 void MediaDrmBridge::OnHasAdditionalUsableKey() { |
927 DCHECK(task_runner_->BelongsToCurrentThread()); | 941 DCHECK(task_runner_->BelongsToCurrentThread()); |
928 DVLOG(1) << __func__; | 942 DVLOG(1) << __func__; |
929 | 943 |
930 player_tracker_.NotifyNewKey(); | 944 player_tracker_.NotifyNewKey(); |
931 } | 945 } |
932 | 946 |
933 } // namespace media | 947 } // namespace media |
OLD | NEW |