From f7c449e93a2a4151b3180af62e533302e9c1c9a7 Mon Sep 17 00:00:00 2001 From: Kongqun Yang Date: Wed, 1 Apr 2015 15:02:38 -0700 Subject: [PATCH] Integrate OnExpirationUpdate and OnSessionKeysChange with Android Also removes OnSessionExpiration which is no longer needed with OnSessionKeysChange. Bug: 19771612 Bug: 19771431 Merged from Widevine CDM repo: https://widevine-internal-review.googlesource.com/#/c/13951/ Change-Id: I0603e808e8d50ff7bb1fb1d5e44fabd8d268ee8a --- .../cdm/core/include/wv_cdm_event_listener.h | 8 +- .../cdm/core/include/wv_cdm_types.h | 12 +-- libwvdrmengine/cdm/core/src/policy_engine.cpp | 9 +-- .../cdm/core/test/policy_engine_unittest.cpp | 40 +++------- .../cdm/test/request_license_test.cpp | 22 +++--- libwvdrmengine/mediadrm/include/WVDrmPlugin.h | 13 ++-- libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 63 +++++++++++---- .../mediadrm/test/WVDrmPlugin_test.cpp | 77 ++++++++++++++++--- 8 files changed, 142 insertions(+), 102 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h b/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h index 1d1f1ef5..6d818fcc 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h @@ -14,11 +14,9 @@ class WvCdmEventListener { virtual ~WvCdmEventListener() {} virtual void OnSessionRenewalNeeded(const CdmSessionId& session_id) = 0; - virtual void OnSessionExpiration(const CdmSessionId& session_id) = 0; - virtual void OnSessionKeysChange( - const CdmSessionId& session_id, - const std::vector& cdm_keys_info, - bool has_new_usable_key) = 0; + virtual void OnSessionKeysChange(const CdmSessionId& session_id, + const CdmKeyStatusMap& keys_status, + bool has_new_usable_key) = 0; virtual void OnExpirationUpdate(const CdmSessionId& session_id, int64_t new_expiry_time) = 0; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 063a18a1..f228d308 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -51,12 +51,12 @@ enum CdmResponseType { enum CdmKeyStatus { kKeyStatusUsable, - kKeyStatusInternalError, kKeyStatusExpired, kKeyStatusOutputNotAllowed, - kKeyStatusOutputDownscaled, kKeyStatusPending, + kKeyStatusInternalError, }; +typedef std::map CdmKeyStatusMap; #define CORE_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ @@ -125,14 +125,6 @@ struct CdmDecryptionParameters { is_video(true) {} }; -struct CdmKeyInformation { - CdmKeyInformation(const KeyId& id, CdmKeyStatus status) - : key_id(id), key_status(status) {} - - KeyId key_id; - CdmKeyStatus key_status; -}; - // forward class references class KeyMessage; class Request; diff --git a/libwvdrmengine/cdm/core/src/policy_engine.cpp b/libwvdrmengine/cdm/core/src/policy_engine.cpp index 3592abd0..395a6bfb 100644 --- a/libwvdrmengine/cdm/core/src/policy_engine.cpp +++ b/libwvdrmengine/cdm/core/src/policy_engine.cpp @@ -54,7 +54,6 @@ void PolicyEngine::OnTimerEvent() { license_state_ != kLicenseStateExpired) { license_state_ = kLicenseStateExpired; NotifyKeysChange(kKeyStatusExpired); - if (event_listener_) event_listener_->OnSessionExpiration(session_id_); return; } @@ -217,7 +216,6 @@ void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) { void PolicyEngine::NotifySessionExpiration() { license_state_ = kLicenseStateExpired; NotifyKeysChange(kKeyStatusExpired); - if (event_listener_) event_listener_->OnSessionExpiration(session_id_); } CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) { @@ -344,12 +342,7 @@ void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) { } } if (keys_changed && event_listener_) { - std::vector keys_info; - for (std::map::iterator it = keys_status_.begin(); - it != keys_status_.end(); ++it) { - keys_info.push_back(CdmKeyInformation(it->first, it->second)); - } - event_listener_->OnSessionKeysChange(session_id_, keys_info, + event_listener_->OnSessionKeysChange(session_id_, keys_status_, has_new_usable_key); } } diff --git a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp index 2c1c3144..f20403f7 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp @@ -60,11 +60,10 @@ using video_widevine_server::sdk::OFFLINE; // gmock methods using ::testing::_; -using ::testing::AllOf; using ::testing::AtLeast; -using ::testing::Field; using ::testing::InSequence; using ::testing::MockFunction; +using ::testing::Pair; using ::testing::Return; using ::testing::StrictMock; using ::testing::UnorderedElementsAre; @@ -72,11 +71,9 @@ using ::testing::UnorderedElementsAre; class MockCdmEventListener : public WvCdmEventListener { public: MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id)); - MOCK_METHOD1(OnSessionExpiration, void(const CdmSessionId& session_id)); - MOCK_METHOD3(OnSessionKeysChange, - void(const CdmSessionId& session_id, - const std::vector& cdm_keys_info, - bool has_new_usable_key)); + MOCK_METHOD3(OnSessionKeysChange, void(const CdmSessionId& session_id, + const CdmKeyStatusMap& keys_status, + bool has_new_usable_key)); MOCK_METHOD2(OnExpirationUpdate, void(const CdmSessionId& session_id, int64_t new_expiry_time)); }; @@ -149,11 +146,8 @@ class PolicyEngineTest : public ::testing::Test { bool expected_has_new_usable_key) { EXPECT_CALL(mock_event_listener_, OnSessionKeysChange( - kSessionId, - UnorderedElementsAre( - AllOf(Field(&CdmKeyInformation::key_id, kKeyId), - Field(&CdmKeyInformation::key_status, - expected_key_status))), + kSessionId, UnorderedElementsAre( + Pair(kKeyId, expected_key_status)), expected_has_new_usable_key)); } @@ -162,14 +156,9 @@ class PolicyEngineTest : public ::testing::Test { bool expected_has_new_usable_key) { EXPECT_CALL(mock_event_listener_, OnSessionKeysChange( - kSessionId, - UnorderedElementsAre( - AllOf(Field(&CdmKeyInformation::key_id, kKeyId), - Field(&CdmKeyInformation::key_status, - expected_key1_status)), - AllOf(Field(&CdmKeyInformation::key_id, kAnotherKeyId), - Field(&CdmKeyInformation::key_status, - expected_key2_status))), + kSessionId, UnorderedElementsAre( + Pair(kKeyId, expected_key1_status), + Pair(kAnotherKeyId, expected_key2_status)), expected_has_new_usable_key)); } @@ -242,7 +231,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_RentalDurationExpired) { OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); EXPECT_CALL(check_, Call(1)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(kSessionId)); EXPECT_CALL(check_, Call(2)); policy_engine_->SetLicense(license_); @@ -278,7 +266,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired) { OnExpirationUpdate(_, playback_start_time + kPlaybackDuration)); EXPECT_CALL(check_, Call(1)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(2)); policy_engine_->SetLicense(license_); @@ -311,7 +298,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_LicenseDurationExpired) { OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); EXPECT_CALL(check_, Call(1)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(2)); policy_engine_->SetLicense(license_); @@ -344,7 +330,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay) { OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); EXPECT_CALL(check_, Call(1)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(2)); policy_engine_->SetLicense(license_); @@ -384,7 +369,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0) { EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(check_, Call(3)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(4)); policy_engine_->SetLicense(license_); @@ -425,7 +409,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackDuration0) { EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(check_, Call(3)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(4)); policy_engine_->SetLicense(license_); @@ -460,7 +443,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseDuration0) { OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); EXPECT_CALL(check_, Call(1)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(2)); policy_engine_->SetLicense(license_); @@ -548,7 +530,6 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse) { EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(2)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(3)); policy_engine_->SetLicense(license_); @@ -689,7 +670,6 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RenewFailedVersionNotUpdated) { EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(check_, Call(3)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(4)); policy_engine_->SetLicense(license_); @@ -750,7 +730,6 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures) { EXPECT_CALL(check_, Call(6)); EXPECT_CALL(check_, Call(7)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(8)); policy_engine_->SetLicense(license_); @@ -802,7 +781,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry) { EXPECT_CALL(check_, Call(6)); EXPECT_CALL(check_, Call(7)); ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_)); EXPECT_CALL(check_, Call(8)); ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL( diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 73b6af8f..f569bb34 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -24,9 +24,12 @@ #include "wv_content_decryption_module.h" using ::testing::_; +using ::testing::AllOf; using ::testing::AtLeast; using ::testing::Each; -using ::testing::Field; +using ::testing::IsEmpty; +using ::testing::Not; +using ::testing::Pair; using ::testing::StrictMock; namespace { @@ -449,11 +452,9 @@ class TestWvCdmEventListener : public WvCdmEventListener { TestWvCdmEventListener() : WvCdmEventListener() {} MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id)); - MOCK_METHOD1(OnSessionExpiration, void(const CdmSessionId& session_id)); - MOCK_METHOD3(OnSessionKeysChange, - void(const CdmSessionId& session_id, - const std::vector& cdm_keys_info, - bool has_new_usable_key)); + MOCK_METHOD3(OnSessionKeysChange, void(const CdmSessionId& session_id, + const CdmKeyStatusMap& keys_status, + bool has_new_usable_key)); MOCK_METHOD2(OnExpirationUpdate, void(const CdmSessionId& session_id, int64_t new_expiry_time)); }; @@ -1171,8 +1172,8 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) { CdmSessionId restore_session_id = session_id_; EXPECT_CALL(listener, OnSessionKeysChange(restore_session_id, - Each(Field(&CdmKeyInformation::key_status, - kKeyStatusUsable)), + AllOf(Each(Pair(_, kKeyStatusUsable)), + Not(IsEmpty())), true)); EXPECT_CALL(listener, OnExpirationUpdate(restore_session_id, _)); EXPECT_EQ(wvcdm::KEY_ADDED, @@ -1185,10 +1186,9 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) { .Times(AtLeast(0)); EXPECT_CALL(listener, OnSessionKeysChange(restore_session_id, - Each(Field(&CdmKeyInformation::key_status, - kKeyStatusExpired)), + AllOf(Each(Pair(_, kKeyStatusExpired)), + Not(IsEmpty())), false)); - EXPECT_CALL(listener, OnSessionExpiration(restore_session_id)); GenerateKeyRelease(key_set_id); key_set_id_ = key_set_id; VerifyKeyRequestResponse(g_license_server, client_auth, false); diff --git a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h index 1e89ffab..56e2bed7 100644 --- a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h @@ -32,7 +32,7 @@ using android::status_t; using android::String8; using android::Vector; using std::map; -using wvcdm::CdmKeyInformation; +using wvcdm::CdmKeyStatusMap; using wvcdm::CdmSessionId; using wvcdm::CdmResponseType; using wvcdm::WvContentDecryptionModule; @@ -142,15 +142,12 @@ class WVDrmPlugin : public android::DrmPlugin, virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId); - virtual void OnSessionExpiration(const CdmSessionId& cdmSessionId); - - virtual void OnSessionKeysChange( - const CdmSessionId& session_id, - const std::vector& cdm_keys_info, - bool has_new_usable_key); + virtual void OnSessionKeysChange(const CdmSessionId& cdmSessionId, + const CdmKeyStatusMap& cdmKeysStatus, + bool hasNewUsableKey); virtual void OnExpirationUpdate(const CdmSessionId& cdmSessionId, - int64_t new_expiry_time); + int64_t newExpiryTime); private: DISALLOW_EVIL_CONSTRUCTORS(WVDrmPlugin); diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index c79484bc..fe8d908b 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -33,6 +33,13 @@ using namespace std; using namespace wvcdm; namespace { + +Vector ToVector(const std::string& str) { + Vector vector; + vector.appendArray(reinterpret_cast(str.data()), str.size()); + return vector; +} + DrmPlugin::KeyRequestType ConvertFromCdmKeyRequestType( CdmKeyRequestType keyRequestType) { switch (keyRequestType) { @@ -46,6 +53,23 @@ DrmPlugin::KeyRequestType ConvertFromCdmKeyRequestType( return DrmPlugin::kKeyRequestType_Unknown; } } + +DrmPlugin::KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { + switch (keyStatus) { + case kKeyStatusUsable: + return DrmPlugin::kKeyStatusType_Usable; + case kKeyStatusExpired: + return DrmPlugin::kKeyStatusType_Expired; + case kKeyStatusOutputNotAllowed: + return DrmPlugin::kKeyStatusType_OutputNotAllowed; + case kKeyStatusPending: + return DrmPlugin::kKeyStatusType_StatusPending; + case kKeyStatusInternalError: + default: + return DrmPlugin::kKeyStatusType_InternalError; + } +} + } // namespace WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm, @@ -941,30 +965,35 @@ status_t WVDrmPlugin::signRSA(const Vector& /* sessionId */, } void WVDrmPlugin::OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId) { - Vector sessionId; - sessionId.appendArray(reinterpret_cast(cdmSessionId.data()), - cdmSessionId.size()); + Vector sessionId = ToVector(cdmSessionId); sendEvent(kDrmPluginEventKeyNeeded, 0, &sessionId, NULL); } -void WVDrmPlugin::OnSessionExpiration(const CdmSessionId& cdmSessionId) { - Vector sessionId; - sessionId.appendArray(reinterpret_cast(cdmSessionId.data()), - cdmSessionId.size()); - sendEvent(kDrmPluginEventKeyExpired, 0, &sessionId, NULL); -} +void WVDrmPlugin::OnSessionKeysChange(const CdmSessionId& cdmSessionId, + const CdmKeyStatusMap& cdmKeysStatus, + bool hasNewUsableKey) { + bool expired = false; + Vector keyStatusList; + for (CdmKeyStatusMap::const_iterator it = cdmKeysStatus.begin(); + it != cdmKeysStatus.end(); ++it) { + const KeyId& keyId = it->first; + const CdmKeyStatus cdmKeyStatus = it->second; + if (cdmKeyStatus == kKeyStatusExpired) expired = true; -void WVDrmPlugin::OnSessionKeysChange( - const CdmSessionId& session_id, - const std::vector& cdm_keys_info, - bool has_new_usable_key) { - // TODO(kqyang): Glue with DrmPlugin API when it is ready. + keyStatusList.push( + {ToVector(keyId), ConvertFromCdmKeyStatus(cdmKeyStatus)}); + } + + Vector sessionId = ToVector(cdmSessionId); + sendKeysChange(&sessionId, &keyStatusList, hasNewUsableKey); + // For backward compatibility. + if (expired) sendEvent(kDrmPluginEventKeyExpired, 0, &sessionId, NULL); } void WVDrmPlugin::OnExpirationUpdate(const CdmSessionId& cdmSessionId, - int64_t new_expiry_time) { - // TODO(kqyang): Glue with DrmPlugin API when it is ready. Note that - // new_expiry_time is in seconds while Android API is in milliseconds. + int64_t newExpiryTime) { + Vector sessionId = ToVector(cdmSessionId); + sendExpirationUpdate(&sessionId, newExpiryTime * 1000); } status_t WVDrmPlugin::mapAndNotifyOfCdmResponseType( diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 57146c77..b756421c 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -113,6 +113,9 @@ class MockDrmPluginListener : public DrmPluginListener { public: MOCK_METHOD4(sendEvent, void(DrmPlugin::EventType, int, const Vector*, const Vector*)); + MOCK_METHOD2(sendExpirationUpdate, void(const Vector*, int64_t)); + MOCK_METHOD3(sendKeysChange, void(const Vector*, + const Vector*, bool)); }; template @@ -1181,27 +1184,77 @@ TEST_F(WVDrmPluginTest, MarshalsEvents) { sp > listener = new StrictMock(); + const int64_t kExpiryTimeInSeconds = 123456789012LL; + const char kKeyId1[] = "Testing Key1 Id "; + const char kKeyId2[] = "Testing Key2 Id "; + const char kKeyId3[] = "Testing Key3 Id "; + const char kKeyId4[] = "Testing Key4 Id "; + { InSequence calls; - EXPECT_CALL(*listener, sendEvent(DrmPlugin::kDrmPluginEventKeyExpired, 0, - Pointee(ElementsAreArray(sessionIdRaw, - kSessionIdSize)), - NULL)) - .Times(1); - - EXPECT_CALL(*listener, sendEvent(DrmPlugin::kDrmPluginEventKeyNeeded, 0, - Pointee(ElementsAreArray(sessionIdRaw, - kSessionIdSize)), - NULL)) - .Times(1); + EXPECT_CALL(*listener, + sendKeysChange( + Pointee(ElementsAreArray(sessionIdRaw, kSessionIdSize)), + Pointee(UnorderedElementsAre(AllOf( + Field(&DrmPlugin::KeyStatus::mKeyId, + ElementsAreArray(kKeyId1, sizeof(kKeyId1) - 1)), + Field(&DrmPlugin::KeyStatus::mType, + DrmPlugin::kKeyStatusType_Expired)))), + false)); + EXPECT_CALL( + *listener, + sendEvent(DrmPlugin::kDrmPluginEventKeyExpired, 0, + Pointee(ElementsAreArray(sessionIdRaw, kSessionIdSize)), + NULL)); + EXPECT_CALL( + *listener, + sendEvent(DrmPlugin::kDrmPluginEventKeyNeeded, 0, + Pointee(ElementsAreArray(sessionIdRaw, kSessionIdSize)), + NULL)); + EXPECT_CALL(*listener, + sendExpirationUpdate( + Pointee(ElementsAreArray(sessionIdRaw, kSessionIdSize)), + kExpiryTimeInSeconds * 1000)); + EXPECT_CALL( + *listener, + sendKeysChange( + Pointee(ElementsAreArray(sessionIdRaw, kSessionIdSize)), + Pointee(UnorderedElementsAre( + AllOf(Field(&DrmPlugin::KeyStatus::mKeyId, + ElementsAreArray(kKeyId1, sizeof(kKeyId1) - 1)), + Field(&DrmPlugin::KeyStatus::mType, + DrmPlugin::kKeyStatusType_Usable)), + AllOf(Field(&DrmPlugin::KeyStatus::mKeyId, + ElementsAreArray(kKeyId2, sizeof(kKeyId2) - 1)), + Field(&DrmPlugin::KeyStatus::mType, + DrmPlugin::kKeyStatusType_OutputNotAllowed)), + AllOf(Field(&DrmPlugin::KeyStatus::mKeyId, + ElementsAreArray(kKeyId3, sizeof(kKeyId3) - 1)), + Field(&DrmPlugin::KeyStatus::mType, + DrmPlugin::kKeyStatusType_InternalError)), + AllOf(Field(&DrmPlugin::KeyStatus::mKeyId, + ElementsAreArray(kKeyId4, sizeof(kKeyId4) - 1)), + Field(&DrmPlugin::KeyStatus::mType, + DrmPlugin::kKeyStatusType_StatusPending)))), + true)); } status_t res = plugin.setListener(listener); ASSERT_EQ(OK, res); - plugin.OnSessionExpiration(cdmSessionId); + CdmKeyStatusMap cdmKeysStatus; + cdmKeysStatus[kKeyId1] = kKeyStatusExpired; + plugin.OnSessionKeysChange(cdmSessionId, cdmKeysStatus, false); + plugin.OnSessionRenewalNeeded(cdmSessionId); + plugin.OnExpirationUpdate(cdmSessionId, kExpiryTimeInSeconds); + + cdmKeysStatus[kKeyId1] = kKeyStatusUsable; + cdmKeysStatus[kKeyId2] = kKeyStatusOutputNotAllowed; + cdmKeysStatus[kKeyId3] = kKeyStatusInternalError; + cdmKeysStatus[kKeyId4] = kKeyStatusPending; + plugin.OnSessionKeysChange(cdmSessionId, cdmKeysStatus, true); } TEST_F(WVDrmPluginTest, GeneratesProvisioningNeededEvent) {