blob: 436dc73caa946e52d7c382e1bc3122e16a6142df [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
Alex Deymoc705cc82014-02-19 11:15:00 -08008#include <string>
9
Alex Deymo0d11c602014-04-23 20:12:20 -070010using base::Time;
11using base::TimeDelta;
Alex Deymoc705cc82014-02-19 11:15:00 -080012using std::string;
13
14namespace chromeos_policy_manager {
15
Alex Deymo0d11c602014-04-23 20:12:20 -070016EvalStatus ChromeOSPolicy::UpdateCheckAllowed(
17 EvaluationContext* ec, State* state, string* error,
18 UpdateCheckParams* result) const {
19 Time next_update_check;
20 if (NextUpdateCheckTime(ec, state, error, &next_update_check) !=
21 EvalStatus::kSucceeded) {
22 return EvalStatus::kFailed;
23 }
24
25 if (!ec->IsTimeGreaterThan(next_update_check))
26 return EvalStatus::kAskMeAgainLater;
27
28 // It is time to check for an update.
29 result->updates_enabled = true;
Alex Deymoe636c3c2014-03-11 19:02:08 -070030 return EvalStatus::kSucceeded;
Alex Deymoc705cc82014-02-19 11:15:00 -080031}
32
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -070033EvalStatus ChromeOSPolicy::UpdateDownloadAndApplyAllowed(EvaluationContext* ec,
34 State* state,
35 string* error,
36 bool* result) const {
37 // TODO(garnold): Write this policy implementation with the actual policy.
38 *result = true;
39 return EvalStatus::kSucceeded;
40}
41
Alex Deymo0d11c602014-04-23 20:12:20 -070042EvalStatus ChromeOSPolicy::NextUpdateCheckTime(EvaluationContext* ec,
43 State* state, string* error,
44 Time* next_update_check) const {
45 // Don't check for updates too often. We limit the update checks to once every
46 // some interval. The interval is kTimeoutInitialInterval the first time and
47 // kTimeoutPeriodicInterval for the subsequent update checks. If the update
48 // check fails, we increase the interval between the update checks
49 // exponentially until kTimeoutMaxBackoffInterval. Finally, to avoid having
50 // many chromebooks running update checks at the exact same time, we add some
51 // fuzz to the interval.
52 const Time* updater_started_time =
53 ec->GetValue(state->updater_provider()->var_updater_started_time());
54 POLICY_CHECK_VALUE_AND_FAIL(updater_started_time, error);
55
56 const base::Time* last_checked_time =
57 ec->GetValue(state->updater_provider()->var_last_checked_time());
58
59 const uint64_t* seed = ec->GetValue(state->random_provider()->var_seed());
60 POLICY_CHECK_VALUE_AND_FAIL(seed, error);
61
62 PRNG prng(*seed);
63
64 if (!last_checked_time || *last_checked_time < *updater_started_time) {
65 // First attempt.
66 *next_update_check = *updater_started_time + FuzzedInterval(
67 &prng, kTimeoutInitialInterval, kTimeoutRegularFuzz);
68 return EvalStatus::kSucceeded;
69 }
70 // Check for previous failed attempts to implement the exponential backoff.
71 const unsigned int* consecutive_failed_update_checks = ec->GetValue(
72 state->updater_provider()->var_consecutive_failed_update_checks());
73 POLICY_CHECK_VALUE_AND_FAIL(consecutive_failed_update_checks, error);
74
75 int interval = kTimeoutInitialInterval;
76 for (unsigned int i = 0; i < *consecutive_failed_update_checks; ++i) {
77 interval *= 2;
78 if (interval > kTimeoutMaxBackoffInterval) {
79 interval = kTimeoutMaxBackoffInterval;
80 break;
81 }
82 }
83
84 *next_update_check = *last_checked_time + FuzzedInterval(
85 &prng, interval, kTimeoutRegularFuzz);
86 return EvalStatus::kSucceeded;
87}
88
89TimeDelta ChromeOSPolicy::FuzzedInterval(PRNG* prng, int interval, int fuzz) {
90 int half_fuzz = fuzz / 2;
91 int lower_bound = interval - half_fuzz;
92 int upper_bound = interval + half_fuzz + 1;
93
94 // This guarantees the output interval is non negative.
95 if (lower_bound < 0)
96 lower_bound = 0;
97
98 int fuzzed_interval = lower_bound;
99 if (upper_bound - lower_bound > 0)
100 fuzzed_interval = lower_bound + prng->rand() % (upper_bound - lower_bound);
101 return TimeDelta::FromSeconds(fuzzed_interval);
102}
103
Alex Deymoc705cc82014-02-19 11:15:00 -0800104} // namespace chromeos_policy_manager