Merge "Replace generic OnEvent with actual event callbacks"

This commit is contained in:
KongQun Yang
2015-03-30 17:35:23 +00:00
committed by Android (Google) Code Review
15 changed files with 371 additions and 463 deletions

View File

@@ -16,12 +16,14 @@ using video_widevine_server::sdk::LicenseIdentification;
class Clock; class Clock;
class CryptoSession; class CryptoSession;
class WvCdmEventListener;
// This acts as an oracle that basically says "Yes(true) you may still decrypt // This acts as an oracle that basically says "Yes(true) you may still decrypt
// or no(false) you may not decrypt this data anymore." // or no(false) you may not decrypt this data anymore."
class PolicyEngine { class PolicyEngine {
public: public:
explicit PolicyEngine(CryptoSession* crypto_session); PolicyEngine(CdmSessionId session_id, WvCdmEventListener* event_listener,
CryptoSession* crypto_session);
virtual ~PolicyEngine(); virtual ~PolicyEngine();
// The value returned should be taken as a hint rather than an absolute // The value returned should be taken as a hint rather than an absolute
@@ -32,11 +34,9 @@ class PolicyEngine {
virtual bool CanDecrypt(const KeyId& key_id); virtual bool CanDecrypt(const KeyId& key_id);
// OnTimerEvent is called when a timer fires. It notifies the Policy Engine // OnTimerEvent is called when a timer fires. It notifies the Policy Engine
// that the timer has fired and that it should check whether any events have // that the timer has fired and dispatches the relevant events through
// occurred since the last timer event. If so, it sets event_occurred to true // |event_listener_|.
// and sets event to point to the event that occurred. If not, it sets virtual void OnTimerEvent();
// event_occurred to false.
virtual void OnTimerEvent(bool* event_occurred, CdmEventType* event);
// SetLicense is used in handling the initial license response. It stores // SetLicense is used in handling the initial license response. It stores
// an exact copy of the policy information stored in the license. // an exact copy of the policy information stored in the license.
@@ -126,6 +126,10 @@ class PolicyEngine {
int64_t next_renewal_time_; int64_t next_renewal_time_;
int64_t policy_max_duration_seconds_; int64_t policy_max_duration_seconds_;
// Used to dispatch CDM events.
CdmSessionId session_id_;
WvCdmEventListener* event_listener_;
MaxResEngine max_res_engine_; MaxResEngine max_res_engine_;
scoped_ptr<Clock> clock_; scoped_ptr<Clock> clock_;

View File

@@ -13,8 +13,8 @@ class WvCdmEventListener {
WvCdmEventListener() {} WvCdmEventListener() {}
virtual ~WvCdmEventListener() {} virtual ~WvCdmEventListener() {}
virtual void OnEvent(const CdmSessionId& session_id, virtual void OnSessionRenewalNeeded(const CdmSessionId& session_id) = 0;
CdmEventType cdm_event) = 0; virtual void OnSessionExpiration(const CdmSessionId& session_id) = 0;
private: private:
CORE_DISALLOW_COPY_AND_ASSIGN(WvCdmEventListener); CORE_DISALLOW_COPY_AND_ASSIGN(WvCdmEventListener);

View File

@@ -53,11 +53,6 @@ enum CdmResponseType {
TypeName(const TypeName&); \ TypeName(const TypeName&); \
void operator=(const TypeName&) void operator=(const TypeName&)
enum CdmEventType {
LICENSE_EXPIRED_EVENT,
LICENSE_RENEWAL_NEEDED_EVENT
};
enum CdmLicenseType { enum CdmLicenseType {
kLicenseTypeOffline, kLicenseTypeOffline,
kLicenseTypeStreaming, kLicenseTypeStreaming,

View File

@@ -30,7 +30,8 @@ CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set,
event_listener_(event_listener), event_listener_(event_listener),
license_parser_(new CdmLicense), license_parser_(new CdmLicense),
crypto_session_(new CryptoSession), crypto_session_(new CryptoSession),
policy_engine_(new PolicyEngine(crypto_session_.get())), policy_engine_(new PolicyEngine(session_id_, event_listener_,
crypto_session_.get())),
file_handle_(new DeviceFiles), file_handle_(new DeviceFiles),
license_received_(false), license_received_(false),
is_offline_(false), is_offline_(false),
@@ -519,9 +520,6 @@ void CdmSession::NotifyResolution(uint32_t width, uint32_t height) {
} }
void CdmSession::OnTimerEvent(bool update_usage) { void CdmSession::OnTimerEvent(bool update_usage) {
bool event_occurred = false;
CdmEventType event;
if (update_usage && has_decrypted_since_last_report_) { if (update_usage && has_decrypted_since_last_report_) {
policy_engine_->DecryptionEvent(); policy_engine_->DecryptionEvent();
has_decrypted_since_last_report_ = false; has_decrypted_since_last_report_ = false;
@@ -529,17 +527,12 @@ void CdmSession::OnTimerEvent(bool update_usage) {
StoreLicense(DeviceFiles::kLicenseStateActive); StoreLicense(DeviceFiles::kLicenseStateActive);
} }
} }
policy_engine_->OnTimerEvent(&event_occurred, &event); policy_engine_->OnTimerEvent();
if (event_occurred) {
if (event_listener_) event_listener_->OnEvent(session_id_, event);
}
} }
void CdmSession::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) { void CdmSession::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
if (key_set_id_ == key_set_id) { if (key_set_id_ == key_set_id) {
if (event_listener_) if (event_listener_) event_listener_->OnSessionExpiration(session_id_);
event_listener_->OnEvent(session_id_, LICENSE_EXPIRED_EVENT);
} }
} }

View File

@@ -13,10 +13,13 @@
#include "properties.h" #include "properties.h"
#include "string_conversions.h" #include "string_conversions.h"
#include "wv_cdm_constants.h" #include "wv_cdm_constants.h"
#include "wv_cdm_event_listener.h"
namespace wvcdm { namespace wvcdm {
PolicyEngine::PolicyEngine(CryptoSession* crypto_session) PolicyEngine::PolicyEngine(CdmSessionId session_id,
WvCdmEventListener* event_listener,
CryptoSession* crypto_session)
: license_state_(kLicenseStateInitial), : license_state_(kLicenseStateInitial),
can_decrypt_(false), can_decrypt_(false),
license_start_time_(0), license_start_time_(0),
@@ -24,6 +27,8 @@ PolicyEngine::PolicyEngine(CryptoSession* crypto_session)
last_playback_time_(0), last_playback_time_(0),
next_renewal_time_(0), next_renewal_time_(0),
policy_max_duration_seconds_(0), policy_max_duration_seconds_(0),
session_id_(session_id),
event_listener_(event_listener),
max_res_engine_(crypto_session), max_res_engine_(crypto_session),
clock_(new Clock) {} clock_(new Clock) {}
@@ -33,8 +38,7 @@ bool PolicyEngine::CanDecrypt(const KeyId& key_id) {
return can_decrypt_ && max_res_engine_.CanDecrypt(key_id); return can_decrypt_ && max_res_engine_.CanDecrypt(key_id);
} }
void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) { void PolicyEngine::OnTimerEvent() {
*event_occurred = false;
int64_t current_time = clock_->GetCurrentTime(); int64_t current_time = clock_->GetCurrentTime();
// License expiration trumps all. // License expiration trumps all.
@@ -43,8 +47,7 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
license_state_ != kLicenseStateExpired) { license_state_ != kLicenseStateExpired) {
license_state_ = kLicenseStateExpired; license_state_ = kLicenseStateExpired;
can_decrypt_ = false; can_decrypt_ = false;
*event = LICENSE_EXPIRED_EVENT; if (event_listener_) event_listener_->OnSessionExpiration(session_id_);
*event_occurred = true;
return; return;
} }
@@ -89,8 +92,7 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
if (renewal_needed) { if (renewal_needed) {
UpdateRenewalRequest(current_time); UpdateRenewalRequest(current_time);
*event = LICENSE_RENEWAL_NEEDED_EVENT; if (event_listener_) event_listener_->OnSessionRenewalNeeded(session_id_);
*event_occurred = true;
} }
max_res_engine_.OnTimerEvent(); max_res_engine_.OnTimerEvent();

View File

@@ -114,7 +114,7 @@ class MockCryptoSession : public CryptoSession {
class MockPolicyEngine : public PolicyEngine { class MockPolicyEngine : public PolicyEngine {
public: public:
MockPolicyEngine() : PolicyEngine(NULL) {} MockPolicyEngine() : PolicyEngine("mock_session_id", NULL, NULL) {}
// Leaving a place-holder for when PolicyEngine methods need to be mocked // Leaving a place-holder for when PolicyEngine methods need to be mocked
}; };

View File

@@ -105,7 +105,8 @@ class MockCryptoSession : public CryptoSession {
class MockPolicyEngine : public PolicyEngine { class MockPolicyEngine : public PolicyEngine {
public: public:
MockPolicyEngine(CryptoSession* crypto) : PolicyEngine(crypto) {} MockPolicyEngine(CryptoSession* crypto)
: PolicyEngine("mock_session_id", NULL, crypto) {}
}; };
class MockClock : public Clock { class MockClock : public Clock {

File diff suppressed because it is too large Load Diff

View File

@@ -34,18 +34,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
} }
} }
void PrintTo(const enum CdmEventType& value, ::std::ostream* os) {
switch (value) {
case LICENSE_EXPIRED_EVENT: *os << "LICENSE_EXPIRED_EVENT";
break;
case LICENSE_RENEWAL_NEEDED_EVENT: *os << "LICENSE_RENEWAL_NEEDED_EVENT";
break;
default:
*os << "Unknown CdmEventType";
break;
}
};
void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) { void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) {
switch (value) { switch (value) {
case kLicenseTypeOffline: *os << "kLicenseTypeOffline"; case kLicenseTypeOffline: *os << "kLicenseTypeOffline";

View File

@@ -10,7 +10,6 @@
namespace wvcdm { namespace wvcdm {
void PrintTo(const enum CdmResponseType& value, ::std::ostream* os); void PrintTo(const enum CdmResponseType& value, ::std::ostream* os);
void PrintTo(const enum CdmEventType& value, ::std::ostream* os);
void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os); void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os);
void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os); void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os);
void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os); void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os);

View File

@@ -243,21 +243,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
uint32_t session_sharing_id_; uint32_t session_sharing_id_;
}; };
class TestWvCdmEventListener : public WvCdmEventListener {
public:
TestWvCdmEventListener() : WvCdmEventListener() {}
virtual void OnEvent(const CdmSessionId& id, CdmEventType event) {
session_id_ = id;
event_type_ = event;
}
CdmSessionId session_id() { return session_id_; }
CdmEventType event_type() { return event_type_; }
private:
CdmSessionId session_id_;
CdmEventType event_type_;
};
class WvCdmExtendedDurationTest : public WvCdmTestBase { class WvCdmExtendedDurationTest : public WvCdmTestBase {
public: public:
WvCdmExtendedDurationTest() {} WvCdmExtendedDurationTest() {}

View File

@@ -4,6 +4,7 @@
#include <getopt.h> #include <getopt.h>
#include <sstream> #include <sstream>
#include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "config_test_env.h" #include "config_test_env.h"
@@ -440,16 +441,9 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
class TestWvCdmEventListener : public WvCdmEventListener { class TestWvCdmEventListener : public WvCdmEventListener {
public: public:
TestWvCdmEventListener() : WvCdmEventListener() {} TestWvCdmEventListener() : WvCdmEventListener() {}
virtual void OnEvent(const CdmSessionId& id, CdmEventType event) {
session_id_ = id;
event_type_ = event;
}
CdmSessionId session_id() { return session_id_; }
CdmEventType event_type() { return event_type_; }
private: MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id));
CdmSessionId session_id_; MOCK_METHOD1(OnSessionExpiration, void(const CdmSessionId& session_id));
CdmEventType event_type_;
}; };
class WvCdmRequestLicenseTest : public WvCdmTestBase { class WvCdmRequestLicenseTest : public WvCdmTestBase {
@@ -1160,7 +1154,7 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
session_id_.clear(); session_id_.clear();
key_set_id_.clear(); key_set_id_.clear();
TestWvCdmEventListener listener; ::testing::StrictMock<TestWvCdmEventListener> listener;
decryptor_.OpenSession(g_key_system, NULL, &listener, &session_id_); decryptor_.OpenSession(g_key_system, NULL, &listener, &session_id_);
CdmSessionId restore_session_id = session_id_; CdmSessionId restore_session_id = session_id_;
EXPECT_EQ(wvcdm::KEY_ADDED, EXPECT_EQ(wvcdm::KEY_ADDED,
@@ -1168,12 +1162,12 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
session_id_.clear(); session_id_.clear();
key_set_id_.clear(); key_set_id_.clear();
EXPECT_TRUE(listener.session_id().size() == 0); // Maybe called since VerifyKeyRequestResponse could take some time.
EXPECT_CALL(listener, OnSessionRenewalNeeded(restore_session_id))
.Times(::testing::AtLeast(0));
EXPECT_CALL(listener, OnSessionExpiration(restore_session_id)).Times(1);
GenerateKeyRelease(key_set_id); GenerateKeyRelease(key_set_id);
key_set_id_ = key_set_id; key_set_id_ = key_set_id;
EXPECT_TRUE(listener.session_id().size() != 0);
EXPECT_TRUE(listener.session_id().compare(restore_session_id) == 0);
EXPECT_TRUE(listener.event_type() == LICENSE_EXPIRED_EVENT);
VerifyKeyRequestResponse(g_license_server, client_auth, false); VerifyKeyRequestResponse(g_license_server, client_auth, false);
decryptor_.CloseSession(restore_session_id); decryptor_.CloseSession(restore_session_id);
} }

View File

@@ -32,7 +32,6 @@ using android::status_t;
using android::String8; using android::String8;
using android::Vector; using android::Vector;
using std::map; using std::map;
using wvcdm::CdmEventType;
using wvcdm::CdmSessionId; using wvcdm::CdmSessionId;
using wvcdm::CdmResponseType; using wvcdm::CdmResponseType;
using wvcdm::WvContentDecryptionModule; using wvcdm::WvContentDecryptionModule;
@@ -140,8 +139,9 @@ class WVDrmPlugin : public android::DrmPlugin,
const Vector<uint8_t>& wrappedKey, const Vector<uint8_t>& wrappedKey,
Vector<uint8_t>& signature); Vector<uint8_t>& signature);
virtual void OnEvent(const CdmSessionId& cdmSessionId, virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId);
CdmEventType cdmEventType);
virtual void OnSessionExpiration(const CdmSessionId& cdmSessionId);
private: private:
DISALLOW_EVIL_CONSTRUCTORS(WVDrmPlugin); DISALLOW_EVIL_CONSTRUCTORS(WVDrmPlugin);

