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/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