1 // Copyright 2019 The Chromium 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 
5 #include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.h"
6 
7 #include "base/time/time.h"
8 #include "base/values.h"
9 #include "chrome/browser/chromeos/child_accounts/time_limit_test_utils.h"
10 
11 namespace chromeos {
12 
13 namespace utils = time_limit_test_utils;
14 
15 namespace time_limit_consistency {
16 namespace {
17 
18 // The default resets_at value is 6AM.
19 constexpr base::TimeDelta kDefaultResetsAt = base::TimeDelta::FromHours(6);
20 
21 // Converts a PolicyType object from the time limit processor to a
22 // ConsistencyGoldenPolicy used by the goldens.
ConvertProcessorPolicyToGoldenPolicy(usage_time_limit::PolicyType processor_policy)23 ConsistencyGoldenPolicy ConvertProcessorPolicyToGoldenPolicy(
24     usage_time_limit::PolicyType processor_policy) {
25   switch (processor_policy) {
26     case usage_time_limit::PolicyType::kOverride:
27       return OVERRIDE;
28     case usage_time_limit::PolicyType::kFixedLimit:
29       return FIXED_LIMIT;
30     case usage_time_limit::PolicyType::kUsageLimit:
31       return USAGE_LIMIT;
32     case usage_time_limit::PolicyType::kNoPolicy:
33       return NO_ACTIVE_POLICY;
34   }
35 
36   NOTREACHED();
37   return UNSPECIFIED_POLICY;
38 }
39 
40 // Converts the representation of a day of week used by the goldens to the one
41 // used by the time limit processor.
ConvertGoldenDayToProcessorDay(ConsistencyGoldenEffectiveDay day)42 const char* ConvertGoldenDayToProcessorDay(ConsistencyGoldenEffectiveDay day) {
43   switch (day) {
44     case MONDAY:
45       return utils::kMonday;
46     case TUESDAY:
47       return utils::kTuesday;
48     case WEDNESDAY:
49       return utils::kWednesday;
50     case THURSDAY:
51       return utils::kThursday;
52     case FRIDAY:
53       return utils::kFriday;
54     case SATURDAY:
55       return utils::kSaturday;
56     case SUNDAY:
57       return utils::kSunday;
58     default:
59       NOTREACHED();
60       return nullptr;
61   }
62 }
63 
64 }  // namespace
65 
ConvertGoldenInputToProcessorInput(const ConsistencyGoldenInput & input)66 base::Value ConvertGoldenInputToProcessorInput(
67     const ConsistencyGoldenInput& input) {
68   // Random date representing the last time the policies were updated,
69   // used whenever the last_updated field is not specified in the input proto.
70   base::Time default_last_updated =
71       utils::TimeFromString("1 Jan 2018 10:00 GMT+0300");
72   base::TimeDelta resets_at =
73       input.has_usage_limit_resets_at()
74           ? utils::CreateTime(input.usage_limit_resets_at().hour(),
75                               input.usage_limit_resets_at().minute())
76           : kDefaultResetsAt;
77 
78   base::Value policy = utils::CreateTimeLimitPolicy(resets_at);
79 
80   /* Begin Window Limits data */
81 
82   for (const ConsistencyGoldenWindowLimitEntry& window_limit :
83        input.window_limits()) {
84     utils::AddTimeWindowLimit(
85         &policy, ConvertGoldenDayToProcessorDay(window_limit.effective_day()),
86         utils::CreateTime(window_limit.starts_at().hour(),
87                           window_limit.starts_at().minute()),
88         utils::CreateTime(window_limit.ends_at().hour(),
89                           window_limit.ends_at().minute()),
90         window_limit.has_last_updated_millis()
91             ? base::Time::FromJavaTime(window_limit.last_updated_millis())
92             : default_last_updated);
93   }
94 
95   /* End Window Limits data */
96   /* Begin Usage Limits data */
97 
98   for (const ConsistencyGoldenUsageLimitEntry& usage_limit :
99        input.usage_limits()) {
100     utils::AddTimeUsageLimit(
101         &policy, ConvertGoldenDayToProcessorDay(usage_limit.effective_day()),
102         base::TimeDelta::FromMinutes(usage_limit.usage_quota_mins()),
103         usage_limit.has_last_updated_millis()
104             ? base::Time::FromJavaTime(usage_limit.last_updated_millis())
105             : default_last_updated);
106   }
107 
108   /* End Usage Limits data */
109   /* Begin Overrides data */
110 
111   for (const ConsistencyGoldenOverride& override_entry : input.overrides()) {
112     if (override_entry.action() == UNLOCK_UNTIL_LOCK_DEADLINE) {
113       utils::AddOverrideWithDuration(
114           &policy, usage_time_limit::TimeLimitOverride::Action::kUnlock,
115           base::Time::FromJavaTime(override_entry.created_at_millis()),
116           base::TimeDelta::FromMilliseconds(override_entry.duration_millis()));
117     } else {
118       utils::AddOverride(
119           &policy,
120           override_entry.action() == LOCK
121               ? usage_time_limit::TimeLimitOverride::Action::kLock
122               : usage_time_limit::TimeLimitOverride::Action::kUnlock,
123           base::Time::FromJavaTime(override_entry.created_at_millis()));
124     }
125   }
126 
127   /* End Overrides data */
128 
129   return policy;
130 }
131 
ConvertProcessorOutputToGoldenOutput(const usage_time_limit::State & state)132 ConsistencyGoldenOutput ConvertProcessorOutputToGoldenOutput(
133     const usage_time_limit::State& state) {
134   ConsistencyGoldenOutput golden_output;
135 
136   golden_output.set_is_locked(state.is_locked);
137   golden_output.set_active_policy(
138       ConvertProcessorPolicyToGoldenPolicy(state.active_policy));
139   golden_output.set_next_active_policy(
140       ConvertProcessorPolicyToGoldenPolicy(state.next_state_active_policy));
141 
142   if (state.is_time_usage_limit_enabled &&
143       golden_output.active_policy() != OVERRIDE) {
144     golden_output.set_remaining_quota_millis(
145         state.remaining_usage.InMilliseconds());
146   }
147 
148   if (state.is_locked) {
149     golden_output.set_next_unlocking_time_millis(
150         state.next_unlock_time.ToJavaTime());
151   }
152 
153   return golden_output;
154 }
155 
156 base::Optional<usage_time_limit::State>
GenerateUnlockUsageLimitOverrideStateFromInput(const ConsistencyGoldenInput & input)157 GenerateUnlockUsageLimitOverrideStateFromInput(
158     const ConsistencyGoldenInput& input) {
159   const ConsistencyGoldenOverride* usage_limit_override = nullptr;
160   for (const ConsistencyGoldenOverride& override_entry : input.overrides()) {
161     if (override_entry.action() == UNLOCK_USAGE_LIMIT &&
162         (!usage_limit_override ||
163          override_entry.created_at_millis() >
164              usage_limit_override->created_at_millis())) {
165       usage_limit_override = &override_entry;
166     }
167   }
168 
169   if (!usage_limit_override)
170     return base::nullopt;
171 
172   usage_time_limit::State previous_state;
173   previous_state.is_locked = true;
174   previous_state.active_policy = usage_time_limit::PolicyType::kUsageLimit;
175   previous_state.is_time_usage_limit_enabled = true;
176   previous_state.remaining_usage = base::TimeDelta::FromMinutes(0);
177 
178   // Usage limit started one minute before the override was created.
179   previous_state.time_usage_limit_started =
180       base::Time::FromJavaTime(usage_limit_override->created_at_millis()) -
181       base::TimeDelta::FromMinutes(1);
182 
183   return previous_state;
184 }
185 
186 }  // namespace time_limit_consistency
187 }  // namespace chromeos
188