Merge "Integrate OnExpirationUpdate and OnSessionKeysChange with Android"

This commit is contained in:
Jeff Tinker
2015-04-10 00:01:32 +00:00
committed by Android (Google) Code Review
8 changed files with 135 additions and 102 deletions

View File

@@ -14,10 +14,8 @@ class WvCdmEventListener {
virtual ~WvCdmEventListener() {} virtual ~WvCdmEventListener() {}
virtual void OnSessionRenewalNeeded(const CdmSessionId& session_id) = 0; virtual void OnSessionRenewalNeeded(const CdmSessionId& session_id) = 0;
virtual void OnSessionExpiration(const CdmSessionId& session_id) = 0; virtual void OnSessionKeysChange(const CdmSessionId& session_id,
virtual void OnSessionKeysChange( const CdmKeyStatusMap& keys_status,
const CdmSessionId& session_id,
const std::vector<CdmKeyInformation>& cdm_keys_info,
bool has_new_usable_key) = 0; bool has_new_usable_key) = 0;
virtual void OnExpirationUpdate(const CdmSessionId& session_id, virtual void OnExpirationUpdate(const CdmSessionId& session_id,
int64_t new_expiry_time) = 0; int64_t new_expiry_time) = 0;

View File

@@ -51,12 +51,12 @@ enum CdmResponseType {
enum CdmKeyStatus { enum CdmKeyStatus {
kKeyStatusUsable, kKeyStatusUsable,
kKeyStatusInternalError,
kKeyStatusExpired, kKeyStatusExpired,
kKeyStatusOutputNotAllowed, kKeyStatusOutputNotAllowed,
kKeyStatusOutputDownscaled,
kKeyStatusPending, kKeyStatusPending,
kKeyStatusInternalError,
}; };
typedef std::map<KeyId, CdmKeyStatus> CdmKeyStatusMap;
#define CORE_DISALLOW_COPY_AND_ASSIGN(TypeName) \ #define CORE_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \ TypeName(const TypeName&); \
@@ -125,14 +125,6 @@ struct CdmDecryptionParameters {
is_video(true) {} 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 // forward class references
class KeyMessage; class KeyMessage;
class Request; class Request;

View File

@@ -54,7 +54,6 @@ void PolicyEngine::OnTimerEvent() {
license_state_ != kLicenseStateExpired) { license_state_ != kLicenseStateExpired) {
license_state_ = kLicenseStateExpired; license_state_ = kLicenseStateExpired;
NotifyKeysChange(kKeyStatusExpired); NotifyKeysChange(kKeyStatusExpired);
if (event_listener_) event_listener_->OnSessionExpiration(session_id_);
return; return;
} }
@@ -217,7 +216,6 @@ void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) {
void PolicyEngine::NotifySessionExpiration() { void PolicyEngine::NotifySessionExpiration() {
license_state_ = kLicenseStateExpired; license_state_ = kLicenseStateExpired;
NotifyKeysChange(kKeyStatusExpired); NotifyKeysChange(kKeyStatusExpired);
if (event_listener_) event_listener_->OnSessionExpiration(session_id_);
} }
CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) { CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) {
@@ -344,12 +342,7 @@ void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) {
} }
} }
if (keys_changed && event_listener_) { if (keys_changed && event_listener_) {
std::vector<CdmKeyInformation> keys_info; event_listener_->OnSessionKeysChange(session_id_, keys_status_,
for (std::map<KeyId, CdmKeyStatus>::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,
has_new_usable_key); has_new_usable_key);
} }
} }

View File