View File

@@ -940,25 +940,18 @@ status_t WVDrmPlugin::signRSA(const Vector<uint8_t>& /* sessionId */,
return android::OK; return android::OK;
} }
void WVDrmPlugin::OnEvent(const CdmSessionId& cdmSessionId, void WVDrmPlugin::OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId) {
CdmEventType cdmEventType) {
Vector<uint8_t> sessionId; Vector<uint8_t> sessionId;
EventType eventType = kDrmPluginEventVendorDefined;
switch (cdmEventType) {
case LICENSE_EXPIRED_EVENT:
eventType = kDrmPluginEventKeyExpired;
break;
case LICENSE_RENEWAL_NEEDED_EVENT:
eventType = kDrmPluginEventKeyNeeded;
break;
}
sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()), sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()),
cdmSessionId.size()); cdmSessionId.size());
sendEvent(kDrmPluginEventKeyNeeded, 0, &sessionId, NULL);
}
// Call base-class method with translated event. void WVDrmPlugin::OnSessionExpiration(const CdmSessionId& cdmSessionId) {
sendEvent(eventType, 0, &sessionId, NULL); Vector<uint8_t> sessionId;
sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()),
cdmSessionId.size());
sendEvent(kDrmPluginEventKeyExpired, 0, &sessionId, NULL);
} }
status_t WVDrmPlugin::mapAndNotifyOfCdmResponseType( status_t WVDrmPlugin::mapAndNotifyOfCdmResponseType(

View File

@@ -1200,8 +1200,8 @@ TEST_F(WVDrmPluginTest, MarshalsEvents) {
status_t res = plugin.setListener(listener); status_t res = plugin.setListener(listener);
ASSERT_EQ(OK, res); ASSERT_EQ(OK, res);
plugin.OnEvent(cdmSessionId, LICENSE_EXPIRED_EVENT); plugin.OnSessionExpiration(cdmSessionId);
plugin.OnEvent(cdmSessionId, LICENSE_RENEWAL_NEEDED_EVENT); plugin.OnSessionRenewalNeeded(cdmSessionId);
} }
TEST_F(WVDrmPluginTest, GeneratesProvisioningNeededEvent) { TEST_F(WVDrmPluginTest, GeneratesProvisioningNeededEvent) {