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