1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_TIME_RESTRICTIONS_MONITOR_H_
18 #define UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_TIME_RESTRICTIONS_MONITOR_H_
19 
20 #include <memory>
21 
22 #include <base/memory/weak_ptr.h>
23 #include <brillo/message_loops/message_loop.h>
24 
25 #include "update_engine/update_manager/device_policy_provider.h"
26 #include "update_engine/update_manager/evaluation_context.h"
27 #include "update_engine/update_manager/weekly_time.h"
28 
29 namespace chromeos_update_manager {
30 
31 // Represents a monitor tracking start of restricted time intervals during which
32 // update download is not allowed. It reads |var_disallowed_time_intervals|,
33 // chooses the next interval according to current time, awaits its start and
34 // notifies the delegate. If the chosen interval is already happening, the
35 // monitor notifies immediately. The monitor will never notify the delegate
36 // while the current list of restricted intervals is empty.
37 //
38 // The monitor detects changes in the restricted intervals and handles the
39 // change with following cases:
40 // 1. No restricted time intervals or none of the intervals is in progress -> no
41 //    new restricted intervals or none of the new intervals matches the current
42 //    time.
43 //    The monitor starts tracking the next interval from the new ones, if any.
44 // 2. No restricted time intervals or none of the intervals is in progress ->
45 //    there is a new interval matching current time.
46 //    The monitor shall pick this new interval and notify the delegate
47 //    immediately about the start of the restricted interval.
48 class UpdateTimeRestrictionsMonitor {
49  public:
50   // Interface to handle start of a restricted time interval.
51   class Delegate {
52    public:
53     virtual ~Delegate() = default;
54 
55     virtual void OnRestrictedIntervalStarts() = 0;
56   };
57 
58   // Creates an instance and starts monitoring the next nearest restricted time
59   // interval if present. If no intervals are available yet the monitor will be
60   // idle until intervals list changes.
61   UpdateTimeRestrictionsMonitor(DevicePolicyProvider* device_policy_provider,
62                                 Delegate* delegate);
63 
64   UpdateTimeRestrictionsMonitor(const UpdateTimeRestrictionsMonitor&) = delete;
65   UpdateTimeRestrictionsMonitor& operator=(
66       const UpdateTimeRestrictionsMonitor&) = delete;
67 
68   ~UpdateTimeRestrictionsMonitor();
69 
IsMonitoringInterval()70   bool IsMonitoringInterval() {
71     return timeout_event_ != brillo::MessageLoop::kTaskIdNull;
72   }
73 
74  private:
75   // Starts monitoring the start of nearest restricted time interval if present
76   // and any change in restricted time intervals from policy.
77   void StartMonitoring();
78   void WaitForRestrictedIntervalStarts(
79       const WeeklyTimeIntervalVector& restricted_time_intervals);
80 
81   // Called when current time lies within a restricted interval.
82   void HandleRestrictedIntervalStarts();
83 
84   // Stop monotoring any restricted intervals.
85   void StopMonitoring();
86 
87   // Called upon change of restricted intervals.
88   void OnIntervalsChanged();
89 
90   // To access restricted time intervals from |device_policy_provider_|.
91   EvaluationContext evaluation_context_;
92 
93   DevicePolicyProvider* const device_policy_provider_;
94   Delegate* const delegate_;
95 
96   // The TaskId returned by the message loop identifying the timeout callback.
97   // Used for cancelling the timeout callback.
98   brillo::MessageLoop::TaskId timeout_event_{brillo::MessageLoop::kTaskIdNull};
99 
100   base::WeakPtrFactory<UpdateTimeRestrictionsMonitor> weak_ptr_factory_;
101 };
102 
103 }  // namespace chromeos_update_manager
104 
105 #endif  // UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_TIME_RESTRICTIONS_MONITOR_H_
106