[ Merge of http://go/wvgerrit/89848 ] Apps query a number of properties at initialization. The mediaDrm API getProperty allows the query of a single property at a time. This causes a series of requests. If no crypto sessions are concurrently open, a series of expensive OEMCrypto Initialization and Termination calls will occur. In this change OEMCrypto termination is delayed. If an OEMCrypto Terminate is followed in close succession by an Initialize, neither will occur avoiding the overhead. A timer enables a countdown process. If no session activity occurs, the timer will eventually terminate OEMCrypto and exit. Bug: 136282358 Test: Android unit/integration tests Change-Id: I442b7919b4e7835c52583516c8bc64d0c150241d
96 lines
2.2 KiB
C++
96 lines
2.2 KiB
C++
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine Master
|
|
// License Agreement.
|
|
//
|
|
// Timer class - provides a simple Android specific timer implementation
|
|
|
|
#include "timer.h"
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <utils/Mutex.h>
|
|
#include <utils/RefBase.h>
|
|
#include <utils/StrongPointer.h>
|
|
#include <utils/Thread.h>
|
|
|
|
namespace wvcdm {
|
|
|
|
class Timer::Impl : virtual public android::RefBase {
|
|
private:
|
|
class ImplThread : public android::Thread {
|
|
public:
|
|
ImplThread() : Thread(false), handler_(nullptr), period_ns_(0) {}
|
|
virtual ~ImplThread() {}
|
|
|
|
bool Start(TimerHandler* handler, uint32_t time_in_secs) {
|
|
handler_ = handler;
|
|
period_ns_ = time_in_secs * 1000000000ll;
|
|
return run("wvcdm::Timer::Impl") == android::NO_ERROR;
|
|
}
|
|
|
|
void Stop(bool wait_for_exit) {
|
|
stop_condition_.signal();
|
|
if (wait_for_exit) {
|
|
requestExitAndWait();
|
|
} else {
|
|
requestExit();
|
|
}
|
|
}
|
|
|
|
private:
|
|
virtual bool threadLoop() {
|
|
android::Mutex::Autolock autoLock(lock_);
|
|
stop_condition_.waitRelative(lock_, period_ns_);
|
|
handler_->OnTimerEvent();
|
|
return true;
|
|
}
|
|
|
|
TimerHandler* handler_;
|
|
uint64_t period_ns_;
|
|
android::Mutex lock_;
|
|
android::Condition stop_condition_;
|
|
|
|
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(bool wait_for_exit) {
|
|
impl_thread_->Stop(wait_for_exit);
|
|
impl_thread_.clear();
|
|
}
|
|
|
|
bool IsRunning() {
|
|
return (impl_thread_ != nullptr) && (impl_thread_->isRunning());
|
|
}
|
|
|
|
CORE_DISALLOW_COPY_AND_ASSIGN(Impl);
|
|
};
|
|
|
|
Timer::Timer() : impl_(new Timer::Impl()) {}
|
|
|
|
Timer::~Timer() {
|
|
if (IsRunning()) Stop(false);
|
|
}
|
|
|
|
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(bool wait_for_exit) { impl_->Stop(wait_for_exit); }
|
|
|
|
bool Timer::IsRunning() { return impl_->IsRunning(); }
|
|
|
|
} // namespace wvcdm
|