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