@@ -60,11 +60,10 @@ using video_widevine_server::sdk::OFFLINE;
// gmock methods // gmock methods
using ::testing::_; using ::testing::_;
using ::testing::AllOf;
using ::testing::AtLeast; using ::testing::AtLeast;
using ::testing::Field;
using ::testing::InSequence; using ::testing::InSequence;
using ::testing::MockFunction; using ::testing::MockFunction;
using ::testing::Pair;
using ::testing::Return; using ::testing::Return;
using ::testing::StrictMock; using ::testing::StrictMock;
using ::testing::UnorderedElementsAre; using ::testing::UnorderedElementsAre;
@@ -72,10 +71,8 @@ using ::testing::UnorderedElementsAre;
class MockCdmEventListener : public WvCdmEventListener { class MockCdmEventListener : public WvCdmEventListener {
public: public:
MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id)); MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id));
MOCK_METHOD1(OnSessionExpiration, void(const CdmSessionId& session_id)); MOCK_METHOD3(OnSessionKeysChange, void(const CdmSessionId& session_id,
MOCK_METHOD3(OnSessionKeysChange, const CdmKeyStatusMap& keys_status,
void(const CdmSessionId& session_id,
const std::vector<CdmKeyInformation>& cdm_keys_info,
bool has_new_usable_key)); bool has_new_usable_key));
MOCK_METHOD2(OnExpirationUpdate, MOCK_METHOD2(OnExpirationUpdate,
void(const CdmSessionId& session_id, int64_t new_expiry_time)); 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) { bool expected_has_new_usable_key) {
EXPECT_CALL(mock_event_listener_, EXPECT_CALL(mock_event_listener_,
OnSessionKeysChange( OnSessionKeysChange(
kSessionId, kSessionId, UnorderedElementsAre(
UnorderedElementsAre( Pair(kKeyId, expected_key_status)),
AllOf(Field(&CdmKeyInformation::key_id, kKeyId),
Field(&CdmKeyInformation::key_status,
expected_key_status))),
expected_has_new_usable_key)); expected_has_new_usable_key));
} }
@@ -162,14 +156,9 @@ class PolicyEngineTest : public ::testing::Test {
bool expected_has_new_usable_key) { bool expected_has_new_usable_key) {
EXPECT_CALL(mock_event_listener_, EXPECT_CALL(mock_event_listener_,
OnSessionKeysChange( OnSessionKeysChange(
kSessionId, kSessionId, UnorderedElementsAre(
UnorderedElementsAre( Pair(kKeyId, expected_key1_status),
AllOf(Field(&CdmKeyInformation::key_id, kKeyId), Pair(kAnotherKeyId, expected_key2_status)),
Field(&CdmKeyInformation::key_status,
expected_key1_status)),
AllOf(Field(&CdmKeyInformation::key_id, kAnotherKeyId),
Field(&CdmKeyInformation::key_status,
expected_key2_status))),
expected_has_new_usable_key)); expected_has_new_usable_key));
} }
@@ -242,7 +231,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_RentalDurationExpired) {
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(kSessionId));
EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -278,7 +266,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired) {
OnExpirationUpdate(_, playback_start_time + kPlaybackDuration)); OnExpirationUpdate(_, playback_start_time + kPlaybackDuration));
EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -311,7 +298,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_LicenseDurationExpired) {
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -344,7 +330,6 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay) {
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -384,7 +369,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0) {
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(3)); EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(4)); EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -425,7 +409,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackDuration0) {
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(3)); EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(4)); EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -460,7 +443,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseDuration0) {
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -548,7 +530,6 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse) {
EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(2));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(3)); EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -689,7 +670,6 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RenewFailedVersionNotUpdated) {
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(3)); EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(4)); EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -750,7 +730,6 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures) {
EXPECT_CALL(check_, Call(6)); EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7)); EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(8)); EXPECT_CALL(check_, Call(8));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
@@ -802,7 +781,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry) {
EXPECT_CALL(check_, Call(6)); EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7)); EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_, OnSessionExpiration(_));
EXPECT_CALL(check_, Call(8)); EXPECT_CALL(check_, Call(8));
ExpectSessionKeysChange(kKeyStatusUsable, true); ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL( EXPECT_CALL(

View File

@@ -24,9 +24,12 @@
#include "wv_content_decryption_module.h" #include "wv_content_decryption_module.h"
using ::testing::_; using ::testing::_;
using ::testing::AllOf;
using ::testing::AtLeast; using ::testing::AtLeast;
using ::testing::Each; using ::testing::Each;
using ::testing::Field; using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::Pair;
using ::testing::StrictMock; using ::testing::StrictMock;
namespace { namespace {
@@ -449,10 +452,8 @@ class TestWvCdmEventListener : public WvCdmEventListener {
TestWvCdmEventListener() : WvCdmEventListener() {} TestWvCdmEventListener() : WvCdmEventListener() {}
MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id)); MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id));
MOCK_METHOD1(OnSessionExpiration, void(const CdmSessionId& session_id)); MOCK_METHOD3(OnSessionKeysChange, void(const CdmSessionId& session_id,
MOCK_METHOD3(OnSessionKeysChange, const CdmKeyStatusMap& keys_status,
void(const CdmSessionId& session_id,
const std::vector<CdmKeyInformation>& cdm_keys_info,
bool has_new_usable_key)); bool has_new_usable_key));
MOCK_METHOD2(OnExpirationUpdate, MOCK_METHOD2(OnExpirationUpdate,
void(const CdmSessionId& session_id, int64_t new_expiry_time)); void(const CdmSessionId& session_id, int64_t new_expiry_time));
@@ -1171,8 +1172,8 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
CdmSessionId restore_session_id = session_id_; CdmSessionId restore_session_id = session_id_;
EXPECT_CALL(listener, EXPECT_CALL(listener,
OnSessionKeysChange(restore_session_id, OnSessionKeysChange(restore_session_id,
Each(Field(&CdmKeyInformation::key_status, AllOf(Each(Pair(_, kKeyStatusUsable)),
kKeyStatusUsable)), Not(IsEmpty())),
true)); true));
EXPECT_CALL(listener, OnExpirationUpdate(restore_session_id, _)); EXPECT_CALL(listener, OnExpirationUpdate(restore_session_id, _));
EXPECT_EQ(wvcdm::KEY_ADDED, EXPECT_EQ(wvcdm::KEY_ADDED,
@@ -1185,10 +1186,9 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
.Times(AtLeast(0)); .Times(AtLeast(0));
EXPECT_CALL(listener, EXPECT_CALL(listener,
OnSessionKeysChange(restore_session_id, OnSessionKeysChange(restore_session_id,
Each(Field(&CdmKeyInformation::key_status, AllOf(Each(Pair(_, kKeyStatusExpired)),
kKeyStatusExpired)), Not(IsEmpty())),
false)); false));
EXPECT_CALL(listener, OnSessionExpiration(restore_session_id));
GenerateKeyRelease(key_set_id); GenerateKeyRelease(key_set_id);
key_set_id_ = key_set_id; key_set_id_ = key_set_id;
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);

View File

@@ -32,7 +32,7 @@ using android::status_t;
using android::String8; using android::String8;
using android::Vector; using android::Vector;
using std::map; using std::map;
using wvcdm::CdmKeyInformation; using wvcdm::CdmKeyStatusMap;
using wvcdm::CdmSessionId; using wvcdm::CdmSessionId;
using wvcdm::CdmResponseType; using wvcdm::CdmResponseType;
using wvcdm::WvContentDecryptionModule; using wvcdm::WvContentDecryptionModule;
@@ -142,15 +142,12 @@ class WVDrmPlugin : public android::DrmPlugin,
virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId); virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId);
virtual void OnSessionExpiration(const CdmSessionId& cdmSessionId); virtual void OnSessionKeysChange(const CdmSessionId& cdmSessionId,
const CdmKeyStatusMap& cdmKeysStatus,
virtual void OnSessionKeysChange( bool hasNewUsableKey);
const CdmSessionId& session_id,
const std::vector<CdmKeyInformation>& cdm_keys_info,
bool has_new_usable_key);
virtual void OnExpirationUpdate(const CdmSessionId& cdmSessionId, virtual void OnExpirationUpdate(const CdmSessionId& cdmSessionId,
int64_t new_expiry_time); int64_t newExpiryTime);
private: private:
DISALLOW_EVIL_CONSTRUCTORS(WVDrmPlugin); DISALLOW_EVIL_CONSTRUCTORS(WVDrmPlugin);

