1 // Copyright 2019 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 CHROME_BROWSER_CHROMEOS_POLICY_SCHEDULED_UPDATE_CHECKER_TASK_EXECUTOR_WITH_RETRIES_H_
6 #define CHROME_BROWSER_CHROMEOS_POLICY_SCHEDULED_UPDATE_CHECKER_TASK_EXECUTOR_WITH_RETRIES_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/callback_forward.h"
12 #include "base/macros.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
16 
17 namespace policy {
18 
19 // This class runs a task that can fail. In case of failure it allows the caller
20 // to retry the task using a OneShotTimer i.e. the retry timer is not suspend
21 // aware. The caller must hold a wake lock if it wants the task to run till
22 // success or retry failure without the device suspending. Any callbacks passed
23 // to its API will not be invoked if an object of this class is destroyed.
24 class TaskExecutorWithRetries {
25  public:
26   using AsyncTask = base::OnceClosure;
27   using RetryFailureCb = base::OnceCallback<void()>;
28 
29   // |description| - String identifying this object.
30   // |get_ticks_since_boot_fn| - Callback that returns current ticks from boot.
31   // Used for scheduling retry timer.
32   // |max_retries| - Maximum number of retries after which trying the task is
33   // given up.
34   // |retry_time| - Time between each retry.
35   TaskExecutorWithRetries(int max_retries, base::TimeDelta retry_time);
36   ~TaskExecutorWithRetries();
37 
38   // Runs |task| and caches |retry_failure_cb| which will be called when
39   // |max_retries_| is reached and |task| couldn't be run successfully.
40   // Consecutive calls override any state and pending callbacks associated with
41   // the previous call. |retry_failure_cb| will return the task that was last
42   // scheduled using |ScheduleRetry|.
43   void Start(AsyncTask task, RetryFailureCb retry_failure_cb);
44 
45   // Resets state and stops all pending callbacks.
46   void Stop();
47 
48   // Cancels all outstanding |RetryTask| calls and schedules a new |RetryTask|
49   // call on the calling sequence to run |task|.
50   void ScheduleRetry(AsyncTask task);
51 
52  private:
53   // Called upon starting |retry_timer_|. Indicates whether or not the timer was
54   // started successfully.
55   void OnRetryTimerStartResult(bool result);
56 
57   // Resets state including stopping all pending callbacks.
58   void ResetState();
59 
60   // Maximum number of retries after which trying the task is given up.
61   const int max_retries_;
62 
63   // Time between each retry.
64   const base::TimeDelta retry_time_;
65 
66   // Current retry iteration. Capped at |max_retries_|.
67   int num_retries_ = 0;
68 
69   // Callback to call after |max_retries_| have been reached and |task| wasn't
70   // successfully scheduled.
71   RetryFailureCb retry_failure_cb_;
72 
73   // Timer used to retry |task| passed in |ScheduleRetry|.
74   base::OneShotTimer retry_timer_;
75 
76   DISALLOW_COPY_AND_ASSIGN(TaskExecutorWithRetries);
77 };
78 
79 }  // namespace policy
80 
81 #endif  // CHROME_BROWSER_CHROMEOS_POLICY_SCHEDULED_UPDATE_CHECKER_TASK_EXECUTOR_WITH_RETRIES_H_
82