|
|
|
|
@@ -35,7 +35,7 @@ static double GetCurrentTime() {
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
tv.tv_sec = tv.tv_usec = 0;
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
return tv.tv_sec;
|
|
|
|
|
return tv.tv_sec + (tv.tv_usec / (1000.0 * 1000.0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// These classes below are naive implementation of the abstract classes defined
|
|
|
|
|
@@ -111,6 +111,7 @@ class TestHost : public cdm::Host {
|
|
|
|
|
void FastForwardTime(double seconds);
|
|
|
|
|
int KeyMessagesSize() const;
|
|
|
|
|
int KeyErrorsSize() const;
|
|
|
|
|
int NumTimers() const;
|
|
|
|
|
|
|
|
|
|
// Returns Key{Message,Error} (replace Message with Error for KeyError). It
|
|
|
|
|
// returns the most recent message passed to SendKeyMessage(). Another call
|
|
|
|
|
@@ -130,7 +131,9 @@ class TestHost : public cdm::Host {
|
|
|
|
|
: expiry_time(expiry_time), context(context) {}
|
|
|
|
|
|
|
|
|
|
bool operator<(const Timer& other) const {
|
|
|
|
|
return expiry_time < other.expiry_time;
|
|
|
|
|
// We want to reverse the order so that the smallest expiry times go to
|
|
|
|
|
// the top of the priority queue.
|
|
|
|
|
return expiry_time > other.expiry_time;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double expiry_time;
|
|
|
|
|
@@ -235,6 +238,7 @@ void TestHost::FastForwardTime(double seconds) {
|
|
|
|
|
} else {
|
|
|
|
|
Timer t = timers_.top();
|
|
|
|
|
timers_.pop();
|
|
|
|
|
ASSERT_GE(t.expiry_time, current_time_);
|
|
|
|
|
current_time_ = t.expiry_time;
|
|
|
|
|
cdm_->TimerExpired(t.context);
|
|
|
|
|
}
|
|
|
|
|
@@ -255,6 +259,8 @@ int TestHost::KeyMessagesSize() const { return key_messages_.size(); }
|
|
|
|
|
|
|
|
|
|
int TestHost::KeyErrorsSize() const { return key_errors_.size(); }
|
|
|
|
|
|
|
|
|
|
int TestHost::NumTimers() const { return timers_.size(); }
|
|
|
|
|
|
|
|
|
|
TestHost::KeyMessage TestHost::GetLastKeyMessage() {
|
|
|
|
|
if (!has_new_key_message_) {
|
|
|
|
|
LOGD("No NEW");
|
|
|
|
|
@@ -289,6 +295,9 @@ TestHost::KeyError TestHost::GetKeyError(int index) const {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestHost::SetCdmPtr(cdm::ContentDecryptionModule* cdm) {
|
|
|
|
|
if (cdm_) {
|
|
|
|
|
cdm_->Destroy();
|
|
|
|
|
}
|
|
|
|
|
cdm_ = cdm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -959,6 +968,113 @@ class WvCdmApiTest : public testing::Test {
|
|
|
|
|
scoped_ptr<TestHost> host_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DummyCDM : public cdm::ContentDecryptionModule {
|
|
|
|
|
public:
|
|
|
|
|
DummyCDM()
|
|
|
|
|
: timer_fired_(false),
|
|
|
|
|
last_context_(NULL) {}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status GenerateKeyRequest(const char*, int, const uint8_t*, int)
|
|
|
|
|
OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status AddKey(const char*, int, const uint8_t*, int,
|
|
|
|
|
const uint8_t*, int) OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual bool IsKeyValid(const uint8_t*, int) OVERRIDE {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status CancelKeyRequest(const char*, int) OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void TimerExpired(void* context) OVERRIDE {
|
|
|
|
|
timer_fired_ = true;
|
|
|
|
|
last_context_ = context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status Decrypt(const cdm::InputBuffer&, cdm::DecryptedBlock*)
|
|
|
|
|
OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status DecryptDecodeAndRenderFrame(const cdm::InputBuffer&)
|
|
|
|
|
OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status DecryptDecodeAndRenderSamples(const cdm::InputBuffer&)
|
|
|
|
|
OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void Destroy() OVERRIDE {
|
|
|
|
|
delete this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status GetProvisioningRequest(std::string*, std::string*)
|
|
|
|
|
OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual cdm::Status HandleProvisioningResponse(std::string&) OVERRIDE {
|
|
|
|
|
return cdm::kSessionError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TimerFired() const {
|
|
|
|
|
return timer_fired_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* LastTimerContext() const {
|
|
|
|
|
return last_context_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ResetTimerStatus() {
|
|
|
|
|
timer_fired_ = false;
|
|
|
|
|
last_context_ = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool timer_fired_;
|
|
|
|
|
void* last_context_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(WvCdmApiTest, TestHostTimer) {
|
|
|
|
|
// Validate that the TestHost timers are processed in the correct order.
|
|
|
|
|
// To do this, we replace the cdm with a dummy that only tracks timers.
|
|
|
|
|
DummyCDM* cdm = new DummyCDM();
|
|
|
|
|
|
|
|
|
|
// The old CDM is destroyed by SetCdmPtr.
|
|
|
|
|
cdm_ = cdm;
|
|
|
|
|
host_->SetCdmPtr(cdm);
|
|
|
|
|
|
|
|
|
|
const double kTimerDelaySeconds = 1.0;
|
|
|
|
|
const int64_t kTimerDelayMs = kTimerDelaySeconds * 1000;
|
|
|
|
|
void* kCtx1 = reinterpret_cast<void*>(0x1);
|
|
|
|
|
void* kCtx2 = reinterpret_cast<void*>(0x2);
|
|
|
|
|
|
|
|
|
|
host_->SetTimer(kTimerDelayMs * 1, kCtx1);
|
|
|
|
|
host_->SetTimer(kTimerDelayMs * 2, kCtx2);
|
|
|
|
|
|
|
|
|
|
host_->FastForwardTime(kTimerDelaySeconds);
|
|
|
|
|
EXPECT_TRUE(cdm->TimerFired());
|
|
|
|
|
EXPECT_EQ(kCtx1, cdm->LastTimerContext());
|
|
|
|
|
cdm->ResetTimerStatus();
|
|
|
|
|
|
|
|
|
|
host_->FastForwardTime(kTimerDelaySeconds);
|
|
|
|
|
EXPECT_TRUE(cdm->TimerFired());
|
|
|
|
|
EXPECT_EQ(kCtx2, cdm->LastTimerContext());
|
|
|
|
|
cdm->ResetTimerStatus();
|
|
|
|
|
|
|
|
|
|
host_->FastForwardTime(kTimerDelaySeconds);
|
|
|
|
|
EXPECT_FALSE(cdm->TimerFired());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note that these tests, BaseMessageTest, NormalDecryption and TimeTest,
|
|
|
|
|
// are dependent on getting back a license from the license server where the
|
|
|
|
|
// url for the license server is defined in the conf_test_env.cpp. If these
|
|
|
|
|
@@ -966,7 +1082,6 @@ class WvCdmApiTest : public testing::Test {
|
|
|
|
|
// and works in your test environment.
|
|
|
|
|
|
|
|
|
|
TEST_F(WvCdmApiTest, DeviceCertificateTest) {
|
|
|
|
|
host_->SetPlatformString("DeviceCertificate", "");
|
|
|
|
|
GenerateKeyRequest(g_key_system, g_key_id); // It will have to provision -
|
|
|
|
|
// in here.
|
|
|
|
|
TestHost::KeyMessage key_msg = host_->GetLastKeyMessage();
|
|
|
|
|
@@ -1027,6 +1142,9 @@ TEST_F(WvCdmApiTest, TimeTest) {
|
|
|
|
|
std::string drm_msg = GetKeyRequestResponse(g_license_server,
|
|
|
|
|
g_client_auth, 200);
|
|
|
|
|
AddKey(key_msg.session_id, drm_msg);
|
|
|
|
|
// We expect that by the time we've added a key, the CDM has set a timer.
|
|
|
|
|
// Otherwise, it couldn't correctly handle renewal.
|
|
|
|
|
EXPECT_NE(0, host_->NumTimers());
|
|
|
|
|
|
|
|
|
|
host_->FastForwardTime(kTestPolicyRenewalDelaySeconds +
|
|
|
|
|
kDelayWaitToForRenewalMessageSeconds);
|
|
|
|
|
|