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