1// Copyright 2014 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#ifndef COMPONENTS_TIMERS_ALARM_TIMER_CHROMEOS_H_
6#define COMPONENTS_TIMERS_ALARM_TIMER_CHROMEOS_H_
7
8#include "base/callback.h"
9#include "base/macros.h"
10#include "base/memory/ref_counted.h"
11#include "base/memory/weak_ptr.h"
12#include "base/time/time.h"
13#include "base/timer/timer.h"
14
15namespace base {
16class MessageLoop;
17struct PendingTask;
18}
19
20namespace timers {
21// The class implements a timer that is capable of waking the system up from a
22// suspended state.  For example, this is useful for running tasks that are
23// needed for maintaining network connectivity, like sending heartbeat messages.
24// Currently, this feature is only available on Chrome OS systems running linux
25// version 3.11 or higher.  On all other platforms, the AlarmTimer behaves
26// exactly the same way as a regular Timer.
27class AlarmTimer : public base::Timer {
28 public:
29  ~AlarmTimer() override;
30
31  bool can_wake_from_suspend() const { return can_wake_from_suspend_; }
32
33  // Sets a hook that will be called when the timer fires and a task has been
34  // queued on |origin_message_loop_|.  Used by tests to wait until a task is
35  // pending in the MessageLoop.
36  void SetTimerFiredCallbackForTest(base::Closure test_callback);
37
38  // Timer overrides.
39  void Stop() override;
40  void Reset() override;
41
42 protected:
43  // The constructors for this class are protected because consumers should
44  // instantiate one of the specialized sub-classes defined below instead.
45  AlarmTimer(bool retain_user_task, bool is_repeating);
46  AlarmTimer(const tracked_objects::Location& posted_from,
47             base::TimeDelta delay,
48             const base::Closure& user_task,
49             bool is_repeating);
50
51 private:
52  // Common initialization that must be performed by both constructors.  This
53  // really should live in a delegated constructor but the way base::Timer's
54  // constructors are written makes it really hard to do so.
55  void Init();
56
57  // Will be called by the delegate to indicate that the timer has fired and
58  // that the user task should be run.
59  void OnTimerFired();
60
61  // Called when |origin_message_loop_| will be destroyed.
62  void WillDestroyCurrentMessageLoop();
63
64  // Delegate that will manage actually setting the timer.
65  class Delegate;
66  scoped_refptr<Delegate> delegate_;
67
68  // Keeps track of the user task we want to run.  A new one is constructed
69  // every time Reset() is called.
70  scoped_ptr<base::PendingTask> pending_task_;
71
72  // Tracks whether the timer has the ability to wake the system up from
73  // suspend.  This is a runtime check because we won't know if the system
74  // supports being woken up from suspend until the delegate actually tries to
75  // set it up.
76  bool can_wake_from_suspend_;
77
78  // Pointer to the message loop that started the timer.  Used to track the
79  // destruction of that message loop.
80  base::MessageLoop* origin_message_loop_;
81
82  // Observes |origin_message_loop_| and informs this class if it will be
83  // destroyed.
84  class MessageLoopObserver;
85  scoped_ptr<MessageLoopObserver> message_loop_observer_;
86
87  base::WeakPtrFactory<AlarmTimer> weak_factory_;
88
89  DISALLOW_COPY_AND_ASSIGN(AlarmTimer);
90};
91
92// As its name suggests, a OneShotAlarmTimer runs a given task once.  It does
93// not remember the task that was given to it after it has fired and does not
94// repeat.  Useful for fire-and-forget tasks.
95class OneShotAlarmTimer : public AlarmTimer {
96 public:
97  // Constructs a basic OneShotAlarmTimer.  An AlarmTimer constructed this way
98  // requires that Start() is called before Reset() is called.
99  OneShotAlarmTimer();
100  ~OneShotAlarmTimer() override;
101};
102
103// A RepeatingAlarmTimer takes a task and delay and repeatedly runs the task
104// using the specified delay as an interval between the runs until it is
105// explicitly stopped.  It remembers both the task and the delay it was given
106// after it fires.
107class RepeatingAlarmTimer : public AlarmTimer {
108 public:
109  // Constructs a basic RepeatingAlarmTimer.  An AlarmTimer constructed this way
110  // requires that Start() is called before Reset() is called.
111  RepeatingAlarmTimer();
112
113  // Constructs a RepeatingAlarmTimer with pre-populated parameters but does not
114  // start it.  Useful if |user_task| or |delay| are not going to change.
115  // Reset() can be called immediately after constructing an AlarmTimer in this
116  // way.
117  RepeatingAlarmTimer(const tracked_objects::Location& posted_from,
118                      base::TimeDelta delay,
119                      const base::Closure& user_task);
120
121  ~RepeatingAlarmTimer() override;
122};
123
124// A SimpleAlarmTimer only fires once but remembers the task that it was given
125// even after it has fired.  Useful if you want to run the same task multiple
126// times but not at a regular interval.
127class SimpleAlarmTimer : public AlarmTimer {
128 public:
129  // Constructs a basic SimpleAlarmTimer.  An AlarmTimer constructed this way
130  // requires that Start() is called before Reset() is called.
131  SimpleAlarmTimer();
132
133  // Constructs a SimpleAlarmTimer with pre-populated parameters but does not
134  // start it.  Useful if |user_task| or |delay| are not going to change.
135  // Reset() can be called immediately after constructing an AlarmTimer in this
136  // way.
137  SimpleAlarmTimer(const tracked_objects::Location& posted_from,
138                   base::TimeDelta delay,
139                   const base::Closure& user_task);
140
141  ~SimpleAlarmTimer() override;
142};
143
144}  // namespace timers
145
146#endif  // COMPONENTS_TIMERS_ALARM_TIMER_CHROMEOS_H_
147