blob: eb50887cc2174c321ef18000764bfe2588d79022 [file] [log] [blame]
Alex Deymoc705cc82014-02-19 11:15:00 -08001// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymo0d11c602014-04-23 20:12:20 -07005#include "update_engine/policy_manager/chromeos_policy.h"
6#include "update_engine/policy_manager/policy_utils.h"
7
Gilad Arnolde1218812014-05-07 12:21:36 -07008#include <algorithm>
Alex Deymoc705cc82014-02-19 11:15:00 -08009#include <string>
10
Alex Deymo0d11c602014-04-23 20:12:20 -070011using base::Time;
12using base::TimeDelta;
Alex Deymoc705cc82014-02-19 11:15:00 -080013using std::string;
14
15namespace chromeos_policy_manager {
16
Alex Deymo0d11c602014-04-23 20:12:20 -070017EvalStatus ChromeOSPolicy::UpdateCheckAllowed(
18 EvaluationContext* ec, State* state, string* error,
19 UpdateCheckParams* result) const {
20 Time next_update_check;
21 if (NextUpdateCheckTime(ec, state, error, &next_update_check) !=
22 EvalStatus::kSucceeded) {
23 return EvalStatus::kFailed;
24 }
25
26 if (!ec->IsTimeGreaterThan(next_update_check))
27 return EvalStatus::kAskMeAgainLater;
28
29 // It is time to check for an update.
30 result->updates_enabled = true;
Alex Deymoe636c3c2014-03-11 19:02:08 -070031 return EvalStatus::kSucceeded;
Alex Deymoc705cc82014-02-19 11:15:00 -080032}
33
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -070034EvalStatus ChromeOSPolicy::UpdateDownloadAndApplyAllowed(EvaluationContext* ec,
35 State* state,
36 string* error,
37 bool* result) const {
38 // TODO(garnold): Write this policy implementation with the actual policy.
39 *result = true;
40 return EvalStatus::kSucceeded;
41}
42
Alex Deymo0d11c602014-04-23 20:12:20 -070043EvalStatus ChromeOSPolicy::NextUpdateCheckTime(EvaluationContext* ec,
44 State* state, string* error,
45 Time* next_update_check) const {
46 // Don't check for updates too often. We limit the update checks to once every
47 // some interval. The interval is kTimeoutInitialInterval the first time and
48 // kTimeoutPeriodicInterval for the subsequent update checks. If the update
49 // check fails, we increase the interval between the update checks
50 // exponentially until kTimeoutMaxBackoffInterval. Finally, to avoid having
51 // many chromebooks running update checks at the exact same time, we add some
52 // fuzz to the interval.
53 const Time* updater_started_time =
54 ec->GetValue(state->updater_provider()->var_updater_started_time());
55 POLICY_CHECK_VALUE_AND_FAIL(updater_started_time, error);
56
57 const base::Time* last_checked_time =
58 ec->GetValue(state->updater_provider()->var_last_checked_time());
59
60 const uint64_t* seed = ec->GetValue(state->random_provider()->var_seed());
61 POLICY_CHECK_VALUE_AND_FAIL(seed, error);
62
63 PRNG prng(*seed);
64
65 if (!last_checked_time || *last_checked_time < *updater_started_time) {
66 // First attempt.
67 *next_update_check = *updater_started_time + FuzzedInterval(
68 &prng, kTimeoutInitialInterval, kTimeoutRegularFuzz);
69 return EvalStatus::kSucceeded;
70 }
71 // Check for previous failed attempts to implement the exponential backoff.
72 const unsigned int* consecutive_failed_update_checks = ec->GetValue(
73 state->updater_provider()->var_consecutive_failed_update_checks());
74 POLICY_CHECK_VALUE_AND_FAIL(consecutive_failed_update_checks, error);
75
76 int interval = kTimeoutInitialInterval;
77 for (unsigned int i = 0; i < *consecutive_failed_update_checks; ++i) {
78 interval *= 2;
79 if (interval > kTimeoutMaxBackoffInterval) {
80 interval = kTimeoutMaxBackoffInterval;
81 break;
82 }
83 }
84
85 *next_update_check = *last_checked_time + FuzzedInterval(
86 &prng, interval, kTimeoutRegularFuzz);
87 return EvalStatus::kSucceeded;
88}
89
90TimeDelta ChromeOSPolicy::FuzzedInterval(PRNG* prng, int interval, int fuzz) {
Gilad Arnolde1218812014-05-07 12:21:36 -070091 DCHECK_GE(interval, 0);
92 DCHECK_GE(fuzz, 0);
Alex Deymo0d11c602014-04-23 20:12:20 -070093 int half_fuzz = fuzz / 2;
Alex Deymo0d11c602014-04-23 20:12:20 -070094 // This guarantees the output interval is non negative.
Gilad Arnolde1218812014-05-07 12:21:36 -070095 int interval_min = std::max(interval - half_fuzz, 0);
96 int interval_max = interval + half_fuzz;
97 return TimeDelta::FromSeconds(prng->RandMinMax(interval_min, interval_max));
Alex Deymo0d11c602014-04-23 20:12:20 -070098}
99
Alex Deymoc705cc82014-02-19 11:15:00 -0800100} // namespace chromeos_policy_manager