This source file includes following definitions.
- timer_task_pending_
- BeginBlockOnSyncMessage
- EndBlockOnSyncMessage
- OnFilterAdded
- OnFilterRemoved
- OnChannelError
- OnMessageReceived
- EnsureTimerScheduled
- MayHaveBecomeUnhung
- GetHungTime
- IsHung
- OnHangTimer
- SendHungMessage
#include "content/renderer/pepper/pepper_hung_plugin_filter.h"
#include "base/bind.h"
#include "content/child/child_process.h"
#include "content/common/frame_messages.h"
#include "content/renderer/render_thread_impl.h"
namespace content {
namespace {
const int kHungThresholdSec = 10;
const int kBlockedHardThresholdSec = kHungThresholdSec * 1.5;
}
PepperHungPluginFilter::PepperHungPluginFilter(
const base::FilePath& plugin_path,
int frame_routing_id,
int plugin_child_id)
: plugin_path_(plugin_path),
frame_routing_id_(frame_routing_id),
plugin_child_id_(plugin_child_id),
filter_(RenderThread::Get()->GetSyncMessageFilter()),
io_loop_(ChildProcess::current()->io_message_loop_proxy()),
pending_sync_message_count_(0),
hung_plugin_showing_(false),
timer_task_pending_(false) {
}
void PepperHungPluginFilter::BeginBlockOnSyncMessage() {
base::AutoLock lock(lock_);
last_message_received_ = base::TimeTicks::Now();
if (pending_sync_message_count_ == 0)
began_blocking_time_ = last_message_received_;
pending_sync_message_count_++;
EnsureTimerScheduled();
}
void PepperHungPluginFilter::EndBlockOnSyncMessage() {
base::AutoLock lock(lock_);
pending_sync_message_count_--;
DCHECK(pending_sync_message_count_ >= 0);
MayHaveBecomeUnhung();
}
void PepperHungPluginFilter::OnFilterAdded(IPC::Channel* channel) {
}
void PepperHungPluginFilter::OnFilterRemoved() {
base::AutoLock lock(lock_);
MayHaveBecomeUnhung();
}
void PepperHungPluginFilter::OnChannelError() {
base::AutoLock lock(lock_);
MayHaveBecomeUnhung();
}
bool PepperHungPluginFilter::OnMessageReceived(const IPC::Message& message) {
base::AutoLock lock(lock_);
last_message_received_ = base::TimeTicks::Now();
MayHaveBecomeUnhung();
return false;
}
PepperHungPluginFilter::~PepperHungPluginFilter() {}
void PepperHungPluginFilter::EnsureTimerScheduled() {
lock_.AssertAcquired();
if (timer_task_pending_)
return;
timer_task_pending_ = true;
io_loop_->PostDelayedTask(FROM_HERE,
base::Bind(&PepperHungPluginFilter::OnHangTimer, this),
base::TimeDelta::FromSeconds(kHungThresholdSec));
}
void PepperHungPluginFilter::MayHaveBecomeUnhung() {
lock_.AssertAcquired();
if (!hung_plugin_showing_ || IsHung())
return;
SendHungMessage(false);
hung_plugin_showing_ = false;
}
base::TimeTicks PepperHungPluginFilter::GetHungTime() const {
lock_.AssertAcquired();
DCHECK(pending_sync_message_count_);
DCHECK(!began_blocking_time_.is_null());
DCHECK(!last_message_received_.is_null());
base::TimeTicks hard_time = began_blocking_time_ +
base::TimeDelta::FromSeconds(kBlockedHardThresholdSec);
base::TimeTicks soft_time = last_message_received_ +
base::TimeDelta::FromSeconds(kHungThresholdSec);
return std::min(soft_time, hard_time);
}
bool PepperHungPluginFilter::IsHung() const {
lock_.AssertAcquired();
if (!pending_sync_message_count_)
return false;
return base::TimeTicks::Now() > GetHungTime();
}
void PepperHungPluginFilter::OnHangTimer() {
base::AutoLock lock(lock_);
timer_task_pending_ = false;
if (!pending_sync_message_count_)
return;
base::TimeDelta delay = GetHungTime() - base::TimeTicks::Now();
if (delay > base::TimeDelta()) {
timer_task_pending_ = true;
io_loop_->PostDelayedTask(FROM_HERE,
base::Bind(&PepperHungPluginFilter::OnHangTimer, this),
delay);
return;
}
hung_plugin_showing_ = true;
SendHungMessage(true);
}
void PepperHungPluginFilter::SendHungMessage(bool is_hung) {
filter_->Send(new FrameHostMsg_PepperPluginHung(
frame_routing_id_, plugin_child_id_, plugin_path_, is_hung));
}
}