Home | History | Annotate | Download | only in input
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/renderer_host/input/timeout_monitor.h"
      6 
      7 using base::Time;
      8 using base::TimeDelta;
      9 
     10 namespace content {
     11 
     12 TimeoutMonitor::TimeoutMonitor(const TimeoutHandler& timeout_handler)
     13     : timeout_handler_(timeout_handler) {
     14   DCHECK(!timeout_handler_.is_null());
     15 }
     16 
     17 TimeoutMonitor::~TimeoutMonitor() {}
     18 
     19 void TimeoutMonitor::Start(TimeDelta delay) {
     20   // Set time_when_considered_timed_out_ if it's null. Also, update
     21   // time_when_considered_timed_out_ if the caller's request is sooner than the
     22   // existing one. This will have the side effect that the existing timeout will
     23   // be forgotten.
     24   Time requested_end_time = Time::Now() + delay;
     25   if (time_when_considered_timed_out_.is_null() ||
     26       time_when_considered_timed_out_ > requested_end_time)
     27     time_when_considered_timed_out_ = requested_end_time;
     28 
     29   // If we already have a timer with the same or shorter duration, then we can
     30   // wait for it to finish.
     31   if (timeout_timer_.IsRunning() && timeout_timer_.GetCurrentDelay() <= delay) {
     32     // If time_when_considered_timed_out_ was null, this timer may fire early.
     33     // CheckTimedOut handles that that by calling Start with the remaining time.
     34     // If time_when_considered_timed_out_ was non-null, it means we still
     35     // haven't been stopped, so we leave time_when_considered_timed_out_ as is.
     36     return;
     37   }
     38 
     39   // Either the timer is not yet running, or we need to adjust the timer to
     40   // fire sooner.
     41   time_when_considered_timed_out_ = requested_end_time;
     42   timeout_timer_.Stop();
     43   timeout_timer_.Start(FROM_HERE, delay, this, &TimeoutMonitor::CheckTimedOut);
     44 }
     45 
     46 void TimeoutMonitor::Restart(TimeDelta delay) {
     47   // Setting to null will cause StartTimeoutMonitor to restart the timer.
     48   time_when_considered_timed_out_ = Time();
     49   Start(delay);
     50 }
     51 
     52 void TimeoutMonitor::Stop() {
     53   // We do not bother to stop the timeout_timer_ here in case it will be
     54   // started again shortly, which happens to be the common use case.
     55   time_when_considered_timed_out_ = Time();
     56 }
     57 
     58 void TimeoutMonitor::CheckTimedOut() {
     59   // If we received a call to |Stop()|.
     60   if (time_when_considered_timed_out_.is_null())
     61     return;
     62 
     63   // If we have not waited long enough, then wait some more.
     64   Time now = Time::Now();
     65   if (now < time_when_considered_timed_out_) {
     66     Start(time_when_considered_timed_out_ - now);
     67     return;
     68   }
     69 
     70   timeout_handler_.Run();
     71 }
     72 
     73 bool TimeoutMonitor::IsRunning() const {
     74   return timeout_timer_.IsRunning() &&
     75          !time_when_considered_timed_out_.is_null();
     76 }
     77 
     78 }  // namespace content
     79