Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: media/base/android/media_drm_bridge.cc

Issue 1341883003: Prepare MediaDrmBridge to work with MediaCodecPlayer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bug526755
Patch Set: Addressed Min's comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 weak_factory_(this) {
315 DVLOG(1) << "MediaDrmBridge::MediaDrmBridge";
316
317 // When this flag is set we need to repost the notifications about
318 // crypto became ready and a key had been added to the Media thread.
319 run_on_media_thread_ = GetMediaTaskRunner()->BelongsToCurrentThread();
320
321 // Create internal callbacks to repost Java new key notification and
322 // promise related notifications to the media thread.
323
324 base::WeakPtr<MediaDrmBridge> weak_this = weak_factory_.GetWeakPtr();
325
326 internal_keys_added_cb_ =
327 base::Bind(&MediaDrmBridge::InternalKeysAdded, weak_this);
328 internal_promise_resolved_cb_ =
329 base::Bind(&MediaDrmBridge::InternalPromiseResolved, weak_this);
330 internal_promise_resolved_with_session_cb_ = base::Bind(
331 &MediaDrmBridge::InternalPromiseResolvedWithSession, weak_this);
332 internal_promise_rejected_cb_ =
333 base::Bind(&MediaDrmBridge::InternalPromiseRejected, weak_this);
334
274 JNIEnv* env = AttachCurrentThread(); 335 JNIEnv* env = AttachCurrentThread();
275 CHECK(env); 336 CHECK(env);
276 337
277 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = 338 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid =
278 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); 339 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size());
279 j_media_drm_.Reset(Java_MediaDrmBridge_create( 340 j_media_drm_.Reset(Java_MediaDrmBridge_create(
280 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); 341 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this)));
281 } 342 }
282 343
283 MediaDrmBridge::~MediaDrmBridge() { 344 MediaDrmBridge::~MediaDrmBridge() {
284 JNIEnv* env = AttachCurrentThread(); 345 JNIEnv* env = AttachCurrentThread();
285 player_tracker_.NotifyCdmUnset(); 346 player_tracker_.NotifyCdmUnset();
286 if (!j_media_drm_.is_null()) 347 if (!j_media_drm_.is_null())
287 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); 348 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj());
288 } 349 }
289 350
290 // static 351 // static
291 scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( 352 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> MediaDrmBridge::Create(
292 const std::string& key_system, 353 const std::string& key_system,
354 SecurityLevel widevine_security_level,
293 const SessionMessageCB& session_message_cb, 355 const SessionMessageCB& session_message_cb,
294 const SessionClosedCB& session_closed_cb, 356 const SessionClosedCB& session_closed_cb,
295 const LegacySessionErrorCB& legacy_session_error_cb, 357 const LegacySessionErrorCB& legacy_session_error_cb,
296 const SessionKeysChangeCB& session_keys_change_cb, 358 const SessionKeysChangeCB& session_keys_change_cb,
297 const SessionExpirationUpdateCB& session_expiration_update_cb) { 359 const SessionExpirationUpdateCB& session_expiration_update_cb) {
298 scoped_ptr<MediaDrmBridge> media_drm_bridge; 360 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> media_drm_bridge;
299 if (!IsAvailable()) 361 if (!IsAvailable())
300 return media_drm_bridge.Pass(); 362 return media_drm_bridge.Pass();
301 363
302 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); 364 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system);
303 if (scheme_uuid.empty()) 365 if (scheme_uuid.empty())
304 return media_drm_bridge.Pass(); 366 return media_drm_bridge.Pass();
305 367
306 media_drm_bridge.reset( 368 media_drm_bridge.reset(
307 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, 369 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb,
308 legacy_session_error_cb, session_keys_change_cb, 370 legacy_session_error_cb, session_keys_change_cb,
309 session_expiration_update_cb)); 371 session_expiration_update_cb));
310 372
311 if (media_drm_bridge->j_media_drm_.is_null()) 373 if (media_drm_bridge->j_media_drm_.is_null())
312 media_drm_bridge.reset(); 374 media_drm_bridge.reset();
313 375
376 if (key_system == kWidevineKeySystem &&
ddorwin 2015/09/16 20:42:21 We shouldn't need the WV check here again.
377 widevine_security_level != SECURITY_LEVEL_NONE &&
378 !media_drm_bridge->SetSecurityLevel(widevine_security_level)) {
379 DVLOG(1) << __FUNCTION__ << ": failed to set security level "
380 << widevine_security_level;
381 media_drm_bridge.reset();
382 }
383
314 return media_drm_bridge.Pass(); 384 return media_drm_bridge.Pass();
315 } 385 }
316 386
317 // static 387 // static
318 scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( 388 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter>
319 const std::string& key_system) { 389 MediaDrmBridge::CreateWithoutSessionSupport(const std::string& key_system) {
320 return MediaDrmBridge::Create( 390 return MediaDrmBridge::Create(key_system, SECURITY_LEVEL_NONE,
321 key_system, SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(), 391 SessionMessageCB(), SessionClosedCB(),
322 SessionKeysChangeCB(), SessionExpirationUpdateCB()); 392 LegacySessionErrorCB(), SessionKeysChangeCB(),
393 SessionExpirationUpdateCB());
323 } 394 }
324 395
325 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { 396 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) {
326 if (security_level != SECURITY_LEVEL_NONE && 397 if (security_level != SECURITY_LEVEL_NONE &&
327 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { 398 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) {
328 NOTREACHED() << "Widevine security level " << security_level 399 NOTREACHED() << "Widevine security level " << security_level
329 << "used with another key system"; 400 << "used with another key system";
330 return false; 401 return false;
331 } 402 }
332 403
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 const std::string& session_id, 489 const std::string& session_id,
419 scoped_ptr<media::NewSessionCdmPromise> promise) { 490 scoped_ptr<media::NewSessionCdmPromise> promise) {
420 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; 491 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android.";
421 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); 492 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported.");
422 } 493 }
423 494
424 void MediaDrmBridge::UpdateSession( 495 void MediaDrmBridge::UpdateSession(
425 const std::string& session_id, 496 const std::string& session_id,
426 const std::vector<uint8_t>& response, 497 const std::vector<uint8_t>& response,
427 scoped_ptr<media::SimpleCdmPromise> promise) { 498 scoped_ptr<media::SimpleCdmPromise> promise) {
428 DVLOG(1) << __FUNCTION__; 499 DVLOG(1) << __FUNCTION__ << " session_id:" << session_id;
429 500
430 JNIEnv* env = AttachCurrentThread(); 501 JNIEnv* env = AttachCurrentThread();
431 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( 502 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray(
432 env, vector_as_array(&response), response.size()); 503 env, vector_as_array(&response), response.size());
433 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( 504 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray(
434 env, reinterpret_cast<const uint8_t*>(session_id.data()), 505 env, reinterpret_cast<const uint8_t*>(session_id.data()),
435 session_id.size()); 506 session_id.size());
436 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); 507 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
437 Java_MediaDrmBridge_updateSession(env, j_media_drm_.obj(), j_session_id.obj(), 508 Java_MediaDrmBridge_updateSession(env, j_media_drm_.obj(), j_session_id.obj(),
438 j_response.obj(), promise_id); 509 j_response.obj(), promise_id);
439 } 510 }
440 511
441 void MediaDrmBridge::CloseSession(const std::string& session_id, 512 void MediaDrmBridge::CloseSession(const std::string& session_id,
442 scoped_ptr<media::SimpleCdmPromise> promise) { 513 scoped_ptr<media::SimpleCdmPromise> promise) {
443 DVLOG(1) << __FUNCTION__; 514 DVLOG(1) << __FUNCTION__;
515
444 JNIEnv* env = AttachCurrentThread(); 516 JNIEnv* env = AttachCurrentThread();
445 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( 517 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray(
446 env, reinterpret_cast<const uint8_t*>(session_id.data()), 518 env, reinterpret_cast<const uint8_t*>(session_id.data()),
447 session_id.size()); 519 session_id.size());
448 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); 520 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
449 Java_MediaDrmBridge_closeSession(env, j_media_drm_.obj(), j_session_id.obj(), 521 Java_MediaDrmBridge_closeSession(env, j_media_drm_.obj(), j_session_id.obj(),
450 promise_id); 522 promise_id);
451 } 523 }
452 524
453 void MediaDrmBridge::RemoveSession( 525 void MediaDrmBridge::RemoveSession(
(...skipping 11 matching lines...) Expand all
465 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, 537 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb,
466 const base::Closure& cdm_unset_cb) { 538 const base::Closure& cdm_unset_cb) {
467 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); 539 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb);
468 } 540 }
469 541
470 void MediaDrmBridge::UnregisterPlayer(int registration_id) { 542 void MediaDrmBridge::UnregisterPlayer(int registration_id) {
471 player_tracker_.UnregisterPlayer(registration_id); 543 player_tracker_.UnregisterPlayer(registration_id);
472 } 544 }
473 545
474 void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) { 546 void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) {
547 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__;
548
475 if (closure.is_null()) { 549 if (closure.is_null()) {
476 media_crypto_ready_cb_.Reset(); 550 media_crypto_ready_cb_.Reset();
477 return; 551 return;
478 } 552 }
479 553
480 DCHECK(media_crypto_ready_cb_.is_null()); 554 DCHECK(media_crypto_ready_cb_.is_null());
481 555
482 if (!GetMediaCrypto().is_null()) { 556 if (!GetMediaCrypto().is_null()) {
483 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); 557 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
484 return; 558 return;
485 } 559 }
486 560
487 media_crypto_ready_cb_ = closure; 561 media_crypto_ready_cb_ = closure;
488 } 562 }
489 563
490 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject) { 564 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject j_media_drm) {
565 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__;
566
491 DCHECK(!GetMediaCrypto().is_null()); 567 DCHECK(!GetMediaCrypto().is_null());
492 if (!media_crypto_ready_cb_.is_null()) 568
493 base::ResetAndReturn(&media_crypto_ready_cb_).Run(); 569 if (media_crypto_ready_cb_.is_null())
570 return;
571
572 RUN_CB_ON_MEDIA_THREAD(base::ResetAndReturn(&media_crypto_ready_cb_));
494 } 573 }
495 574
496 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, 575 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env,
497 jobject j_media_drm, 576 jobject j_media_drm,
498 jint j_promise_id) { 577 jint j_promise_id) {
499 cdm_promise_adapter_.ResolvePromise(j_promise_id); 578 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__;
579 RUN_CB_ON_MEDIA_THREAD(internal_promise_resolved_cb_, j_promise_id);
580 }
581
582 void MediaDrmBridge::InternalPromiseResolved(uint32_t promise_id) {
583 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__
584 << ": promise_id:" << promise_id;
585 cdm_promise_adapter_.ResolvePromise(promise_id);
500 } 586 }
501 587
502 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, 588 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env,
503 jobject j_media_drm, 589 jobject j_media_drm,
504 jint j_promise_id, 590 jint j_promise_id,
505 jbyteArray j_session_id) { 591 jbyteArray j_session_id) {
506 cdm_promise_adapter_.ResolvePromise(j_promise_id, 592 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__;
507 GetSessionId(env, j_session_id)); 593 RUN_CB_ON_MEDIA_THREAD(internal_promise_resolved_with_session_cb_,
594 j_promise_id, GetSessionId(env, j_session_id));
595 }
596
597 void MediaDrmBridge::InternalPromiseResolvedWithSession(
598 uint32_t promise_id,
599 const std::string& session_id) {
600 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__
601 << ": promise_id:" << promise_id << " session_id:" << session_id;
602 cdm_promise_adapter_.ResolvePromise(promise_id, session_id);
508 } 603 }
509 604
510 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, 605 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env,
511 jobject j_media_drm, 606 jobject j_media_drm,
512 jint j_promise_id, 607 jint j_promise_id,
513 jstring j_error_message) { 608 jstring j_error_message) {
609 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__;
514 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message); 610 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message);
515 cdm_promise_adapter_.RejectPromise(j_promise_id, MediaKeys::UNKNOWN_ERROR, 0, 611 RUN_CB_ON_MEDIA_THREAD(internal_promise_rejected_cb_, j_promise_id,
612 error_message);
613 }
614
615 void MediaDrmBridge::InternalPromiseRejected(uint32_t promise_id,
616 const std::string& error_message) {
617 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__
618 << ": promise_id:" << promise_id << " error:" << error_message;
619 cdm_promise_adapter_.RejectPromise(promise_id, MediaKeys::UNKNOWN_ERROR, 0,
516 error_message); 620 error_message);
517 } 621 }
518 622
519 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, 623 void MediaDrmBridge::OnSessionMessage(JNIEnv* env,
520 jobject j_media_drm, 624 jobject j_media_drm,
521 jbyteArray j_session_id, 625 jbyteArray j_session_id,
522 jint j_message_type, 626 jint j_message_type,
523 jbyteArray j_message, 627 jbyteArray j_message,
524 jstring j_legacy_destination_url) { 628 jstring j_legacy_destination_url) {
525 std::vector<uint8> message; 629 std::vector<uint8> message;
526 JavaByteArrayToByteVector(env, j_message, &message); 630 JavaByteArrayToByteVector(env, j_message, &message);
527 GURL legacy_destination_url = 631 GURL legacy_destination_url =
528 GURL(ConvertJavaStringToUTF8(env, j_legacy_destination_url)); 632 GURL(ConvertJavaStringToUTF8(env, j_legacy_destination_url));
529 MediaKeys::MessageType message_type = 633 MediaKeys::MessageType message_type =
530 GetMessageType(static_cast<RequestType>(j_message_type)); 634 GetMessageType(static_cast<RequestType>(j_message_type));
531 635
532 session_message_cb_.Run(GetSessionId(env, j_session_id), message_type, 636 std::string session_id = GetSessionId(env, j_session_id);
533 message, legacy_destination_url); 637
638 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__
639 << " session_id:" << session_id;
640
641 // We need to preserve the order of messages. If the promise-related
642 // callbacks are posted to the Media thread, we have to do the same with
643 // all callbacks. See the comment in media_drm_proxy.h.
644 RUN_CB_ON_MEDIA_THREAD(session_message_cb_, session_id, message_type, message,
645 legacy_destination_url);
534 } 646 }
535 647
536 void MediaDrmBridge::OnSessionClosed(JNIEnv* env, 648 void MediaDrmBridge::OnSessionClosed(JNIEnv* env,
537 jobject j_media_drm, 649 jobject j_media_drm,
538 jbyteArray j_session_id) { 650 jbyteArray j_session_id) {
539 session_closed_cb_.Run(GetSessionId(env, j_session_id)); 651 std::string session_id = GetSessionId(env, j_session_id);
652 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__
653 << " session_id:" << session_id;
654
655 RUN_CB_ON_MEDIA_THREAD(session_closed_cb_, session_id);
ddorwin 2015/09/16 20:42:21 Should it be up to the caller to ensure this? At w
540 } 656 }
541 657
542 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, 658 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env,
543 jobject j_media_drm, 659 jobject j_media_drm,
544 jbyteArray j_session_id, 660 jbyteArray j_session_id,
545 jobjectArray j_keys_info, 661 jobjectArray j_keys_info,
546 bool has_additional_usable_key) { 662 bool has_additional_usable_key) {
547 if (has_additional_usable_key) 663 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__;
548 player_tracker_.NotifyNewKey();
549 664
550 CdmKeysInfo cdm_keys_info; 665 CdmKeysInfo cdm_keys_info;
551 666
552 size_t size = env->GetArrayLength(j_keys_info); 667 size_t size = env->GetArrayLength(j_keys_info);
553 DCHECK_GT(size, 0u); 668 DCHECK_GT(size, 0u);
554 669
555 for (size_t i = 0; i < size; ++i) { 670 for (size_t i = 0; i < size; ++i) {
556 ScopedJavaLocalRef<jobject> j_key_status( 671 ScopedJavaLocalRef<jobject> j_key_status(
557 env, env->GetObjectArrayElement(j_keys_info, i)); 672 env, env->GetObjectArrayElement(j_keys_info, i));
558 673
(...skipping 13 matching lines...) Expand all
572 << key_status; 687 << key_status;
573 688
574 // TODO(xhwang): Update CdmKeyInformation to take key_id and status in the 689 // TODO(xhwang): Update CdmKeyInformation to take key_id and status in the
575 // constructor. 690 // constructor.
576 scoped_ptr<CdmKeyInformation> cdm_key_information(new CdmKeyInformation()); 691 scoped_ptr<CdmKeyInformation> cdm_key_information(new CdmKeyInformation());
577 cdm_key_information->key_id = key_id; 692 cdm_key_information->key_id = key_id;
578 cdm_key_information->status = key_status; 693 cdm_key_information->status = key_status;
579 cdm_keys_info.push_back(cdm_key_information.release()); 694 cdm_keys_info.push_back(cdm_key_information.release());
580 } 695 }
581 696
582 session_keys_change_cb_.Run(GetSessionId(env, j_session_id), 697 RUN_CB_ON_MEDIA_THREAD(internal_keys_added_cb_, has_additional_usable_key);
583 has_additional_usable_key, cdm_keys_info.Pass()); 698
699 std::string session_id = GetSessionId(env, j_session_id);
700
701 if (run_on_media_thread_ && !GetMediaTaskRunner()->BelongsToCurrentThread()) {
702 GetMediaTaskRunner()->PostTask(
703 FROM_HERE,
704 base::Bind(session_keys_change_cb_, session_id,
705 has_additional_usable_key, base::Passed(&cdm_keys_info)));
706 } else {
707 session_keys_change_cb_.Run(session_id, has_additional_usable_key,
708 cdm_keys_info.Pass());
709 }
710 }
711
712 void MediaDrmBridge::InternalKeysAdded(bool has_additional_usable_key) {
713 if (has_additional_usable_key)
714 player_tracker_.NotifyNewKey();
584 } 715 }
585 716
586 // According to MeidaDrm documentation [1], zero |expiry_time_ms| means the keys 717 // 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], 718 // 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 719 // 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 720 // 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]. 721 // spec uses to indicate that the license will never expire [5].
591 // [1] http://developer.android.com/reference/android/media/MediaDrm.OnExpiratio nUpdateListener.html 722 // [1] http://developer.android.com/reference/android/media/MediaDrm.OnExpiratio nUpdateListener.html
592 // [2] See base::Time::FromDoubleT() 723 // [2] See base::Time::FromDoubleT()
593 // [3] See base::Time::ToJavaTime() 724 // [3] See base::Time::ToJavaTime()
594 // [4] See MediaKeySession::expirationChanged() 725 // [4] See MediaKeySession::expirationChanged()
595 // [5] https://github.com/w3c/encrypted-media/issues/58 726 // [5] https://github.com/w3c/encrypted-media/issues/58
596 void MediaDrmBridge::OnSessionExpirationUpdate(JNIEnv* env, 727 void MediaDrmBridge::OnSessionExpirationUpdate(JNIEnv* env,
597 jobject j_media_drm, 728 jobject j_media_drm,
598 jbyteArray j_session_id, 729 jbyteArray j_session_id,
599 jlong expiry_time_ms) { 730 jlong expiry_time_ms) {
600 DVLOG(2) << __FUNCTION__ << ": " << expiry_time_ms << " ms"; 731 std::string session_id = GetSessionId(env, j_session_id);
601 session_expiration_update_cb_.Run( 732 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__
602 GetSessionId(env, j_session_id), 733 << ": session_id:" << session_id << " expiration:" << expiry_time_ms
603 base::Time::FromDoubleT(expiry_time_ms / 1000.0)); 734 << " ms";
735
736 RUN_CB_ON_MEDIA_THREAD(session_expiration_update_cb_, session_id,
737 base::Time::FromDoubleT(expiry_time_ms / 1000.0));
604 } 738 }
605 739
606 void MediaDrmBridge::OnLegacySessionError(JNIEnv* env, 740 void MediaDrmBridge::OnLegacySessionError(JNIEnv* env,
607 jobject j_media_drm, 741 jobject j_media_drm,
608 jbyteArray j_session_id, 742 jbyteArray j_session_id,
609 jstring j_error_message) { 743 jstring j_error_message) {
744 std::string session_id = GetSessionId(env, j_session_id);
610 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message); 745 std::string error_message = ConvertJavaStringToUTF8(env, j_error_message);
611 legacy_session_error_cb_.Run(GetSessionId(env, j_session_id), 746
612 MediaKeys::UNKNOWN_ERROR, 0, error_message); 747 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__ << " session_id:" << session_id
748 << " error:" << error_message;
749
750 RUN_CB_ON_MEDIA_THREAD(legacy_session_error_cb_, session_id,
751 MediaKeys::UNKNOWN_ERROR, 0, error_message);
613 } 752 }
614 753
615 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { 754 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() {
616 JNIEnv* env = AttachCurrentThread(); 755 JNIEnv* env = AttachCurrentThread();
617 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); 756 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj());
618 } 757 }
619 758
620 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { 759 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() {
621 JNIEnv* env = AttachCurrentThread(); 760 JNIEnv* env = AttachCurrentThread();
622 ScopedJavaLocalRef<jstring> j_security_level = 761 ScopedJavaLocalRef<jstring> j_security_level =
(...skipping 15 matching lines...) Expand all
638 void MediaDrmBridge::ResetDeviceCredentials( 777 void MediaDrmBridge::ResetDeviceCredentials(
639 const ResetCredentialsCB& callback) { 778 const ResetCredentialsCB& callback) {
640 DCHECK(reset_credentials_cb_.is_null()); 779 DCHECK(reset_credentials_cb_.is_null());
641 reset_credentials_cb_ = callback; 780 reset_credentials_cb_ = callback;
642 JNIEnv* env = AttachCurrentThread(); 781 JNIEnv* env = AttachCurrentThread();
643 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); 782 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj());
644 } 783 }
645 784
646 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( 785 void MediaDrmBridge::OnResetDeviceCredentialsCompleted(
647 JNIEnv* env, jobject, bool success) { 786 JNIEnv* env, jobject, bool success) {
648 base::ResetAndReturn(&reset_credentials_cb_).Run(success); 787 DVLOG(1) << "MediaDrmBridge::" << __FUNCTION__ << ": success:" << success;
788
789 RUN_CB_ON_MEDIA_THREAD(base::ResetAndReturn(&reset_credentials_cb_), success);
649 } 790 }
650 791
651 } // namespace media 792 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698