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: ~Policy()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> PolicyRequestName(EvalStatus (Policy::* policy_method)(EvaluationContext *,State *,std::string *,R *,Args...)const)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: Policy()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