View File

@@ -53,6 +53,23 @@ DrmPlugin::KeyRequestType ConvertFromCdmKeyRequestType(
return DrmPlugin::kKeyRequestType_Unknown; 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 } // namespace
WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm, WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm,
@@ -859,30 +876,35 @@ status_t WVDrmPlugin::signRSA(const Vector<uint8_t>& /* sessionId */,
} }
void WVDrmPlugin::OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId) { void WVDrmPlugin::OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId) {
Vector<uint8_t> sessionId; Vector<uint8_t> sessionId = ToVector(cdmSessionId);
sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()),
cdmSessionId.size());
sendEvent(kDrmPluginEventKeyNeeded, 0, &sessionId, NULL); sendEvent(kDrmPluginEventKeyNeeded, 0, &sessionId, NULL);
} }
void WVDrmPlugin::OnSessionExpiration(const CdmSessionId& cdmSessionId) { void WVDrmPlugin::OnSessionKeysChange(const CdmSessionId& cdmSessionId,
Vector<uint8_t> sessionId; const CdmKeyStatusMap& cdmKeysStatus,
sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()), bool hasNewUsableKey) {
cdmSessionId.size()); bool expired = false;
sendEvent(kDrmPluginEventKeyExpired, 0, &sessionId, NULL); Vector<KeyStatus> 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;
keyStatusList.push(
{ToVector(keyId), ConvertFromCdmKeyStatus(cdmKeyStatus)});
} }
void WVDrmPlugin::OnSessionKeysChange( Vector<uint8_t> sessionId = ToVector(cdmSessionId);
const CdmSessionId& session_id, sendKeysChange(&sessionId, &keyStatusList, hasNewUsableKey);
const std::vector<CdmKeyInformation>& cdm_keys_info, // For backward compatibility.
bool has_new_usable_key) { if (expired) sendEvent(kDrmPluginEventKeyExpired, 0, &sessionId, NULL);
// TODO(kqyang): Glue with DrmPlugin API when it is ready.
} }
void WVDrmPlugin::OnExpirationUpdate(const CdmSessionId& cdmSessionId, void WVDrmPlugin::OnExpirationUpdate(const CdmSessionId& cdmSessionId,
int64_t new_expiry_time) { int64_t newExpiryTime) {
// TODO(kqyang): Glue with DrmPlugin API when it is ready. Note that Vector<uint8_t> sessionId = ToVector(cdmSessionId);
// new_expiry_time is in seconds while Android API is in milliseconds. sendExpirationUpdate(&sessionId, newExpiryTime * 1000);
} }
status_t WVDrmPlugin::queryProperty(const std::string& property, status_t WVDrmPlugin::queryProperty(const std::string& property,

View File

@@ -113,6 +113,9 @@ class MockDrmPluginListener : public DrmPluginListener {
public: public:
MOCK_METHOD4(sendEvent, void(DrmPlugin::EventType, int, MOCK_METHOD4(sendEvent, void(DrmPlugin::EventType, int,
const Vector<uint8_t>*, const Vector<uint8_t>*)); const Vector<uint8_t>*, const Vector<uint8_t>*));
MOCK_METHOD2(sendExpirationUpdate, void(const Vector<uint8_t>*, int64_t));
MOCK_METHOD3(sendKeysChange, void(const Vector<uint8_t>*,
const Vector<DrmPlugin::KeyStatus>*, bool));
}; };
template <uint8_t DIGIT> template <uint8_t DIGIT>
@@ -1191,27 +1194,77 @@ TEST_F(WVDrmPluginTest, MarshalsEvents) {
sp<StrictMock<MockDrmPluginListener> > listener = sp<StrictMock<MockDrmPluginListener> > listener =
new StrictMock<MockDrmPluginListener>(); new StrictMock<MockDrmPluginListener>();
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; InSequence calls;
EXPECT_CALL(*listener, sendEvent(DrmPlugin::kDrmPluginEventKeyExpired, 0, EXPECT_CALL(*listener,
Pointee(ElementsAreArray(sessionIdRaw, sendKeysChange(
kSessionIdSize)), Pointee(ElementsAreArray(sessionIdRaw, kSessionIdSize)),
NULL)) Pointee(UnorderedElementsAre(AllOf(
.Times(1); Field(&DrmPlugin::KeyStatus::mKeyId,
ElementsAreArray(kKeyId1, sizeof(kKeyId1) - 1)),
EXPECT_CALL(*listener, sendEvent(DrmPlugin::kDrmPluginEventKeyNeeded, 0, Field(&DrmPlugin::KeyStatus::mType,
Pointee(ElementsAreArray(sessionIdRaw, DrmPlugin::kKeyStatusType_Expired)))),
kSessionIdSize)), false));
NULL)) EXPECT_CALL(
.Times(1); *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); status_t res = plugin.setListener(listener);
ASSERT_EQ(OK, res); ASSERT_EQ(OK, res);
plugin.OnSessionExpiration(cdmSessionId); CdmKeyStatusMap cdmKeysStatus;
cdmKeysStatus[kKeyId1] = kKeyStatusExpired;
plugin.OnSessionKeysChange(cdmSessionId, cdmKeysStatus, false);
plugin.OnSessionRenewalNeeded(cdmSessionId); 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) { TEST_F(WVDrmPluginTest, GeneratesProvisioningNeededEvent) {