Generate renewal and expiry events

The android timer class was not generating timer events correctly. This caused
renewal and expiration events not to be sent. A strong pointer to the
timer thread was not held and this caused the android util timer
thread to exit after firing once. This is now addressed.

Bug: 8736545

Merge of https://widevine-internal-review.googlesource.com/#/c/5353/
from the Widevine CDM repository.

Change-Id: I2d904e55d4d10eacc1a51f1c6b5c1a267c92c8d8
This commit is contained in:
Jeff Tinker
2013-05-02 16:42:04 -07:00
parent cb5541b740
commit 3cfb86cea1
6 changed files with 111 additions and 18 deletions

View File

@@ -34,7 +34,7 @@ class Timer {
Timer(); Timer();
~Timer(); ~Timer();
void Start(TimerHandler *handler, uint32_t time_in_secs); bool Start(TimerHandler *handler, uint32_t time_in_secs);
void Stop(); void Stop();
bool IsRunning(); bool IsRunning();

View File

@@ -101,6 +101,8 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
} }
sessions_.erase(session_id); sessions_.erase(session_id);
if (sessions_.size() == 0)
DisablePolicyTimer();
iter->second->DestroySession(); iter->second->DestroySession();
delete iter->second; delete iter->second;
return NO_ERROR; return NO_ERROR;

View File

@@ -0,0 +1,54 @@
// Copyright 2013 Google Inc. All Rights Reserved.
#include "gtest/gtest.h"
#include "timer.h"
namespace wvcdm {
class TestTimerHandler : public TimerHandler {
public:
TestTimerHandler() : timer_events_(0) {};
virtual ~TestTimerHandler() {};
virtual void OnTimerEvent() {
timer_events_++;
}
uint32_t GetTimerEvents() { return timer_events_; }
void ResetTimerEvents() { timer_events_ = 0; }
private:
uint32_t timer_events_;
};
TEST(TimerTest, ParametersCheck) {
Timer timer;
EXPECT_FALSE(timer.Start(NULL, 10));
TestTimerHandler handler;
EXPECT_FALSE(timer.Start(&handler, 0));
}
TEST(TimerTest, TimerCheck) {
TestTimerHandler handler;
Timer timer;
uint32_t duration = 10;
EXPECT_EQ(static_cast<uint32_t>(0), handler.GetTimerEvents());
EXPECT_FALSE(timer.IsRunning());
EXPECT_TRUE(timer.Start(&handler, 1));
EXPECT_TRUE(timer.IsRunning());
sleep(duration);
EXPECT_TRUE(duration-1 <= handler.GetTimerEvents());
EXPECT_TRUE(handler.GetTimerEvents() <= duration+1);
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
sleep(duration);
EXPECT_TRUE(duration-1 <= handler.GetTimerEvents());
EXPECT_TRUE(handler.GetTimerEvents() <= duration+1);
}
}

View File

@@ -5,19 +5,23 @@
#include <unistd.h> #include <unistd.h>
#include "timer.h" #include "timer.h"
#include "utils/RefBase.h"
#include "utils/StrongPointer.h"
#include "utils/Thread.h" #include "utils/Thread.h"
namespace wvcdm { namespace wvcdm {
class Timer::Impl : public android::Thread { class Timer::Impl : virtual public android::RefBase {
private:
class ImplThread : public android::Thread {
public: public:
Impl() : Thread(false), handler_(NULL), period_(0) {} ImplThread() : Thread(false), handler_(NULL), period_(0) {}
virtual ~Impl() {}; virtual ~ImplThread() {};
void Start(TimerHandler *handler, uint32_t time_in_secs) { bool Start(TimerHandler *handler, uint32_t time_in_secs) {
handler_ = handler; handler_ = handler;
period_ = time_in_secs; period_ = time_in_secs;
run(); return run() == android::NO_ERROR;
} }
private: private:
@@ -29,6 +33,31 @@ class Timer::Impl : public android::Thread {
TimerHandler *handler_; TimerHandler *handler_;
uint32_t period_; uint32_t period_;
CORE_DISALLOW_COPY_AND_ASSIGN(ImplThread);
};
android::sp<ImplThread> impl_thread_;
public:
Impl() {}
virtual ~Impl() {};
bool Start(TimerHandler *handler, uint32_t time_in_secs) {
impl_thread_ = new ImplThread();
return impl_thread_->Start(handler, time_in_secs);
}
void Stop() {
impl_thread_->requestExitAndWait();
impl_thread_.clear();
}
bool IsRunning() {
return (impl_thread_ != NULL) && (impl_thread_->isRunning());
}
CORE_DISALLOW_COPY_AND_ASSIGN(Impl);
}; };
Timer::Timer() : impl_(new Timer::Impl()) { Timer::Timer() : impl_(new Timer::Impl()) {
@@ -42,16 +71,19 @@ Timer::~Timer() {
impl_ = NULL; impl_ = NULL;
} }
void Timer::Start(TimerHandler *handler, uint32_t time_in_secs) { bool Timer::Start(TimerHandler *handler, uint32_t time_in_secs) {
impl_->Start(handler, time_in_secs); if (!handler || time_in_secs == 0)
return false;
return impl_->Start(handler, time_in_secs);
} }
void Timer::Stop() { void Timer::Stop() {
impl_->requestExitAndWait(); impl_->Stop();
} }
bool Timer::IsRunning() { bool Timer::IsRunning() {
return impl_->getTid() < 0; return impl_->IsRunning();
} }
} // namespace wvcdm } // namespace wvcdm

View File

@@ -35,5 +35,9 @@ test_name := request_license_test
test_src_dir := . test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk include $(LOCAL_PATH)/unit-test.mk
test_name := timer_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := test_name :=
test_src_dir := test_src_dir :=

View File

@@ -16,6 +16,7 @@ adb shell /system/bin/cdm_engine_test
adb shell /system/bin/oemcrypto_test adb shell /system/bin/oemcrypto_test
adb shell /system/bin/file_store_unittest adb shell /system/bin/file_store_unittest
adb shell /system/bin/device_files_unittest adb shell /system/bin/device_files_unittest
adb shell /system/bin/timer_unittest
adb shell LD_LIBRARY_PATH=/system/vendor/lib/mediadrm/ /system/bin/libwvdrmengine_test adb shell LD_LIBRARY_PATH=/system/vendor/lib/mediadrm/ /system/bin/libwvdrmengine_test
adb shell am start com.widevine.test/com.widevine.test.MediaDrmAPITest adb shell am start com.widevine.test/com.widevine.test.MediaDrmAPITest