From 3cfb86cea16083758a02accbecb707216d611f16 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Thu, 2 May 2013 16:42:04 -0700 Subject: [PATCH] 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 --- libwvdrmengine/cdm/core/include/timer.h | 2 +- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 2 + .../cdm/core/test/timer_unittest.cpp | 54 +++++++++++++++ libwvdrmengine/cdm/src/timer.cpp | 66 ++++++++++++++----- libwvdrmengine/cdm/test/Android.mk | 4 ++ libwvdrmengine/run_all_unit_tests.sh | 1 + 6 files changed, 111 insertions(+), 18 deletions(-) create mode 100644 libwvdrmengine/cdm/core/test/timer_unittest.cpp diff --git a/libwvdrmengine/cdm/core/include/timer.h b/libwvdrmengine/cdm/core/include/timer.h index 4baa2330..8458b1d0 100644 --- a/libwvdrmengine/cdm/core/include/timer.h +++ b/libwvdrmengine/cdm/core/include/timer.h @@ -34,7 +34,7 @@ class Timer { Timer(); ~Timer(); - void Start(TimerHandler *handler, uint32_t time_in_secs); + bool Start(TimerHandler *handler, uint32_t time_in_secs); void Stop(); bool IsRunning(); diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 2a5c5493..aa8c4714 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -101,6 +101,8 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { } sessions_.erase(session_id); + if (sessions_.size() == 0) + DisablePolicyTimer(); iter->second->DestroySession(); delete iter->second; return NO_ERROR; diff --git a/libwvdrmengine/cdm/core/test/timer_unittest.cpp b/libwvdrmengine/cdm/core/test/timer_unittest.cpp new file mode 100644 index 00000000..df41b8b1 --- /dev/null +++ b/libwvdrmengine/cdm/core/test/timer_unittest.cpp @@ -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(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); +} + +} diff --git a/libwvdrmengine/cdm/src/timer.cpp b/libwvdrmengine/cdm/src/timer.cpp index 8e5028dd..88bd10d3 100644 --- a/libwvdrmengine/cdm/src/timer.cpp +++ b/libwvdrmengine/cdm/src/timer.cpp @@ -5,30 +5,59 @@ #include #include "timer.h" +#include "utils/RefBase.h" +#include "utils/StrongPointer.h" #include "utils/Thread.h" namespace wvcdm { -class Timer::Impl : public android::Thread { +class Timer::Impl : virtual public android::RefBase { + private: + class ImplThread : public android::Thread { + public: + ImplThread() : Thread(false), handler_(NULL), period_(0) {} + virtual ~ImplThread() {}; + + bool Start(TimerHandler *handler, uint32_t time_in_secs) { + handler_ = handler; + period_ = time_in_secs; + return run() == android::NO_ERROR; + } + + private: + virtual bool threadLoop() { + sleep(period_); + handler_->OnTimerEvent(); + return true; + } + + TimerHandler *handler_; + uint32_t period_; + + CORE_DISALLOW_COPY_AND_ASSIGN(ImplThread); + }; + + android::sp impl_thread_; + public: - Impl() : Thread(false), handler_(NULL), period_(0) {} + Impl() {} virtual ~Impl() {}; - void Start(TimerHandler *handler, uint32_t time_in_secs) { - handler_ = handler; - period_ = time_in_secs; - run(); + bool Start(TimerHandler *handler, uint32_t time_in_secs) { + impl_thread_ = new ImplThread(); + return impl_thread_->Start(handler, time_in_secs); } - private: - virtual bool threadLoop() { - sleep(period_); - handler_->OnTimerEvent(); - return true; + void Stop() { + impl_thread_->requestExitAndWait(); + impl_thread_.clear(); } - TimerHandler *handler_; - uint32_t period_; + bool IsRunning() { + return (impl_thread_ != NULL) && (impl_thread_->isRunning()); + } + + CORE_DISALLOW_COPY_AND_ASSIGN(Impl); }; Timer::Timer() : impl_(new Timer::Impl()) { @@ -42,16 +71,19 @@ Timer::~Timer() { impl_ = NULL; } -void Timer::Start(TimerHandler *handler, uint32_t time_in_secs) { - impl_->Start(handler, time_in_secs); +bool Timer::Start(TimerHandler *handler, uint32_t time_in_secs) { + if (!handler || time_in_secs == 0) + return false; + + return impl_->Start(handler, time_in_secs); } void Timer::Stop() { - impl_->requestExitAndWait(); + impl_->Stop(); } bool Timer::IsRunning() { - return impl_->getTid() < 0; + return impl_->IsRunning(); } } // namespace wvcdm diff --git a/libwvdrmengine/cdm/test/Android.mk b/libwvdrmengine/cdm/test/Android.mk index 0ef4c20a..03f2e1ae 100644 --- a/libwvdrmengine/cdm/test/Android.mk +++ b/libwvdrmengine/cdm/test/Android.mk @@ -35,5 +35,9 @@ test_name := request_license_test test_src_dir := . include $(LOCAL_PATH)/unit-test.mk +test_name := timer_unittest +test_src_dir := ../core/test +include $(LOCAL_PATH)/unit-test.mk + test_name := test_src_dir := diff --git a/libwvdrmengine/run_all_unit_tests.sh b/libwvdrmengine/run_all_unit_tests.sh index c5f156c1..94da840c 100755 --- a/libwvdrmengine/run_all_unit_tests.sh +++ b/libwvdrmengine/run_all_unit_tests.sh @@ -16,6 +16,7 @@ adb shell /system/bin/cdm_engine_test adb shell /system/bin/oemcrypto_test adb shell /system/bin/file_store_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 am start com.widevine.test/com.widevine.test.MediaDrmAPITest