1 //
2 // Copyright (C) 2014 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_POLICY_H_
18 #define UPDATE_ENGINE_UPDATE_MANAGER_POLICY_H_
19 
20 #include <string>
21 #include <tuple>
22 #include <vector>
23 
24 #include "update_engine/common/error_code.h"
25 #include "update_engine/payload_consumer/install_plan.h"
26 #include "update_engine/update_manager/evaluation_context.h"
27 #include "update_engine/update_manager/rollback_prefs.h"
28 #include "update_engine/update_manager/state.h"
29 
30 namespace chromeos_update_manager {
31 
32 // The three different results of a policy request.
33 enum class EvalStatus {
34   kFailed,
35   kSucceeded,
36   kAskMeAgainLater,
37   kContinue,
38 };
39 
40 std::string ToString(EvalStatus status);
41 
42 // Parameters of an update check. These parameters are determined by the
43 // UpdateCheckAllowed policy.
44 struct UpdateCheckParams {
45   bool updates_enabled;  // Whether the auto-updates are enabled on this build.
46 
47   // Attributes pertaining to the case where update checks are allowed.
48   //
49   // A target version prefix, if imposed by policy; otherwise, an empty string.
50   std::string target_version_prefix;
51   // Specifies whether rollback images are allowed by device policy.
52   bool rollback_allowed;
53   // Specifies the number of Chrome milestones rollback should be allowed,
54   // starting from the stable version at any time. Value is -1 if unspecified
55   // (e.g. no device policy is available yet), in this case no version
56   // roll-forward should happen.
57   int rollback_allowed_milestones;
58   // A target channel, if so imposed by policy; otherwise, an empty string.
59   std::string target_channel;
60 
61   // Whether the allowed update is interactive (user-initiated) or periodic.
62   bool interactive;
63 };
64 
65 // Input arguments to UpdateCanStart.
66 //
67 // A snapshot of the state of the current update process. This includes
68 // everything that a policy might need and that occurred since the first time
69 // the current payload was first seen and attempted (consecutively).
70 struct UpdateState {
71   // Information pertaining to the current update payload and/or check.
72   //
73   // Whether the current update check is an interactive one. The caller should
74   // feed the value returned by the preceding call to UpdateCheckAllowed().
75   bool interactive;
76   // Whether it is a delta payload.
77   bool is_delta_payload;
78   // Wallclock time when payload was first (consecutively) offered by Omaha.
79   base::Time first_seen;
80   // Number of consecutive update checks returning the current update.
81   int num_checks;
82   // Number of update payload failures and the wallclock time when it was last
83   // updated by the updater. These should both be nullified whenever a new
84   // update is seen; they are updated at the policy's descretion (via
85   // UpdateDownloadParams.do_increment_failures) once all of the usable download
86   // URLs for the payload have been used without success. They should be
87   // persisted across reboots.
88   int num_failures;
89   base::Time failures_last_updated;
90 
91   // Information pertaining to downloading and applying of the current update.
92   //
93   // An array of download URLs provided by Omaha.
94   std::vector<std::string> download_urls;
95   // Max number of errors allowed per download URL.
96   int download_errors_max;
97   // The index of the URL to download from, as determined in the previous call
98   // to the policy. For a newly seen payload, this should be -1.
99   int last_download_url_idx;
100   // The number of successive download errors pertaining to this last URL, as
101   // determined in the previous call to the policy. For a newly seen payload,
102   // this should be zero.
103   int last_download_url_num_errors;
104   // An array of errors that occurred while trying to download this update since
105   // the previous call to this policy has returned, or since this payload was
106   // first seen, or since the updater process has started (whichever is later).
107   // Includes the URL index attempted, the error code, and the wallclock-based
108   // timestamp when it occurred.
109   std::vector<std::tuple<int, chromeos_update_engine::ErrorCode, base::Time>>
110       download_errors;
111   // Whether Omaha forbids use of P2P for downloading and/or sharing.
112   bool p2p_downloading_disabled;
113   bool p2p_sharing_disabled;
114   // The number of P2P download attempts and wallclock-based time when P2P
115   // download was first attempted.
116   int p2p_num_attempts;
117   base::Time p2p_first_attempted;
118 
119   // Information pertaining to update backoff mechanism.
120   //
121   // The currently known (persisted) wallclock-based backoff expiration time;
122   // zero if none.
123   base::Time backoff_expiry;
124   // Whether backoff is disabled by Omaha.
125   bool is_backoff_disabled;
126 
127   // Information pertaining to update scattering.
128   //
129   // The currently known (persisted) scattering wallclock-based wait period and
130   // update check threshold; zero if none.
131   base::TimeDelta scatter_wait_period;
132   int scatter_check_threshold;
133   // Maximum wait period allowed for this update, as determined by Omaha.
134   base::TimeDelta scatter_wait_period_max;
135   // Minimum/maximum check threshold values.
136   // TODO(garnold) These appear to not be related to the current update and so
137   // should probably be obtained as variables via UpdaterProvider.
138   int scatter_check_threshold_min;
139   int scatter_check_threshold_max;
140 };
141 
142 // Results regarding the downloading and applying of an update, as determined by
143 // UpdateCanStart.
144 //
145 // An enumerator for the reasons of not allowing an update to start.
146 enum class UpdateCannotStartReason {
147   kUndefined,
148   kCheckDue,
149   kScattering,
150   kBackoff,
151   kCannotDownload,
152 };
153 
154 struct UpdateDownloadParams {
155   // Whether the update attempt is allowed to proceed.
156   bool update_can_start;
157   // If update cannot proceed, a reason code for why it cannot do so.
158   UpdateCannotStartReason cannot_start_reason;
159 
160   // Download related attributes. The update engine uses them to choose the
161   // means for downloading and applying an update.
162   //
163   // The index of the download URL to use (-1 means no suitable URL was found)
164   // and whether it can be used. Even if there's no URL or its use is not
165   // allowed (backoff, scattering) there may still be other means for download
166   // (like P2P).  The URL index needs to be persisted and handed back to the
167   // policy on the next time it is called.
168   int download_url_idx;
169   bool download_url_allowed;
170   // The number of download errors associated with this download URL. This value
171   // needs to be persisted and handed back to the policy on the next time it is
172   // called.
173   int download_url_num_errors;
174   // Whether P2P download and sharing are allowed.
175   bool p2p_downloading_allowed;
176   bool p2p_sharing_allowed;
177 
178   // Other values that need to be persisted and handed to the policy as need on
179   // the next call.
180   //
181   // Whether an update failure has been identified by the policy. The client
182   // should increment and persist its update failure count, and record the time
183   // when this was done; it needs to hand these values back to the policy
184   // (UpdateState.{num_failures,failures_last_updated}) on the next time it is
185   // called.
186   bool do_increment_failures;
187   // The current backof expiry.
188   base::Time backoff_expiry;
189   // The scattering wait period and check threshold.
190   base::TimeDelta scatter_wait_period;
191   int scatter_check_threshold;
192 };
193 
194 // The Policy class is an interface to the ensemble of policy requests that the
195 // client can make. A derived class includes the policy implementations of
196 // these.
197 //
198 // When compile-time selection of the policy is required due to missing or extra
199 // parts in a given platform, a different Policy subclass can be used.
200 class Policy {
201  public:
202   virtual ~Policy() {}
203 
204   // Returns the name of a public policy request.
205   // IMPORTANT: Be sure to add a conditional for each new public policy that is
206   // being added to this class in the future.
207   template <typename R, typename... Args>
208   std::string PolicyRequestName(EvalStatus (Policy::*policy_method)(
209       EvaluationContext*, State*, std::string*, R*, Args...) const) const {
210     std::string class_name = PolicyName() + "::";
211 
212     if (reinterpret_cast<typeof(&Policy::UpdateCheckAllowed)>(policy_method) ==
213         &Policy::UpdateCheckAllowed)
214       return class_name + "UpdateCheckAllowed";
215     if (reinterpret_cast<typeof(&Policy::UpdateCanBeApplied)>(policy_method) ==
216         &Policy::UpdateCanBeApplied)
217       return class_name + "UpdateCanBeApplied";
218     if (reinterpret_cast<typeof(&Policy::UpdateCanStart)>(policy_method) ==
219         &Policy::UpdateCanStart)
220       return class_name + "UpdateCanStart";
221     if (reinterpret_cast<typeof(&Policy::UpdateDownloadAllowed)>(
222             policy_method) == &Policy::UpdateDownloadAllowed)
223       return class_name + "UpdateDownloadAllowed";
224     if (reinterpret_cast<typeof(&Policy::P2PEnabled)>(policy_method) ==
225         &Policy::P2PEnabled)
226       return class_name + "P2PEnabled";
227     if (reinterpret_cast<typeof(&Policy::P2PEnabledChanged)>(policy_method) ==
228         &Policy::P2PEnabledChanged)
229       return class_name + "P2PEnabledChanged";
230 
231     NOTREACHED();
232     return class_name + "(unknown)";
233   }
234 
235   // List of policy requests. A policy request takes an EvaluationContext as the
236   // first argument, a State instance, a returned error message, a returned
237   // value and optionally followed by one or more arbitrary constant arguments.
238   //
239   // When the implementation fails, the method returns EvalStatus::kFailed and
240   // sets the |error| string.
241 
242   // UpdateCheckAllowed returns whether it is allowed to request an update check
243   // to Omaha.
244   virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec,
245                                         State* state,
246                                         std::string* error,
247                                         UpdateCheckParams* result) const = 0;
248 
249   // UpdateCanBeApplied returns whether the given |install_plan| can be acted
250   // on at this time.  The reason for not applying is returned in |result|.
251   // The Policy may modify the passed-in |install_plan|, based on the
252   // implementation in the Policy and values provided by the EvaluationContext.
253   virtual EvalStatus UpdateCanBeApplied(
254       EvaluationContext* ec,
255       State* state,
256       std::string* error,
257       chromeos_update_engine::ErrorCode* result,
258       chromeos_update_engine::InstallPlan* install_plan) const = 0;
259 
260   // Returns EvalStatus::kSucceeded if either an update can start being
261   // processed, or the attempt needs to be aborted. In cases where the update
262   // needs to wait for some condition to be satisfied, but none of the values
263   // that need to be persisted has changed, returns
264   // EvalStatus::kAskMeAgainLater. Arguments include an |update_state| that
265   // encapsulates data pertaining to the current ongoing update process.
266   virtual EvalStatus UpdateCanStart(EvaluationContext* ec,
267                                     State* state,
268                                     std::string* error,
269                                     UpdateDownloadParams* result,
270                                     UpdateState update_state) const = 0;
271 
272   // Checks whether downloading of an update is allowed; currently, this checks
273   // whether the network connection type is suitable for updating over.  May
274   // consult the shill provider as well as the device policy (if available).
275   // Returns |EvalStatus::kSucceeded|, setting |result| according to whether or
276   // not the current connection can be used; on error, returns
277   // |EvalStatus::kFailed| and sets |error| accordingly.
278   virtual EvalStatus UpdateDownloadAllowed(EvaluationContext* ec,
279                                            State* state,
280                                            std::string* error,
281                                            bool* result) const = 0;
282 
283   // Checks whether P2P is enabled. This may consult device policy and other
284   // global settings.
285   virtual EvalStatus P2PEnabled(EvaluationContext* ec,
286                                 State* state,
287                                 std::string* error,
288                                 bool* result) const = 0;
289 
290   // Checks whether P2P is enabled, but blocks (returns
291   // |EvalStatus::kAskMeAgainLater|) until it is different from |prev_result|.
292   // If the P2P enabled status is not expected to change, will return
293   // immediately with |EvalStatus::kSucceeded|. This internally uses the
294   // P2PEnabled() policy above.
295   virtual EvalStatus P2PEnabledChanged(EvaluationContext* ec,
296                                        State* state,
297                                        std::string* error,
298                                        bool* result,
299                                        bool prev_result) const = 0;
300 
301  protected:
302   Policy() {}
303 
304   // Returns the name of the actual policy class.
305   virtual std::string PolicyName() const = 0;
306 
307  private:
308   DISALLOW_COPY_AND_ASSIGN(Policy);
309 };
310 
311 }  // namespace chromeos_update_manager
312 
313 #endif  // UPDATE_ENGINE_UPDATE_MANAGER_POLICY_H_
314