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_CHROMEOS_POLICY_H_
     18 #define UPDATE_ENGINE_UPDATE_MANAGER_CHROMEOS_POLICY_H_
     19 
     20 #include <string>
     21 
     22 #include <base/time/time.h>
     23 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     24 
     25 #include "update_engine/update_manager/policy.h"
     26 #include "update_engine/update_manager/prng.h"
     27 
     28 namespace chromeos_update_manager {
     29 
     30 // Output information from UpdateBackoffAndDownloadUrl.
     31 struct UpdateBackoffAndDownloadUrlResult {
     32   // Whether the failed attempt count (maintained by the caller) needs to be
     33   // incremented.
     34   bool do_increment_failures;
     35   // The current backoff expiry. Null if backoff is not in effect.
     36   base::Time backoff_expiry;
     37   // The new URL index to use and number of download errors associated with it.
     38   // Significant iff |do_increment_failures| is false and |backoff_expiry| is
     39   // null. Negative value means no usable URL was found.
     40   int url_idx;
     41   int url_num_errors;
     42 };
     43 
     44 // Parameters for update scattering, as returned by UpdateScattering.
     45 struct UpdateScatteringResult {
     46   bool is_scattering;
     47   base::TimeDelta wait_period;
     48   int check_threshold;
     49 };
     50 
     51 // ChromeOSPolicy implements the policy-related logic used in ChromeOS.
     52 class ChromeOSPolicy : public Policy {
     53  public:
     54   ChromeOSPolicy() {}
     55   ~ChromeOSPolicy() override {}
     56 
     57   // Policy overrides.
     58   EvalStatus UpdateCheckAllowed(
     59       EvaluationContext* ec, State* state, std::string* error,
     60       UpdateCheckParams* result) const override;
     61 
     62   EvalStatus UpdateCanStart(
     63       EvaluationContext* ec,
     64       State* state,
     65       std::string* error,
     66       UpdateDownloadParams* result,
     67       UpdateState update_state) const override;
     68 
     69   EvalStatus UpdateDownloadAllowed(
     70       EvaluationContext* ec,
     71       State* state,
     72       std::string* error,
     73       bool* result) const override;
     74 
     75   EvalStatus P2PEnabled(
     76       EvaluationContext* ec,
     77       State* state,
     78       std::string* error,
     79       bool* result) const override;
     80 
     81   EvalStatus P2PEnabledChanged(
     82       EvaluationContext* ec,
     83       State* state,
     84       std::string* error,
     85       bool* result,
     86       bool prev_result) const override;
     87 
     88  protected:
     89   // Policy override.
     90   std::string PolicyName() const override { return "ChromeOSPolicy"; }
     91 
     92  private:
     93   friend class UmChromeOSPolicyTest;
     94   FRIEND_TEST(UmChromeOSPolicyTest,
     95               FirstCheckIsAtMostInitialIntervalAfterStart);
     96   FRIEND_TEST(UmChromeOSPolicyTest, RecurringCheckBaseIntervalAndFuzz);
     97   FRIEND_TEST(UmChromeOSPolicyTest, RecurringCheckBackoffIntervalAndFuzz);
     98   FRIEND_TEST(UmChromeOSPolicyTest, RecurringCheckServerDictatedPollInterval);
     99   FRIEND_TEST(UmChromeOSPolicyTest, ExponentialBackoffIsCapped);
    100   FRIEND_TEST(UmChromeOSPolicyTest, UpdateCheckAllowedWaitsForTheTimeout);
    101   FRIEND_TEST(UmChromeOSPolicyTest, UpdateCheckAllowedWaitsForOOBE);
    102   FRIEND_TEST(UmChromeOSPolicyTest,
    103               UpdateCanStartNotAllowedScatteringNewWaitPeriodApplies);
    104   FRIEND_TEST(UmChromeOSPolicyTest,
    105               UpdateCanStartNotAllowedScatteringPrevWaitPeriodStillApplies);
    106   FRIEND_TEST(UmChromeOSPolicyTest,
    107               UpdateCanStartNotAllowedScatteringNewCountThresholdApplies);
    108   FRIEND_TEST(UmChromeOSPolicyTest,
    109               UpdateCanStartNotAllowedScatteringPrevCountThresholdStillApplies);
    110   FRIEND_TEST(UmChromeOSPolicyTest, UpdateCanStartAllowedScatteringSatisfied);
    111   FRIEND_TEST(UmChromeOSPolicyTest,
    112               UpdateCanStartAllowedInteractivePreventsScattering);
    113   FRIEND_TEST(UmChromeOSPolicyTest,
    114               UpdateCanStartAllowedP2PDownloadingBlockedDueToNumAttempts);
    115   FRIEND_TEST(UmChromeOSPolicyTest,
    116               UpdateCanStartAllowedP2PDownloadingBlockedDueToAttemptsPeriod);
    117 
    118   // Auxiliary constant (zero by default).
    119   const base::TimeDelta kZeroInterval;
    120 
    121   // Default update check timeout interval/fuzz values used to compute the
    122   // NextUpdateCheckTime(), in seconds. Actual fuzz is within +/- half of the
    123   // indicated value.
    124   static const int kTimeoutInitialInterval;
    125   static const int kTimeoutPeriodicInterval;
    126   static const int kTimeoutMaxBackoffInterval;
    127   static const int kTimeoutRegularFuzz;
    128 
    129   // Maximum update attempt backoff interval and fuzz.
    130   static const int kAttemptBackoffMaxIntervalInDays;
    131   static const int kAttemptBackoffFuzzInHours;
    132 
    133   // Maximum number of times we'll allow using P2P for the same update payload.
    134   static const int kMaxP2PAttempts;
    135   // Maximum period of time allowed for download a payload via P2P, in seconds.
    136   static const int kMaxP2PAttemptsPeriodInSeconds;
    137 
    138   // A private policy implementation returning the wallclock timestamp when
    139   // the next update check should happen.
    140   // TODO(garnold) We should probably change that to infer a monotonic
    141   // timestamp, which will make the update check intervals more resilient to
    142   // clock skews. Might require switching some of the variables exported by the
    143   // UpdaterProvider to report monotonic time, as well.
    144   EvalStatus NextUpdateCheckTime(EvaluationContext* ec, State* state,
    145                                  std::string* error,
    146                                  base::Time* next_update_check) const;
    147 
    148   // Returns a TimeDelta based on the provided |interval| seconds +/- half
    149   // |fuzz| seconds. The return value is guaranteed to be a non-negative
    150   // TimeDelta.
    151   static base::TimeDelta FuzzedInterval(PRNG* prng, int interval, int fuzz);
    152 
    153   // A private policy for determining backoff and the download URL to use.
    154   // Within |update_state|, |backoff_expiry| and |is_backoff_disabled| are used
    155   // for determining whether backoff is still in effect; if not,
    156   // |download_errors| is scanned past |failures_last_updated|, and a new
    157   // download URL from |download_urls| is found and written to |result->url_idx|
    158   // (-1 means no usable URL exists); |download_errors_max| determines the
    159   // maximum number of attempts per URL, according to the Omaha response. If an
    160   // update failure is identified then |result->do_increment_failures| is set to
    161   // true; if backoff is enabled, a new backoff period is computed (from the
    162   // time of failure) based on |num_failures|. Otherwise, backoff expiry is
    163   // nullified, indicating that no backoff is in effect.
    164   //
    165   // If backing off but the previous backoff expiry is unchanged, returns
    166   // |EvalStatus::kAskMeAgainLater|. Otherwise:
    167   //
    168   // * If backing off with a new expiry time, then |result->backoff_expiry| is
    169   //   set to this time.
    170   //
    171   // * Else, |result->backoff_expiry| is set to null, indicating that no backoff
    172   //   is in effect.
    173   //
    174   // In any of these cases, returns |EvalStatus::kSucceeded|. If an error
    175   // occurred, returns |EvalStatus::kFailed|.
    176   EvalStatus UpdateBackoffAndDownloadUrl(
    177       EvaluationContext* ec, State* state, std::string* error,
    178       UpdateBackoffAndDownloadUrlResult* result,
    179       const UpdateState& update_state) const;
    180 
    181   // A private policy for checking whether scattering is due. Writes in |result|
    182   // the decision as to whether or not to scatter; a wallclock-based scatter
    183   // wait period, which ranges from zero (do not wait) and no greater than the
    184   // current scatter factor provided by the device policy (if available) or the
    185   // maximum wait period determined by Omaha; and an update check-based
    186   // threshold between zero (no threshold) and the maximum number determined by
    187   // the update engine. Within |update_state|, |scatter_wait_period| should
    188   // contain the last scattering period returned by this function, or zero if no
    189   // wait period is known; |scatter_check_threshold| is the last update check
    190   // threshold, or zero if no such threshold is known. If not scattering, or if
    191   // any of the scattering values has changed, returns |EvalStatus::kSucceeded|;
    192   // otherwise, |EvalStatus::kAskMeAgainLater|.
    193   EvalStatus UpdateScattering(EvaluationContext* ec, State* state,
    194                               std::string* error,
    195                               UpdateScatteringResult* result,
    196                               const UpdateState& update_state) const;
    197 
    198   DISALLOW_COPY_AND_ASSIGN(ChromeOSPolicy);
    199 };
    200 
    201 }  // namespace chromeos_update_manager
    202 
    203 #endif  // UPDATE_ENGINE_UPDATE_MANAGER_CHROMEOS_POLICY_H_
    204