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/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
13 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
14 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
15 #include "base/location.h" | 16 #include "base/location.h" |
16 #include "base/logging.h" | 17 #include "base/logging.h" |
17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
18 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
21 #include "base/sys_byteorder.h" | 22 #include "base/sys_byteorder.h" |
22 #include "base/sys_info.h" | 23 #include "base/sys_info.h" |
23 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
24 #include "jni/MediaDrmBridge_jni.h" | 25 #include "jni/MediaDrmBridge_jni.h" |
25 #include "media/base/android/media_client_android.h" | 26 #include "media/base/android/media_client_android.h" |
| 27 #include "media/base/android/media_codec_player.h" // for GetMediaTaskRunner() |
26 #include "media/base/android/media_drm_bridge_delegate.h" | 28 #include "media/base/android/media_drm_bridge_delegate.h" |
27 #include "media/base/cdm_key_information.h" | 29 #include "media/base/cdm_key_information.h" |
28 | 30 |
29 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 31 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
30 | 32 |
| 33 #define RUN_CB_ON_MEDIA_THREAD(CB, ...) \ |
| 34 do { \ |
| 35 if (run_on_media_thread_ && \ |
| 36 !GetMediaTaskRunner()->BelongsToCurrentThread()) { \ |
| 37 GetMediaTaskRunner()->PostTask(FROM_HERE, \ |
| 38 base::Bind(CB, ##__VA_ARGS__)); \ |
| 39 } else { \ |
| 40 CB.Run(__VA_ARGS__); \ |
| 41 } \ |
| 42 } while (0) |
| 43 |
31 using base::android::AttachCurrentThread; | 44 using base::android::AttachCurrentThread; |
32 using base::android::ConvertUTF8ToJavaString; | 45 using base::android::ConvertUTF8ToJavaString; |
33 using base::android::ConvertJavaStringToUTF8; | 46 using base::android::ConvertJavaStringToUTF8; |
34 using base::android::JavaByteArrayToByteVector; | 47 using base::android::JavaByteArrayToByteVector; |
35 using base::android::ScopedJavaLocalRef; | 48 using base::android::ScopedJavaLocalRef; |
36 | 49 |
37 namespace media { | 50 namespace media { |
38 | 51 |
39 namespace { | 52 namespace { |
40 | 53 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 int32 os_bugfix_version = 0; | 234 int32 os_bugfix_version = 0; |
222 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, | 235 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, |
223 &os_minor_version, | 236 &os_minor_version, |
224 &os_bugfix_version); | 237 &os_bugfix_version); |
225 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) | 238 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) |
226 return false; | 239 return false; |
227 | 240 |
228 return true; | 241 return true; |
229 } | 242 } |
230 | 243 |
| 244 // static |
| 245 bool MediaDrmBridge::CanCreate(const std::string& key_system, |
| 246 SecurityLevel widevine_security_level) { |
| 247 if (!IsAvailable()) { |
| 248 DVLOG(1) << __FUNCTION__ << ": DRM is not available"; |
| 249 return false; |
| 250 } |
| 251 |
| 252 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
| 253 if (scheme_uuid.empty()) { |
| 254 DVLOG(1) << __FUNCTION__ << ": key system " << key_system |
| 255 << " not supported"; |
| 256 return false; |
| 257 } |
| 258 |
| 259 if (key_system == kWidevineKeySystem && |
| 260 widevine_security_level != SECURITY_LEVEL_NONE && |
| 261 !std::equal(scheme_uuid.begin(), scheme_uuid.end(), kWidevineUuid)) { |
| 262 NOTREACHED() << "Widevine security level " << widevine_security_level |
| 263 << "used with another key system"; |
| 264 return false; |
| 265 } |
| 266 return true; |
| 267 } |
| 268 |
231 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 269 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
232 // static | 270 // static |
233 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 271 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
234 DCHECK(IsAvailable()); | 272 DCHECK(IsAvailable()); |
235 return SECURITY_LEVEL_1 == security_level; | 273 return SECURITY_LEVEL_1 == security_level; |
236 } | 274 } |
237 | 275 |
238 // static | 276 // static |
239 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 277 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
240 return g_key_system_manager.Get().GetPlatformKeySystemNames(); | 278 return g_key_system_manager.Get().GetPlatformKeySystemNames(); |
241 } | 279 } |
242 | 280 |
243 // static | 281 // static |
244 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 282 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
245 DCHECK(!key_system.empty()); | 283 DCHECK(!key_system.empty()); |
246 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 284 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
247 } | 285 } |
248 | 286 |
249 // static | 287 // static |
250 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 288 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
251 const std::string& key_system, | 289 const std::string& key_system, |
252 const std::string& container_mime_type) { | 290 const std::string& container_mime_type) { |
253 DCHECK(!key_system.empty() && !container_mime_type.empty()); | 291 DCHECK(!key_system.empty() && !container_mime_type.empty()); |
254 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); | 292 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
255 } | 293 } |
256 | 294 |
| 295 // static |
257 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 296 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
258 return RegisterNativesImpl(env); | 297 return RegisterNativesImpl(env); |
259 } | 298 } |
260 | 299 |
261 MediaDrmBridge::MediaDrmBridge( | 300 MediaDrmBridge::MediaDrmBridge( |
262 const std::vector<uint8>& scheme_uuid, | 301 const std::vector<uint8>& scheme_uuid, |
263 const SessionMessageCB& session_message_cb, | 302 const SessionMessageCB& session_message_cb, |
264 const SessionClosedCB& session_closed_cb, | 303 const SessionClosedCB& session_closed_cb, |
265 const LegacySessionErrorCB& legacy_session_error_cb, | 304 const LegacySessionErrorCB& legacy_session_error_cb, |
266 const SessionKeysChangeCB& session_keys_change_cb, | 305 const SessionKeysChangeCB& session_keys_change_cb, |
267 const SessionExpirationUpdateCB& session_expiration_update_cb) | 306 const SessionExpirationUpdateCB& session_expiration_update_cb) |
268 : scheme_uuid_(scheme_uuid), | 307 : scheme_uuid_(scheme_uuid), |
269 session_message_cb_(session_message_cb), | 308 session_message_cb_(session_message_cb), |
270 session_closed_cb_(session_closed_cb), | 309 session_closed_cb_(session_closed_cb), |
271 legacy_session_error_cb_(legacy_session_error_cb), | 310 legacy_session_error_cb_(legacy_session_error_cb), |
272 session_keys_change_cb_(session_keys_change_cb), | 311 session_keys_change_cb_(session_keys_change_cb), |
273 session_expiration_update_cb_(session_expiration_update_cb) { | 312 session_expiration_update_cb_(session_expiration_update_cb), |
| 313 run_on_media_thread_(false) { |
| 314 DVLOG(1) << "MediaDrmBridge::MediaDrmBridge"; |
| 315 |
| 316 // When this flag is set we need to repost the notifications coming from |
| 317 // Java UI thread to the media thread. |
| 318 run_on_media_thread_ = GetMediaTaskRunner()->BelongsToCurrentThread(); |
| 319 |
| 320 // Create internal callbacks to repost Java notifications to the media thread. |
| 321 // TODO(timav): weak pointers instead of unretained? |
| 322 |
| 323 /* |
| 324 internal_promise_resolved_cb_ = base::Bind( |
| 325 &MediaDrmBridge::InternalPromiseResolved, base::Unretained(this)); |
| 326 internal_promise_resolved_with_session_cb_ = base::Bind( |
| 327 &MediaDrmBridge::InternalPromiseResolvedWithSession, |
| 328 base::Unretained(this)); |
| 329 internal_promise_rejected_cb_ = base::Bind( |
| 330 &MediaDrmBridge::InternalPromiseRejected, base::Unretained(this)); |
| 331 internal_session_keys_changed_cb_ = base::Bind( |
| 332 &MediaDrmBridge::InternalSessionKeysChanged, base::Unretained(this)); |
| 333 */ |
| 334 |
| 335 internal_keys_added_cb_ = |
| 336 base::Bind(&MediaDrmBridge::InternalKeysAdded, base::Unretained(this)); |
| 337 |
274 JNIEnv* env = AttachCurrentThread(); | 338 JNIEnv* env = AttachCurrentThread(); |
275 CHECK(env); | 339 CHECK(env); |
276 | 340 |
277 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 341 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
278 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 342 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
279 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 343 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
280 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); | 344 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); |
281 } | 345 } |
282 | 346 |
283 MediaDrmBridge::~MediaDrmBridge() { | 347 MediaDrmBridge::~MediaDrmBridge() { |
284 JNIEnv* env = AttachCurrentThread(); | 348 JNIEnv* env = AttachCurrentThread(); |
285 player_tracker_.NotifyCdmUnset(); | 349 player_tracker_.NotifyCdmUnset(); |
286 if (!j_media_drm_.is_null()) | 350 if (!j_media_drm_.is_null()) |
287 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | 351 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); |
288 } | 352 } |
289 | 353 |
290 // static | 354 // static |
291 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( | 355 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> MediaDrmBridge::Create( |
292 const std::string& key_system, | 356 const std::string& key_system, |
| 357 SecurityLevel widevine_security_level, |
293 const SessionMessageCB& session_message_cb, | 358 const SessionMessageCB& session_message_cb, |
294 const SessionClosedCB& session_closed_cb, | 359 const SessionClosedCB& session_closed_cb, |
295 const LegacySessionErrorCB& legacy_session_error_cb, | 360 const LegacySessionErrorCB& legacy_session_error_cb, |
296 const SessionKeysChangeCB& session_keys_change_cb, | 361 const SessionKeysChangeCB& session_keys_change_cb, |
297 const SessionExpirationUpdateCB& session_expiration_update_cb) { | 362 const SessionExpirationUpdateCB& session_expiration_update_cb) { |
298 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 363 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> media_drm_bridge; |
299 if (!IsAvailable()) | 364 if (!IsAvailable()) |
300 return media_drm_bridge.Pass(); | 365 return media_drm_bridge.Pass(); |
301 | 366 |
302 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); | 367 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
303 if (scheme_uuid.empty()) | 368 if (scheme_uuid.empty()) |
304 return media_drm_bridge.Pass(); | 369 return media_drm_bridge.Pass(); |
305 | 370 |
306 media_drm_bridge.reset( | 371 media_drm_bridge.reset( |
307 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, | 372 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, |
308 legacy_session_error_cb, session_keys_change_cb, | 373 legacy_session_error_cb, session_keys_change_cb, |
309 session_expiration_update_cb)); | 374 session_expiration_update_cb)); |
310 | 375 |
311 if (media_drm_bridge->j_media_drm_.is_null()) | 376 if (media_drm_bridge->j_media_drm_.is_null()) |
312 media_drm_bridge.reset(); | 377 media_drm_bridge.reset(); |
313 | 378 |
| 379 if (key_system == kWidevineKeySystem && |
| 380 widevine_security_level != SECURITY_LEVEL_NONE && |
| 381 !media_drm_bridge->SetSecurityLevel(widevine_security_level)) { |
| 382 DVLOG(1) << __FUNCTION__ << ": failed to set security level " |
| 383 << widevine_security_level; |
| 384 media_drm_bridge.reset(); |
| 385 } |
| 386 |
314 return media_drm_bridge.Pass(); | 387 return media_drm_bridge.Pass(); |
315 } | 388 } |
316 | 389 |
317 // static | 390 // static |
318 scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( | 391 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> |
319 const std::string& key_system) { | 392 MediaDrmBridge::CreateWithoutSessionSupport(const std::string& key_system) { |
320 return MediaDrmBridge::Create( | 393 return MediaDrmBridge::Create(key_system, SECURITY_LEVEL_NONE, |
321 key_system, SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(), | 394 SessionMessageCB(), SessionClosedCB(), |
322 SessionKeysChangeCB(), SessionExpirationUpdateCB()); | 395 LegacySessionErrorCB(), SessionKeysChangeCB(), |
| 396 SessionExpirationUpdateCB()); |
323 } | 397 } |
324 | 398 |
325 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { | 399 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { |
326 if (security_level != SECURITY_LEVEL_NONE && | 400 if (security_level != SECURITY_LEVEL_NONE && |
327 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { | 401 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { |
328 NOTREACHED() << "Widevine security level " << security_level | 402 NOTREACHED() << "Widevine security level " << security_level |
329 << "used with another key system"; | 403 << "used with another key system"; |
330 return false; | 404 return false; |
331 } | 405 } |
332 | 406 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, | 539 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, |
466 const base::Closure& cdm_unset_cb) { | 540 const base::Closure& cdm_unset_cb) { |
467 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); | 541 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); |
468 } | 542 } |
469 | 543 |
470 void MediaDrmBridge::UnregisterPlayer(int registration_id) { | 544 void MediaDrmBridge::UnregisterPlayer(int registration_id) { |
471 player_tracker_.UnregisterPlayer(registration_id); | 545 player_tracker_.UnregisterPlayer(registration_id); |
472 } | 546 } |
473 | 547 |
474 void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) { | 548 void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) { |
| 549 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
| 550 |
475 if (closure.is_null()) { | 551 if (closure.is_null()) { |
476 media_crypto_ready_cb_.Reset(); | 552 media_crypto_ready_cb_.Reset(); |
477 return; | 553 return; |
478 } | 554 } |
479 | 555 |
480 DCHECK(media_crypto_ready_cb_.is_null()); | 556 DCHECK(media_crypto_ready_cb_.is_null()); |
481 | 557 |
482 if (!GetMediaCrypto().is_null()) { | 558 if (!GetMediaCrypto().is_null()) { |
483 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); | 559 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); |
484 return; | 560 return; |
485 } | 561 } |
486 | 562 |
487 media_crypto_ready_cb_ = closure; | 563 media_crypto_ready_cb_ = closure; |
488 } | 564 } |
489 | 565 |
490 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject) { | 566 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject j_media_drm) { |
| 567 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
| 568 |
491 DCHECK(!GetMediaCrypto().is_null()); | 569 DCHECK(!GetMediaCrypto().is_null()); |
492 if (!media_crypto_ready_cb_.is_null()) | 570 |
| 571 if (media_crypto_ready_cb_.is_null()) |
| 572 return; |
| 573 |
| 574 if (run_on_media_thread_ && !GetMediaTaskRunner()->BelongsToCurrentThread()) { |
| 575 GetMediaTaskRunner()->PostTask( |
| 576 FROM_HERE, base::ResetAndReturn(&media_crypto_ready_cb_)); |
| 577 } else { |
493 base::ResetAndReturn(&media_crypto_ready_cb_).Run(); | 578 base::ResetAndReturn(&media_crypto_ready_cb_).Run(); |
| 579 } |
| 580 // RUN_CB_ON_MEDIA_THREAD(base::ResetAndReturn(&media_crypto_ready_cb_)); |
494 } | 581 } |
495 | 582 |
496 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, | 583 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, |
497 jobject j_media_drm, | 584 jobject j_media_drm, |
498 jint j_promise_id) { | 585 jint j_promise_id) { |
| 586 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
499 cdm_promise_adapter_.ResolvePromise(j_promise_id); | 587 cdm_promise_adapter_.ResolvePromise(j_promise_id); |
| 588 // RUN_CB_ON_MEDIA_THREAD(internal_promise_resolved_cb_, j_promise_id); |
| 589 } |
| 590 |
| 591 void MediaDrmBridge::InternalPromiseResolved(uint32_t promise_id) { |
| 592 cdm_promise_adapter_.ResolvePromise(promise_id); |
500 } | 593 } |
501 | 594 |
502 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, | 595 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, |
503 jobject j_media_drm, | 596 jobject j_media_drm, |
504 jint j_promise_id, | 597 jint j_promise_id, |
505 jbyteArray j_session_id) { | 598 jbyteArray j_session_id) { |
506 cdm_promise_adapter_.ResolvePromise(j_promise_id, | 599 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
507 GetSessionId(env, j_session_id)); | 600 std::string session_id = GetSessionId(env, j_session_id); |
| 601 |
| 602 cdm_promise_adapter_.ResolvePromise(j_promise_id, session_id); |
| 603 // RUN_CB_ON_MEDIA_THREAD(internal_promise_resolved_with_session_cb_, |
| 604 // j_promise_id, session_id); |
| 605 } |
| 606 |
| 607 void MediaDrmBridge::InternalPromiseResolvedWithSession( |
| 608 uint32_t promise_id, |
| 609 const std::string& session_id) { |
| 610 cdm_promise_adapter_.ResolvePromise(promise_id, session_id); |
508 } | 611 } |
509 | 612 |
510 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, | 613 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, |
511 jobject j_media_drm, | 614 jobject j_media_drm, |
512 jint j_promise_id, | 615 jint j_promise_id, |
513 jstring j_error_message) { | 616 jstring j_error_message) { |
| 617 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
514 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message); | 618 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message); |
| 619 |
515 cdm_promise_adapter_.RejectPromise(j_promise_id, MediaKeys::UNKNOWN_ERROR, 0, | 620 cdm_promise_adapter_.RejectPromise(j_promise_id, MediaKeys::UNKNOWN_ERROR, 0, |
516 error_message); | 621 error_message); |
| 622 // RUN_CB_ON_MEDIA_THREAD(internal_promise_rejected_cb_, j_promise_id, |
| 623 // error_message); |
| 624 } |
| 625 |
| 626 void MediaDrmBridge::InternalPromiseRejected(uint32_t promise_id, |
| 627 const std::string& error_message) { |
| 628 cdm_promise_adapter_.RejectPromise(promise_id, MediaKeys::UNKNOWN_ERROR, 0, |
| 629 error_message); |
517 } | 630 } |
518 | 631 |
519 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, | 632 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, |
520 jobject j_media_drm, | 633 jobject j_media_drm, |
521 jbyteArray j_session_id, | 634 jbyteArray j_session_id, |
522 jint j_message_type, | 635 jint j_message_type, |
523 jbyteArray j_message, | 636 jbyteArray j_message, |
524 jstring j_legacy_destination_url) { | 637 jstring j_legacy_destination_url) { |
| 638 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
| 639 |
525 std::vector<uint8> message; | 640 std::vector<uint8> message; |
526 JavaByteArrayToByteVector(env, j_message, &message); | 641 JavaByteArrayToByteVector(env, j_message, &message); |
527 GURL legacy_destination_url = | 642 GURL legacy_destination_url = |
528 GURL(ConvertJavaStringToUTF8(env, j_legacy_destination_url)); | 643 GURL(ConvertJavaStringToUTF8(env, j_legacy_destination_url)); |
529 MediaKeys::MessageType message_type = | 644 MediaKeys::MessageType message_type = |
530 GetMessageType(static_cast<RequestType>(j_message_type)); | 645 GetMessageType(static_cast<RequestType>(j_message_type)); |
| 646 std::string session_id = GetSessionId(env, j_session_id); |
531 | 647 |
532 session_message_cb_.Run(GetSessionId(env, j_session_id), message_type, | 648 // RUN_CB_ON_MEDIA_THREAD(session_message_cb_, session_id, message_type, |
533 message, legacy_destination_url); | 649 // message, legacy_destination_url); |
| 650 |
| 651 session_message_cb_.Run(session_id, message_type, message, |
| 652 legacy_destination_url); |
534 } | 653 } |
535 | 654 |
536 void MediaDrmBridge::OnSessionClosed(JNIEnv* env, | 655 void MediaDrmBridge::OnSessionClosed(JNIEnv* env, |
537 jobject j_media_drm, | 656 jobject j_media_drm, |
538 jbyteArray j_session_id) { | 657 jbyteArray j_session_id) { |
| 658 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
| 659 |
| 660 std::string session_id = GetSessionId(env, j_session_id); |
| 661 |
| 662 // RUN_CB_ON_MEDIA_THREAD(session_closed_cb_, session_id); |
| 663 |
539 session_closed_cb_.Run(GetSessionId(env, j_session_id)); | 664 session_closed_cb_.Run(GetSessionId(env, j_session_id)); |
540 } | 665 } |
541 | 666 |
542 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, | 667 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, |
543 jobject j_media_drm, | 668 jobject j_media_drm, |
544 jbyteArray j_session_id, | 669 jbyteArray j_session_id, |
545 jobjectArray j_keys_info, | 670 jobjectArray j_keys_info, |
546 bool has_additional_usable_key) { | 671 bool has_additional_usable_key) { |
547 if (has_additional_usable_key) | 672 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
548 player_tracker_.NotifyNewKey(); | |
549 | 673 |
550 CdmKeysInfo cdm_keys_info; | 674 CdmKeysInfo cdm_keys_info; |
551 | 675 |
552 size_t size = env->GetArrayLength(j_keys_info); | 676 size_t size = env->GetArrayLength(j_keys_info); |
553 DCHECK_GT(size, 0u); | 677 DCHECK_GT(size, 0u); |
554 | 678 |
555 for (size_t i = 0; i < size; ++i) { | 679 for (size_t i = 0; i < size; ++i) { |
556 ScopedJavaLocalRef<jobject> j_key_status( | 680 ScopedJavaLocalRef<jobject> j_key_status( |
557 env, env->GetObjectArrayElement(j_keys_info, i)); | 681 env, env->GetObjectArrayElement(j_keys_info, i)); |
558 | 682 |
(...skipping 13 matching lines...) Expand all Loading... |
572 << key_status; | 696 << key_status; |
573 | 697 |
574 // TODO(xhwang): Update CdmKeyInformation to take key_id and status in the | 698 // TODO(xhwang): Update CdmKeyInformation to take key_id and status in the |
575 // constructor. | 699 // constructor. |
576 scoped_ptr<CdmKeyInformation> cdm_key_information(new CdmKeyInformation()); | 700 scoped_ptr<CdmKeyInformation> cdm_key_information(new CdmKeyInformation()); |
577 cdm_key_information->key_id = key_id; | 701 cdm_key_information->key_id = key_id; |
578 cdm_key_information->status = key_status; | 702 cdm_key_information->status = key_status; |
579 cdm_keys_info.push_back(cdm_key_information.release()); | 703 cdm_keys_info.push_back(cdm_key_information.release()); |
580 } | 704 } |
581 | 705 |
582 session_keys_change_cb_.Run(GetSessionId(env, j_session_id), | 706 std::string session_id = GetSessionId(env, j_session_id); |
583 has_additional_usable_key, cdm_keys_info.Pass()); | 707 |
| 708 /* |
| 709 if (run_on_media_thread_ && !GetMediaTaskRunner()->BelongsToCurrentThread()) { |
| 710 GetMediaTaskRunner()->PostTask( |
| 711 FROM_HERE, base::Bind(internal_session_keys_changed_cb_, |
| 712 session_id, |
| 713 has_additional_usable_key, |
| 714 base::Passed(&cdm_keys_info))); |
| 715 } else { |
| 716 internal_session_keys_changed_cb_.Run(session_id, |
| 717 has_additional_usable_key, |
| 718 cdm_keys_info.Pass()); |
| 719 } |
| 720 */ |
| 721 |
| 722 RUN_CB_ON_MEDIA_THREAD(internal_keys_added_cb_, has_additional_usable_key); |
| 723 |
| 724 session_keys_change_cb_.Run(session_id, has_additional_usable_key, |
| 725 cdm_keys_info.Pass()); |
| 726 } |
| 727 |
| 728 void MediaDrmBridge::InternalSessionKeysChanged(const std::string& session_id, |
| 729 bool has_additional_usable_key, |
| 730 CdmKeysInfo cdm_keys_info) { |
| 731 if (has_additional_usable_key) |
| 732 player_tracker_.NotifyNewKey(); |
| 733 |
| 734 session_keys_change_cb_.Run(session_id, has_additional_usable_key, |
| 735 cdm_keys_info.Pass()); |
| 736 } |
| 737 |
| 738 void MediaDrmBridge::InternalKeysAdded(bool has_additional_usable_key) { |
| 739 if (has_additional_usable_key) |
| 740 player_tracker_.NotifyNewKey(); |
584 } | 741 } |
585 | 742 |
586 // According to MeidaDrm documentation [1], zero |expiry_time_ms| means the keys | 743 // According to MeidaDrm documentation [1], zero |expiry_time_ms| means the keys |
587 // will never expire. This will be translated into a NULL base::Time() [2], | 744 // will never expire. This will be translated into a NULL base::Time() [2], |
588 // which will then be mapped to a zero Java time [3]. The zero Java time is | 745 // which will then be mapped to a zero Java time [3]. The zero Java time is |
589 // passed to Blink which will then be translated to NaN [4], which is what the | 746 // passed to Blink which will then be translated to NaN [4], which is what the |
590 // spec uses to indicate that the license will never expire [5]. | 747 // spec uses to indicate that the license will never expire [5]. |
591 // [1] http://developer.android.com/reference/android/media/MediaDrm.OnExpiratio
nUpdateListener.html | 748 // [1] http://developer.android.com/reference/android/media/MediaDrm.OnExpiratio
nUpdateListener.html |
592 // [2] See base::Time::FromDoubleT() | 749 // [2] See base::Time::FromDoubleT() |
593 // [3] See base::Time::ToJavaTime() | 750 // [3] See base::Time::ToJavaTime() |
594 // [4] See MediaKeySession::expirationChanged() | 751 // [4] See MediaKeySession::expirationChanged() |
595 // [5] https://github.com/w3c/encrypted-media/issues/58 | 752 // [5] https://github.com/w3c/encrypted-media/issues/58 |
596 void MediaDrmBridge::OnSessionExpirationUpdate(JNIEnv* env, | 753 void MediaDrmBridge::OnSessionExpirationUpdate(JNIEnv* env, |
597 jobject j_media_drm, | 754 jobject j_media_drm, |
598 jbyteArray j_session_id, | 755 jbyteArray j_session_id, |
599 jlong expiry_time_ms) { | 756 jlong expiry_time_ms) { |
| 757 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
600 DVLOG(2) << __FUNCTION__ << ": " << expiry_time_ms << " ms"; | 758 DVLOG(2) << __FUNCTION__ << ": " << expiry_time_ms << " ms"; |
601 session_expiration_update_cb_.Run( | 759 std::string session_id = GetSessionId(env, j_session_id); |
602 GetSessionId(env, j_session_id), | 760 base::Time expiration_time = base::Time::FromDoubleT(expiry_time_ms / 1000.0); |
603 base::Time::FromDoubleT(expiry_time_ms / 1000.0)); | 761 |
| 762 // RUN_CB_ON_MEDIA_THREAD(session_expiration_update_cb_, session_id, |
| 763 // expiration_time); |
| 764 |
| 765 session_expiration_update_cb_.Run(session_id, expiration_time); |
604 } | 766 } |
605 | 767 |
606 void MediaDrmBridge::OnLegacySessionError(JNIEnv* env, | 768 void MediaDrmBridge::OnLegacySessionError(JNIEnv* env, |
607 jobject j_media_drm, | 769 jobject j_media_drm, |
608 jbyteArray j_session_id, | 770 jbyteArray j_session_id, |
609 jstring j_error_message) { | 771 jstring j_error_message) { |
| 772 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
| 773 std::string session_id = GetSessionId(env, j_session_id); |
610 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message); | 774 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message); |
611 legacy_session_error_cb_.Run(GetSessionId(env, j_session_id), | 775 |
612 MediaKeys::UNKNOWN_ERROR, 0, error_message); | 776 // RUN_CB_ON_MEDIA_THREAD(legacy_session_error_cb_, session_id, |
| 777 // MediaKeys::UNKNOWN_ERROR, 0, error_message); |
| 778 |
| 779 legacy_session_error_cb_.Run(session_id, MediaKeys::UNKNOWN_ERROR, 0, |
| 780 error_message); |
613 } | 781 } |
614 | 782 |
615 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { | 783 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { |
616 JNIEnv* env = AttachCurrentThread(); | 784 JNIEnv* env = AttachCurrentThread(); |
617 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); | 785 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); |
618 } | 786 } |
619 | 787 |
620 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { | 788 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { |
621 JNIEnv* env = AttachCurrentThread(); | 789 JNIEnv* env = AttachCurrentThread(); |
622 ScopedJavaLocalRef<jstring> j_security_level = | 790 ScopedJavaLocalRef<jstring> j_security_level = |
(...skipping 15 matching lines...) Expand all Loading... |
638 void MediaDrmBridge::ResetDeviceCredentials( | 806 void MediaDrmBridge::ResetDeviceCredentials( |
639 const ResetCredentialsCB& callback) { | 807 const ResetCredentialsCB& callback) { |
640 DCHECK(reset_credentials_cb_.is_null()); | 808 DCHECK(reset_credentials_cb_.is_null()); |
641 reset_credentials_cb_ = callback; | 809 reset_credentials_cb_ = callback; |
642 JNIEnv* env = AttachCurrentThread(); | 810 JNIEnv* env = AttachCurrentThread(); |
643 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 811 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
644 } | 812 } |
645 | 813 |
646 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 814 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
647 JNIEnv* env, jobject, bool success) { | 815 JNIEnv* env, jobject, bool success) { |
| 816 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__; |
| 817 |
| 818 // RUN_CB_ON_MEDIA_THREAD(base::ResetAndReturn(&reset_credentials_cb_), |
| 819 // success); |
| 820 |
648 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 821 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
649 } | 822 } |
650 | 823 |
651 } // namespace media | 824 } // namespace media |
OLD | NEW |