123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "media/cdm/win/media_foundation_cdm_session.h"
- #include <wchar.h>
- #include "base/bind.h"
- #include "base/test/mock_callback.h"
- #include "base/test/task_environment.h"
- #include "media/base/mock_filters.h"
- #include "media/base/test_helpers.h"
- #include "media/base/win/mf_helpers.h"
- #include "media/base/win/mf_mocks.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using ::testing::_;
- using ::testing::DoAll;
- using ::testing::InSequence;
- using ::testing::IsEmpty;
- using ::testing::NotNull;
- using ::testing::Return;
- using ::testing::SetArgPointee;
- using ::testing::StrictMock;
- using ::testing::WithoutArgs;
- namespace media {
- namespace {
- const double kExpirationMs = 123456789.0;
- const auto kExpirationTime = base::Time::FromJsTime(kExpirationMs);
- const char kTestUmaPrefix[] = "Media.EME.TestUmaPrefix.";
- std::vector<uint8_t> StringToVector(const std::string& str) {
- return std::vector<uint8_t>(str.begin(), str.end());
- }
- } // namespace
- using Microsoft::WRL::ComPtr;
- class MediaFoundationCdmSessionTest : public testing::Test {
- public:
- MediaFoundationCdmSessionTest()
- : mf_cdm_(MakeComPtr<MockMFCdm>()),
- mf_cdm_session_(MakeComPtr<MockMFCdmSession>()),
- cdm_session_(
- kTestUmaPrefix,
- base::BindRepeating(&MockCdmClient::OnSessionMessage,
- base::Unretained(&cdm_client_)),
- base::BindRepeating(&MockCdmClient::OnSessionKeysChange,
- base::Unretained(&cdm_client_)),
- base::BindRepeating(&MockCdmClient::OnSessionExpirationUpdate,
- base::Unretained(&cdm_client_))) {}
- ~MediaFoundationCdmSessionTest() override = default;
- void Initialize() {
- COM_EXPECT_CALL(mf_cdm_,
- CreateSession(MF_MEDIAKEYSESSION_TYPE_TEMPORARY, _, _))
- .WillOnce(DoAll(SaveComPtr<1>(&mf_cdm_session_callbacks_),
- SetComPointee<2>(mf_cdm_session_.Get()), Return(S_OK)));
- ASSERT_SUCCESS(
- cdm_session_.Initialize(mf_cdm_.Get(), CdmSessionType::kTemporary));
- }
- void GenerateRequest() {
- std::vector<uint8_t> init_data = StringToVector("init_data");
- std::vector<uint8_t> license_request = StringToVector("request");
- base::MockCallback<MediaFoundationCdmSession::SessionIdCB> session_id_cb;
- // Session ID to return. Will be released by |mf_cdm_session_|.
- LPWSTR session_id = nullptr;
- ASSERT_SUCCESS(CopyCoTaskMemWideString(L"session_id", &session_id));
- {
- // Use InSequence here because the order of events matter. |session_id_cb|
- // must be called before OnSessionMessage().
- InSequence seq;
- COM_EXPECT_CALL(mf_cdm_session_, GenerateRequest(_, _, init_data.size()))
- .WillOnce(WithoutArgs([&] {
- mf_cdm_session_callbacks_->KeyMessage(
- MF_MEDIAKEYSESSION_MESSAGETYPE_LICENSE_REQUEST,
- license_request.data(), license_request.size(), nullptr);
- return S_OK;
- }));
- COM_EXPECT_CALL(mf_cdm_session_, GetSessionId(_))
- .WillOnce(DoAll(SetArgPointee<0>(session_id), Return(S_OK)));
- EXPECT_CALL(session_id_cb, Run(_)).WillOnce(Return(true));
- EXPECT_CALL(cdm_client_,
- OnSessionMessage(_, CdmMessageType::LICENSE_REQUEST,
- license_request));
- }
- EXPECT_SUCCESS(cdm_session_.GenerateRequest(
- EmeInitDataType::WEBM, init_data, session_id_cb.Get()));
- task_environment_.RunUntilIdle();
- }
- protected:
- base::test::TaskEnvironment task_environment_;
- StrictMock<MockCdmClient> cdm_client_;
- ComPtr<MockMFCdm> mf_cdm_;
- ComPtr<MockMFCdmSession> mf_cdm_session_;
- MediaFoundationCdmSession cdm_session_;
- ComPtr<IMFContentDecryptionModuleSessionCallbacks> mf_cdm_session_callbacks_;
- };
- TEST_F(MediaFoundationCdmSessionTest, Initialize) {
- Initialize();
- }
- TEST_F(MediaFoundationCdmSessionTest, Initialize_Failure) {
- COM_EXPECT_CALL(mf_cdm_,
- CreateSession(MF_MEDIAKEYSESSION_TYPE_TEMPORARY, _, _))
- .WillOnce(DoAll(SaveComPtr<1>(&mf_cdm_session_callbacks_),
- SetComPointee<2>(mf_cdm_session_.Get()), Return(E_FAIL)));
- EXPECT_FAILED(
- cdm_session_.Initialize(mf_cdm_.Get(), CdmSessionType::kTemporary));
- }
- TEST_F(MediaFoundationCdmSessionTest, GenerateRequest) {
- Initialize();
- GenerateRequest();
- }
- TEST_F(MediaFoundationCdmSessionTest, GenerateRequest_Failure) {
- Initialize();
- std::vector<uint8_t> init_data = StringToVector("init_data");
- base::MockCallback<MediaFoundationCdmSession::SessionIdCB> session_id_cb;
- COM_EXPECT_CALL(mf_cdm_session_, GenerateRequest(_, _, init_data.size()))
- .WillOnce(Return(E_FAIL));
- EXPECT_FAILED(cdm_session_.GenerateRequest(EmeInitDataType::WEBM, init_data,
- session_id_cb.Get()));
- task_environment_.RunUntilIdle();
- }
- TEST_F(MediaFoundationCdmSessionTest, GetSessionId_Failure) {
- Initialize();
- std::vector<uint8_t> init_data = StringToVector("init_data");
- std::vector<uint8_t> license_request = StringToVector("request");
- base::MockCallback<MediaFoundationCdmSession::SessionIdCB> session_id_cb;
- COM_EXPECT_CALL(mf_cdm_session_, GenerateRequest(_, _, init_data.size()))
- .WillOnce(WithoutArgs([&] {
- mf_cdm_session_callbacks_->KeyMessage(
- MF_MEDIAKEYSESSION_MESSAGETYPE_LICENSE_REQUEST,
- license_request.data(), license_request.size(), nullptr);
- return S_OK;
- }));
- COM_EXPECT_CALL(mf_cdm_session_, GetSessionId(_)).WillOnce(Return(E_FAIL));
- EXPECT_CALL(session_id_cb, Run(IsEmpty()));
- // OnSessionMessage() will not be called.
- EXPECT_SUCCESS(cdm_session_.GenerateRequest(EmeInitDataType::WEBM, init_data,
- session_id_cb.Get()));
- task_environment_.RunUntilIdle();
- }
- TEST_F(MediaFoundationCdmSessionTest, GetSessionId_Empty) {
- Initialize();
- std::vector<uint8_t> init_data = StringToVector("init_data");
- std::vector<uint8_t> license_request = StringToVector("request");
- base::MockCallback<MediaFoundationCdmSession::SessionIdCB> session_id_cb;
- // Session ID to return. Will be released by |mf_cdm_session_|.
- LPWSTR empty_session_id = nullptr;
- ASSERT_SUCCESS(CopyCoTaskMemWideString(L"", &empty_session_id));
- COM_EXPECT_CALL(mf_cdm_session_, GenerateRequest(_, _, init_data.size()))
- .WillOnce(WithoutArgs([&] {
- mf_cdm_session_callbacks_->KeyMessage(
- MF_MEDIAKEYSESSION_MESSAGETYPE_LICENSE_REQUEST,
- license_request.data(), license_request.size(), nullptr);
- return S_OK;
- }));
- COM_EXPECT_CALL(mf_cdm_session_, GetSessionId(_))
- .WillOnce(DoAll(SetArgPointee<0>(empty_session_id), Return(S_OK)));
- EXPECT_CALL(session_id_cb, Run(IsEmpty()));
- // OnSessionMessage() will not be called since session ID is empty.
- EXPECT_SUCCESS(cdm_session_.GenerateRequest(EmeInitDataType::WEBM, init_data,
- session_id_cb.Get()));
- task_environment_.RunUntilIdle();
- }
- TEST_F(MediaFoundationCdmSessionTest, Update) {
- Initialize();
- GenerateRequest();
- std::vector<uint8_t> response = StringToVector("response");
- COM_EXPECT_CALL(mf_cdm_session_, Update(NotNull(), response.size()))
- .WillOnce(DoAll([&] { mf_cdm_session_callbacks_->KeyStatusChanged(); },
- Return(S_OK)));
- COM_EXPECT_CALL(mf_cdm_session_, GetKeyStatuses(_, _)).WillOnce(Return(S_OK));
- COM_EXPECT_CALL(mf_cdm_session_, GetExpiration(_))
- .WillOnce(DoAll(SetArgPointee<0>(kExpirationMs), Return(S_OK)));
- EXPECT_CALL(cdm_client_, OnSessionKeysChangeCalled(_, true));
- EXPECT_CALL(cdm_client_, OnSessionExpirationUpdate(_, kExpirationTime));
- EXPECT_SUCCESS(cdm_session_.Update(response));
- task_environment_.RunUntilIdle();
- }
- TEST_F(MediaFoundationCdmSessionTest, Update_Failure) {
- Initialize();
- GenerateRequest();
- std::vector<uint8_t> response = StringToVector("response");
- COM_EXPECT_CALL(mf_cdm_session_, Update(NotNull(), response.size()))
- .WillOnce(Return(E_FAIL));
- EXPECT_FAILED(cdm_session_.Update(response));
- }
- TEST_F(MediaFoundationCdmSessionTest, Close) {
- Initialize();
- GenerateRequest();
- COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(S_OK));
- EXPECT_SUCCESS(cdm_session_.Close());
- }
- TEST_F(MediaFoundationCdmSessionTest, Close_Failure) {
- Initialize();
- GenerateRequest();
- COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(E_FAIL));
- EXPECT_FAILED(cdm_session_.Close());
- }
- TEST_F(MediaFoundationCdmSessionTest, Remove) {
- Initialize();
- GenerateRequest();
- COM_EXPECT_CALL(mf_cdm_session_, Remove()).WillOnce(Return(S_OK));
- COM_EXPECT_CALL(mf_cdm_session_, GetExpiration(_))
- .WillOnce(DoAll(SetArgPointee<0>(kExpirationMs), Return(S_OK)));
- EXPECT_CALL(cdm_client_, OnSessionExpirationUpdate(_, kExpirationTime));
- EXPECT_SUCCESS(cdm_session_.Remove());
- }
- TEST_F(MediaFoundationCdmSessionTest, Remove_Failure) {
- Initialize();
- GenerateRequest();
- COM_EXPECT_CALL(mf_cdm_session_, Remove()).WillOnce(Return(E_FAIL));
- EXPECT_FAILED(cdm_session_.Remove());
- }
- } // namespace media
|