OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/media/cdm/browser_cdm_manager.h" | 5 #include "content/browser/media/cdm/browser_cdm_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 scoped_ptr<NewSessionPromise> promise( | 338 scoped_ptr<NewSessionPromise> promise( |
339 new NewSessionPromise(this, render_frame_id, cdm_id, promise_id)); | 339 new NewSessionPromise(this, render_frame_id, cdm_id, promise_id)); |
340 | 340 |
341 if (init_data.size() > kMaxInitDataLength) { | 341 if (init_data.size() > kMaxInitDataLength) { |
342 LOG(WARNING) << "InitData for ID: " << cdm_id | 342 LOG(WARNING) << "InitData for ID: " << cdm_id |
343 << " too long: " << init_data.size(); | 343 << " too long: " << init_data.size(); |
344 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Init data too long."); | 344 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Init data too long."); |
345 return; | 345 return; |
346 } | 346 } |
347 | 347 |
348 // Convert the session content type into a MIME type. "audio" and "video" | 348 media::EmeInitDataType eme_init_data_type = media::EME_INIT_DATA_TYPE_NONE; |
349 // don't matter, so using "video" for the MIME type. | |
350 // Ref: | |
351 // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypte
d-media.html#dom-createsession | |
352 std::string mime_type; | |
353 switch (init_data_type) { | 349 switch (init_data_type) { |
354 case CREATE_SESSION_TYPE_WEBM: | 350 case INIT_DATA_TYPE_WEBM: |
355 mime_type = "video/webm"; | 351 eme_init_data_type = media::EME_INIT_DATA_TYPE_WEBM; |
356 break; | 352 break; |
357 case CREATE_SESSION_TYPE_MP4: | 353 #if defined(USE_PROPRIETARY_CODECS) |
358 mime_type = "video/mp4"; | 354 case INIT_DATA_TYPE_CENC: |
| 355 eme_init_data_type = media::EME_INIT_DATA_TYPE_CENC; |
359 break; | 356 break; |
| 357 #endif |
360 default: | 358 default: |
361 NOTREACHED(); | 359 NOTREACHED(); |
362 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, | 360 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, |
363 "Invalid init data type."); | 361 "Invalid init data type."); |
364 return; | 362 return; |
365 } | 363 } |
366 | 364 |
367 #if defined(OS_ANDROID) | 365 #if defined(OS_ANDROID) |
368 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 366 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
369 switches::kDisableInfobarForProtectedMediaIdentifier)) { | 367 switches::kDisableInfobarForProtectedMediaIdentifier)) { |
370 GenerateRequestIfPermitted(render_frame_id, cdm_id, mime_type, init_data, | 368 GenerateRequestIfPermitted(render_frame_id, cdm_id, eme_init_data_type, |
371 promise.Pass(), true); | 369 init_data, promise.Pass(), true); |
372 return; | 370 return; |
373 } | 371 } |
374 #endif | 372 #endif |
375 | 373 |
376 BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id); | 374 BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id); |
377 if (!cdm) { | 375 if (!cdm) { |
378 DLOG(WARNING) << "No CDM found for: " << render_frame_id << ", " << cdm_id; | 376 DLOG(WARNING) << "No CDM found for: " << render_frame_id << ", " << cdm_id; |
379 promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found."); | 377 promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found."); |
380 return; | 378 return; |
381 } | 379 } |
382 | 380 |
383 std::map<uint64, GURL>::const_iterator iter = | 381 std::map<uint64, GURL>::const_iterator iter = |
384 cdm_security_origin_map_.find(GetId(render_frame_id, cdm_id)); | 382 cdm_security_origin_map_.find(GetId(render_frame_id, cdm_id)); |
385 if (iter == cdm_security_origin_map_.end()) { | 383 if (iter == cdm_security_origin_map_.end()) { |
386 NOTREACHED(); | 384 NOTREACHED(); |
387 promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found."); | 385 promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found."); |
388 return; | 386 return; |
389 } | 387 } |
390 GURL security_origin = iter->second; | 388 GURL security_origin = iter->second; |
391 | 389 |
392 RequestSessionPermission(render_frame_id, security_origin, cdm_id, mime_type, | 390 RequestSessionPermission(render_frame_id, security_origin, cdm_id, |
393 init_data, promise.Pass()); | 391 eme_init_data_type, init_data, promise.Pass()); |
394 } | 392 } |
395 | 393 |
396 void BrowserCdmManager::OnUpdateSession(int render_frame_id, | 394 void BrowserCdmManager::OnUpdateSession(int render_frame_id, |
397 int cdm_id, | 395 int cdm_id, |
398 uint32_t promise_id, | 396 uint32_t promise_id, |
399 const std::string& session_id, | 397 const std::string& session_id, |
400 const std::vector<uint8>& response) { | 398 const std::vector<uint8>& response) { |
401 scoped_ptr<SimplePromise> promise( | 399 scoped_ptr<SimplePromise> promise( |
402 new SimplePromise(this, render_frame_id, cdm_id, promise_id)); | 400 new SimplePromise(this, render_frame_id, cdm_id, promise_id)); |
403 | 401 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 if (cdm_cancel_permission_map_.count(id)) { | 492 if (cdm_cancel_permission_map_.count(id)) { |
495 cdm_cancel_permission_map_[id].Run(); | 493 cdm_cancel_permission_map_[id].Run(); |
496 cdm_cancel_permission_map_.erase(id); | 494 cdm_cancel_permission_map_.erase(id); |
497 } | 495 } |
498 } | 496 } |
499 | 497 |
500 void BrowserCdmManager::RequestSessionPermission( | 498 void BrowserCdmManager::RequestSessionPermission( |
501 int render_frame_id, | 499 int render_frame_id, |
502 const GURL& security_origin, | 500 const GURL& security_origin, |
503 int cdm_id, | 501 int cdm_id, |
504 const std::string& init_data_type, | 502 media::EmeInitDataType init_data_type, |
505 const std::vector<uint8>& init_data, | 503 const std::vector<uint8>& init_data, |
506 scoped_ptr<media::NewSessionCdmPromise> promise) { | 504 scoped_ptr<media::NewSessionCdmPromise> promise) { |
507 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 505 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
508 BrowserThread::PostTask( | 506 BrowserThread::PostTask( |
509 BrowserThread::UI, FROM_HERE, | 507 BrowserThread::UI, FROM_HERE, |
510 base::Bind(&BrowserCdmManager::RequestSessionPermission, this, | 508 base::Bind(&BrowserCdmManager::RequestSessionPermission, this, |
511 render_frame_id, security_origin, cdm_id, init_data_type, | 509 render_frame_id, security_origin, cdm_id, init_data_type, |
512 init_data, base::Passed(&promise))); | 510 init_data, base::Passed(&promise))); |
513 return; | 511 return; |
514 } | 512 } |
515 | 513 |
516 RenderFrameHost* rfh = | 514 RenderFrameHost* rfh = |
517 RenderFrameHost::FromID(render_process_id_, render_frame_id); | 515 RenderFrameHost::FromID(render_process_id_, render_frame_id); |
518 WebContents* web_contents = WebContents::FromRenderFrameHost(rfh); | 516 WebContents* web_contents = WebContents::FromRenderFrameHost(rfh); |
519 DCHECK(web_contents); | 517 DCHECK(web_contents); |
520 GetContentClient()->browser()->RequestPermission( | 518 GetContentClient()->browser()->RequestPermission( |
521 content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER, web_contents, | 519 content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER, web_contents, |
522 0, // bridge id | 520 0, // bridge id |
523 security_origin, | 521 security_origin, |
524 // Only implemented for Android infobars which do not support | 522 // Only implemented for Android infobars which do not support |
525 // user gestures. | 523 // user gestures. |
526 true, base::Bind(&BrowserCdmManager::GenerateRequestIfPermitted, this, | 524 true, base::Bind(&BrowserCdmManager::GenerateRequestIfPermitted, this, |
527 render_frame_id, cdm_id, init_data_type, init_data, | 525 render_frame_id, cdm_id, init_data_type, init_data, |
528 base::Passed(&promise))); | 526 base::Passed(&promise))); |
529 } | 527 } |
530 | 528 |
531 void BrowserCdmManager::GenerateRequestIfPermitted( | 529 void BrowserCdmManager::GenerateRequestIfPermitted( |
532 int render_frame_id, | 530 int render_frame_id, |
533 int cdm_id, | 531 int cdm_id, |
534 const std::string& init_data_type, | 532 media::EmeInitDataType init_data_type, |
535 const std::vector<uint8>& init_data, | 533 const std::vector<uint8>& init_data, |
536 scoped_ptr<media::NewSessionCdmPromise> promise, | 534 scoped_ptr<media::NewSessionCdmPromise> promise, |
537 bool permitted) { | 535 bool permitted) { |
538 cdm_cancel_permission_map_.erase(GetId(render_frame_id, cdm_id)); | 536 cdm_cancel_permission_map_.erase(GetId(render_frame_id, cdm_id)); |
539 if (!permitted) { | 537 if (!permitted) { |
540 promise->reject(MediaKeys::NOT_SUPPORTED_ERROR, 0, "Permission denied."); | 538 promise->reject(MediaKeys::NOT_SUPPORTED_ERROR, 0, "Permission denied."); |
541 return; | 539 return; |
542 } | 540 } |
543 | 541 |
544 BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id); | 542 BrowserCdm* cdm = GetCdm(render_frame_id, cdm_id); |
545 if (!cdm) { | 543 if (!cdm) { |
546 promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found."); | 544 promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found."); |
547 return; | 545 return; |
548 } | 546 } |
549 | 547 |
| 548 // TODO(ddorwin): Move this conversion to MediaDrmBridge when fixing |
| 549 // crbug.com/417440. |
| 550 // "audio"/"video" does not matter, so use "video". |
| 551 std::string init_data_type_string; |
| 552 switch (init_data_type) { |
| 553 case media::EME_INIT_DATA_TYPE_WEBM: |
| 554 init_data_type_string = "video/webm"; |
| 555 break; |
| 556 #if defined(USE_PROPRIETARY_CODECS) |
| 557 case media::EME_INIT_DATA_TYPE_CENC: |
| 558 init_data_type_string = "video/mp4"; |
| 559 break; |
| 560 #endif |
| 561 default: |
| 562 NOTREACHED(); |
| 563 } |
| 564 |
550 // Only the temporary session type is supported in browser CDM path. | 565 // Only the temporary session type is supported in browser CDM path. |
551 // TODO(xhwang): Add SessionType support if needed. | 566 // TODO(xhwang): Add SessionType support if needed. |
552 cdm->CreateSessionAndGenerateRequest(media::MediaKeys::TEMPORARY_SESSION, | 567 cdm->CreateSessionAndGenerateRequest(media::MediaKeys::TEMPORARY_SESSION, |
553 init_data_type, &init_data[0], | 568 init_data_type_string, &init_data[0], |
554 init_data.size(), promise.Pass()); | 569 init_data.size(), promise.Pass()); |
555 } | 570 } |
556 | 571 |
557 } // namespace content | 572 } // namespace content |
OLD | NEW |