Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "content/renderer/media/android/webmediaplayer_android.h" | 5 #include "content/renderer/media/android/webmediaplayer_android.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 #include "gpu/command_buffer/client/gles2_interface.h" | 33 #include "gpu/command_buffer/client/gles2_interface.h" |
| 34 #include "gpu/command_buffer/common/mailbox_holder.h" | 34 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 35 #include "media/base/android/media_player_android.h" | 35 #include "media/base/android/media_player_android.h" |
| 36 #include "media/base/bind_to_current_loop.h" | 36 #include "media/base/bind_to_current_loop.h" |
| 37 // TODO(xhwang): Remove when we remove prefixed EME implementation. | 37 // TODO(xhwang): Remove when we remove prefixed EME implementation. |
| 38 #include "media/base/media_keys.h" | 38 #include "media/base/media_keys.h" |
| 39 #include "media/base/media_switches.h" | 39 #include "media/base/media_switches.h" |
| 40 #include "media/base/video_frame.h" | 40 #include "media/base/video_frame.h" |
| 41 #include "net/base/mime_util.h" | 41 #include "net/base/mime_util.h" |
| 42 #include "third_party/WebKit/public/platform/Platform.h" | 42 #include "third_party/WebKit/public/platform/Platform.h" |
| 43 #include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h" | |
| 43 #include "third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h" | 44 #include "third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h" |
| 44 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" | 45 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" |
| 45 #include "third_party/WebKit/public/platform/WebString.h" | 46 #include "third_party/WebKit/public/platform/WebString.h" |
| 46 #include "third_party/WebKit/public/platform/WebURL.h" | 47 #include "third_party/WebKit/public/platform/WebURL.h" |
| 47 #include "third_party/WebKit/public/web/WebDocument.h" | 48 #include "third_party/WebKit/public/web/WebDocument.h" |
| 48 #include "third_party/WebKit/public/web/WebFrame.h" | 49 #include "third_party/WebKit/public/web/WebFrame.h" |
| 49 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" | 50 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
| 50 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 51 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
| 51 #include "third_party/WebKit/public/web/WebView.h" | 52 #include "third_party/WebKit/public/web/WebView.h" |
| 52 #include "third_party/skia/include/core/SkCanvas.h" | 53 #include "third_party/skia/include/core/SkCanvas.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 return web_graphics_context_->insertSyncPoint(); | 90 return web_graphics_context_->insertSyncPoint(); |
| 90 } | 91 } |
| 91 virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE { | 92 virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE { |
| 92 web_graphics_context_->waitSyncPoint(sync_point); | 93 web_graphics_context_->waitSyncPoint(sync_point); |
| 93 } | 94 } |
| 94 | 95 |
| 95 private: | 96 private: |
| 96 blink::WebGraphicsContext3D* web_graphics_context_; | 97 blink::WebGraphicsContext3D* web_graphics_context_; |
| 97 }; | 98 }; |
| 98 | 99 |
| 100 // Used for calls to decryptor_ready_cb_ where the result can be ignored. | |
| 101 void DoNothing(bool) { | |
| 102 } | |
| 103 | |
| 99 } // namespace | 104 } // namespace |
| 100 | 105 |
| 101 namespace content { | 106 namespace content { |
| 102 | 107 |
| 103 WebMediaPlayerAndroid::WebMediaPlayerAndroid( | 108 WebMediaPlayerAndroid::WebMediaPlayerAndroid( |
| 104 blink::WebFrame* frame, | 109 blink::WebFrame* frame, |
| 105 blink::WebMediaPlayerClient* client, | 110 blink::WebMediaPlayerClient* client, |
| 106 base::WeakPtr<WebMediaPlayerDelegate> delegate, | 111 base::WeakPtr<WebMediaPlayerDelegate> delegate, |
| 107 RendererMediaPlayerManager* player_manager, | 112 RendererMediaPlayerManager* player_manager, |
| 108 RendererCdmManager* cdm_manager, | 113 RendererCdmManager* cdm_manager, |
| (...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1362 base::Bind(&WebMediaPlayerAndroid::OnKeyMessage, | 1367 base::Bind(&WebMediaPlayerAndroid::OnKeyMessage, |
| 1363 weak_factory_.GetWeakPtr()))); | 1368 weak_factory_.GetWeakPtr()))); |
| 1364 } | 1369 } |
| 1365 | 1370 |
| 1366 GURL security_origin(frame_->document().securityOrigin().toString()); | 1371 GURL security_origin(frame_->document().securityOrigin().toString()); |
| 1367 if (!proxy_decryptor_->InitializeCDM(key_system, security_origin)) | 1372 if (!proxy_decryptor_->InitializeCDM(key_system, security_origin)) |
| 1368 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; | 1373 return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; |
| 1369 | 1374 |
| 1370 if (!decryptor_ready_cb_.is_null()) { | 1375 if (!decryptor_ready_cb_.is_null()) { |
| 1371 base::ResetAndReturn(&decryptor_ready_cb_) | 1376 base::ResetAndReturn(&decryptor_ready_cb_) |
| 1372 .Run(proxy_decryptor_->GetDecryptor()); | 1377 .Run(proxy_decryptor_->GetDecryptor(), base::Bind(DoNothing)); |
| 1373 } | 1378 } |
| 1374 | 1379 |
| 1375 // Only browser CDMs have CDM ID. Render side CDMs (e.g. ClearKey CDM) do | 1380 // Only browser CDMs have CDM ID. Render side CDMs (e.g. ClearKey CDM) do |
| 1376 // not have a CDM ID and there is no need to call player_manager_->SetCdm(). | 1381 // not have a CDM ID and there is no need to call player_manager_->SetCdm(). |
| 1377 if (proxy_decryptor_->GetCdmId() != RendererCdmManager::kInvalidCdmId) | 1382 if (proxy_decryptor_->GetCdmId() != RendererCdmManager::kInvalidCdmId) |
| 1378 player_manager_->SetCdm(player_id_, proxy_decryptor_->GetCdmId()); | 1383 player_manager_->SetCdm(player_id_, proxy_decryptor_->GetCdmId()); |
| 1379 | 1384 |
| 1380 current_key_system_ = key_system; | 1385 current_key_system_ = key_system; |
| 1381 } else if (key_system != current_key_system_) { | 1386 } else if (key_system != current_key_system_) { |
| 1382 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; | 1387 return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1481 DCHECK(main_thread_checker_.CalledOnValidThread()); | 1486 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 1482 | 1487 |
| 1483 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 | 1488 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 |
| 1484 if (!cdm) | 1489 if (!cdm) |
| 1485 return; | 1490 return; |
| 1486 | 1491 |
| 1487 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); | 1492 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); |
| 1488 if (!web_cdm_) | 1493 if (!web_cdm_) |
| 1489 return; | 1494 return; |
| 1490 | 1495 |
| 1491 if (!decryptor_ready_cb_.is_null()) | 1496 if (!decryptor_ready_cb_.is_null()) { |
| 1492 base::ResetAndReturn(&decryptor_ready_cb_).Run(web_cdm_->GetDecryptor()); | 1497 base::ResetAndReturn(&decryptor_ready_cb_) |
| 1498 .Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing)); | |
| 1499 } | |
| 1493 | 1500 |
| 1494 if (web_cdm_->GetCdmId() != RendererCdmManager::kInvalidCdmId) | 1501 if (web_cdm_->GetCdmId() != RendererCdmManager::kInvalidCdmId) |
| 1495 player_manager_->SetCdm(player_id_, web_cdm_->GetCdmId()); | 1502 player_manager_->SetCdm(player_id_, web_cdm_->GetCdmId()); |
| 1496 } | 1503 } |
| 1497 | 1504 |
| 1505 void WebMediaPlayerAndroid::setContentDecryptionModule( | |
| 1506 blink::WebContentDecryptionModule* cdm, | |
| 1507 blink::WebContentDecryptionModuleResult result) { | |
| 1508 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1509 | |
| 1510 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 | |
| 1511 if (!cdm) { | |
| 1512 result.completeWithError( | |
| 1513 blink::WebContentDecryptionModuleExceptionNotSupportedError, | |
| 1514 0, | |
| 1515 "Null MediaKeys object is not supported."); | |
|
xhwang
2014/08/12 16:12:59
return here?
jrummell
2014/08/12 22:54:18
Done.
| |
| 1516 } | |
| 1517 | |
| 1518 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); | |
| 1519 if (!web_cdm_) | |
| 1520 return; | |
|
xhwang
2014/08/12 16:12:59
Now with the |result|, we need to make sure the |r
jrummell
2014/08/12 22:54:18
Done.
| |
| 1521 | |
| 1522 if (!decryptor_ready_cb_.is_null()) { | |
| 1523 base::ResetAndReturn(&decryptor_ready_cb_).Run( | |
| 1524 web_cdm_->GetDecryptor(), | |
| 1525 media::BindToCurrentLoop( | |
| 1526 base::Bind(&WebMediaPlayerAndroid::ContentDecryptionModuleAttached, | |
| 1527 weak_factory_.GetWeakPtr(), | |
| 1528 result))); | |
| 1529 } else { | |
| 1530 // No pipeline/decoder connected, so resolve the promise. When something | |
| 1531 // is connected, setting the CDM will happen in SetDecryptorReadyCB(). | |
| 1532 ContentDecryptionModuleAttached(result, true); | |
| 1533 } | |
| 1534 | |
| 1535 if (web_cdm_->GetCdmId() != RendererCdmManager::kInvalidCdmId) | |
| 1536 player_manager_->SetCdm(player_id_, web_cdm_->GetCdmId()); | |
| 1537 } | |
| 1538 | |
| 1539 void WebMediaPlayerAndroid::setContentDecryptionModuleSync( | |
| 1540 blink::WebContentDecryptionModule* cdm) { | |
| 1541 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1542 | |
| 1543 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 | |
| 1544 if (!cdm) | |
| 1545 return; | |
| 1546 | |
| 1547 DCHECK(decryptor_ready_cb_.is_null()); | |
| 1548 | |
| 1549 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); | |
| 1550 if (web_cdm_->GetCdmId() != RendererCdmManager::kInvalidCdmId) | |
| 1551 player_manager_->SetCdm(player_id_, web_cdm_->GetCdmId()); | |
| 1552 } | |
| 1553 | |
| 1554 void WebMediaPlayerAndroid::ContentDecryptionModuleAttached( | |
| 1555 blink::WebContentDecryptionModuleResult result, | |
| 1556 bool success) { | |
| 1557 if (success) { | |
| 1558 result.complete(); | |
| 1559 return; | |
| 1560 } | |
| 1561 | |
| 1562 result.completeWithError( | |
| 1563 blink::WebContentDecryptionModuleExceptionNotSupportedError, | |
| 1564 0, | |
| 1565 "Unable to set MediaKeys object"); | |
| 1566 } | |
| 1567 | |
| 1498 void WebMediaPlayerAndroid::OnKeyAdded(const std::string& session_id) { | 1568 void WebMediaPlayerAndroid::OnKeyAdded(const std::string& session_id) { |
| 1499 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); | 1569 EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); |
| 1500 | 1570 |
| 1501 client_->keyAdded( | 1571 client_->keyAdded( |
| 1502 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), | 1572 WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)), |
| 1503 WebString::fromUTF8(session_id)); | 1573 WebString::fromUTF8(session_id)); |
| 1504 } | 1574 } |
| 1505 | 1575 |
| 1506 void WebMediaPlayerAndroid::OnKeyError(const std::string& session_id, | 1576 void WebMediaPlayerAndroid::OnKeyError(const std::string& session_id, |
| 1507 media::MediaKeys::KeyError error_code, | 1577 media::MediaKeys::KeyError error_code, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 client_->keyNeeded( | 1632 client_->keyNeeded( |
| 1563 WebString::fromUTF8(type), init_data_ptr, init_data.size()); | 1633 WebString::fromUTF8(type), init_data_ptr, init_data.size()); |
| 1564 } | 1634 } |
| 1565 | 1635 |
| 1566 void WebMediaPlayerAndroid::SetDecryptorReadyCB( | 1636 void WebMediaPlayerAndroid::SetDecryptorReadyCB( |
| 1567 const media::DecryptorReadyCB& decryptor_ready_cb) { | 1637 const media::DecryptorReadyCB& decryptor_ready_cb) { |
| 1568 DCHECK(main_thread_checker_.CalledOnValidThread()); | 1638 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 1569 | 1639 |
| 1570 // Cancels the previous decryptor request. | 1640 // Cancels the previous decryptor request. |
| 1571 if (decryptor_ready_cb.is_null()) { | 1641 if (decryptor_ready_cb.is_null()) { |
| 1572 if (!decryptor_ready_cb_.is_null()) | 1642 if (!decryptor_ready_cb_.is_null()) { |
| 1573 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); | 1643 base::ResetAndReturn(&decryptor_ready_cb_) |
| 1644 .Run(NULL, base::Bind(DoNothing)); | |
| 1645 } | |
| 1574 return; | 1646 return; |
| 1575 } | 1647 } |
| 1576 | 1648 |
| 1577 // TODO(xhwang): Support multiple decryptor notification request (e.g. from | 1649 // TODO(xhwang): Support multiple decryptor notification request (e.g. from |
| 1578 // video and audio). The current implementation is okay for the current | 1650 // video and audio). The current implementation is okay for the current |
| 1579 // media pipeline since we initialize audio and video decoders in sequence. | 1651 // media pipeline since we initialize audio and video decoders in sequence. |
| 1580 // But WebMediaPlayerImpl should not depend on media pipeline's implementation | 1652 // But WebMediaPlayerImpl should not depend on media pipeline's implementation |
| 1581 // detail. | 1653 // detail. |
| 1582 DCHECK(decryptor_ready_cb_.is_null()); | 1654 DCHECK(decryptor_ready_cb_.is_null()); |
| 1583 | 1655 |
| 1584 // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink. | 1656 // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink. |
| 1585 DCHECK(!proxy_decryptor_ || !web_cdm_); | 1657 DCHECK(!proxy_decryptor_ || !web_cdm_); |
| 1586 | 1658 |
| 1587 if (proxy_decryptor_) { | 1659 if (proxy_decryptor_) { |
| 1588 decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor()); | 1660 decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor(), |
| 1661 base::Bind(DoNothing)); | |
| 1589 return; | 1662 return; |
| 1590 } | 1663 } |
| 1591 | 1664 |
| 1592 if (web_cdm_) { | 1665 if (web_cdm_) { |
| 1593 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); | 1666 decryptor_ready_cb.Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing)); |
| 1594 return; | 1667 return; |
| 1595 } | 1668 } |
| 1596 | 1669 |
| 1597 decryptor_ready_cb_ = decryptor_ready_cb; | 1670 decryptor_ready_cb_ = decryptor_ready_cb; |
| 1598 } | 1671 } |
| 1599 | 1672 |
| 1600 void WebMediaPlayerAndroid::enterFullscreen() { | 1673 void WebMediaPlayerAndroid::enterFullscreen() { |
| 1601 if (player_manager_->CanEnterFullscreen(frame_)) { | 1674 if (player_manager_->CanEnterFullscreen(frame_)) { |
| 1602 player_manager_->EnterFullscreen(player_id_, frame_); | 1675 player_manager_->EnterFullscreen(player_id_, frame_); |
| 1603 SetNeedsEstablishPeer(false); | 1676 SetNeedsEstablishPeer(false); |
| 1604 } | 1677 } |
| 1605 } | 1678 } |
| 1606 | 1679 |
| 1607 bool WebMediaPlayerAndroid::canEnterFullscreen() const { | 1680 bool WebMediaPlayerAndroid::canEnterFullscreen() const { |
| 1608 return player_manager_->CanEnterFullscreen(frame_); | 1681 return player_manager_->CanEnterFullscreen(frame_); |
| 1609 } | 1682 } |
| 1610 | 1683 |
| 1611 } // namespace content | 1684 } // namespace content |
| OLD | NEW |