0

[Bedtime Hours] Add more util functions to WeeklyTimeChecked

Add WeeklyTimeChecked::FromTimeDelta and test_support builders from
TimeDelta.

Bug: b:345186543
Change-Id: Ic6ceade5d39c2aa835fa9b28580b9de188b501d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5832039
Reviewed-by: Emmanuel Arias Soto <eariassoto@google.com>
Commit-Queue: Ivan Šandrk <isandrk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1350668}
This commit is contained in:
Ivan Šandrk
2024-09-04 09:14:17 +00:00
committed by Chromium LUCI CQ
parent 7b87bdf3c3
commit ac1fe2fe93
5 changed files with 105 additions and 5 deletions

@ -27,17 +27,36 @@ base::Value::Dict BuildWeeklyTimeCheckedDict(WeeklyTimeChecked::Day day_of_week,
return dict;
}
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(
WeeklyTimeChecked::Day start_day, int start_milliseconds,
WeeklyTimeChecked::Day end_day, int end_milliseconds) {
base::Value::Dict BuildWeeklyTimeCheckedDict(base::TimeDelta time_delta) {
auto w = WeeklyTimeChecked::FromTimeDelta(time_delta);
return BuildWeeklyTimeCheckedDict(w.day_of_week(),
w.milliseconds_since_midnight());
}
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(base::Value::Dict start,
base::Value::Dict end) {
base::Value::Dict dict;
auto start = BuildWeeklyTimeCheckedDict(start_day, start_milliseconds);
auto end = BuildWeeklyTimeCheckedDict(end_day, end_milliseconds);
EXPECT_TRUE(dict.Set(WeeklyTimeIntervalChecked::kStart, std::move(start)));
EXPECT_TRUE(dict.Set(WeeklyTimeIntervalChecked::kEnd, std::move(end)));
return dict;
}
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(base::TimeDelta start,
base::TimeDelta end) {
return BuildWeeklyTimeIntervalCheckedDict(BuildWeeklyTimeCheckedDict(start),
BuildWeeklyTimeCheckedDict(end));
}
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(
WeeklyTimeChecked::Day start_day,
int start_milliseconds,
WeeklyTimeChecked::Day end_day,
int end_milliseconds) {
return BuildWeeklyTimeIntervalCheckedDict(
BuildWeeklyTimeCheckedDict(start_day, start_milliseconds),
BuildWeeklyTimeCheckedDict(end_day, end_milliseconds));
}
base::Value::List BuildList(std::string_view json_str) {
std::optional<base::Value> value = base::JSONReader::Read(json_str);
if (!value.has_value()) {
@ -51,6 +70,21 @@ base::Value::List BuildList(std::string_view json_str) {
return std::move(value.value()).TakeList();
}
base::Value::List BuildList(base::Time now,
base::TimeDelta from_now,
base::TimeDelta duration) {
// TODO(isandrk): Can probably simplify function to only pass in start_time
// (which would be equal to now + from_now).
WeeklyTimeChecked current_weekly_time_checked =
WeeklyTimeChecked::FromTimeAsLocalTime(now);
base::TimeDelta current_time_of_week =
current_weekly_time_checked.ToTimeDelta();
base::TimeDelta start = current_time_of_week + from_now;
base::TimeDelta end = start + duration;
return base::Value::List().Append(
BuildWeeklyTimeIntervalCheckedDict(start, end));
}
std::vector<WeeklyTimeIntervalChecked> BuildIntervals(
std::string_view json_str) {
base::Value::List list = BuildList(json_str);

@ -22,8 +22,13 @@ namespace policy::weekly_time {
// `chromeos::prefs::kDeviceRestrictionSchedule`.
base::Value::Dict BuildWeeklyTimeCheckedDict(WeeklyTimeChecked::Day day_of_week,
int milliseconds_since_midnight);
base::Value::Dict BuildWeeklyTimeCheckedDict(base::TimeDelta time_delta);
// Represents an interval from `chromeos::prefs::kDeviceRestrictionSchedule`.
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(base::TimeDelta start,
base::TimeDelta end);
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(base::Value::Dict start,
base::Value::Dict end);
base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(
WeeklyTimeChecked::Day start_day, int start_milliseconds,
WeeklyTimeChecked::Day end_day, int end_milliseconds);
@ -31,6 +36,13 @@ base::Value::Dict BuildWeeklyTimeIntervalCheckedDict(
// Builds a `base::Value::List` from the given `json_str`.
base::Value::List BuildList(std::string_view json_str);
// Builds a list with one interval starting `from_now` from `now` with duration
// `duration`. `from_now` can be negative meaning the interval started in the
// past.
base::Value::List BuildList(base::Time now,
base::TimeDelta from_now,
base::TimeDelta duration);
// Builds a list of intervals from the given `json_str`.
std::vector<WeeklyTimeIntervalChecked> BuildIntervals(
std::string_view json_str);

@ -84,6 +84,21 @@ WeeklyTimeChecked WeeklyTimeChecked::FromTimeAsLocalTime(base::Time time) {
return FromExploded(exploded);
}
// static
WeeklyTimeChecked WeeklyTimeChecked::FromTimeDelta(base::TimeDelta time_delta) {
time_delta %= base::Days(7);
if (time_delta.is_negative()) {
time_delta += base::Days(7);
}
int day = time_delta.InDays();
time_delta -= base::Days(day);
int millis = time_delta.InMilliseconds();
// Add one to day since Monday starts at 1, not at 0.
return WeeklyTimeChecked(static_cast<Day>(day + 1), millis);
}
base::TimeDelta WeeklyTimeChecked::ToTimeDelta() const {
return base::Days(static_cast<int>(day_of_week_) - 1) +
base::Milliseconds(milliseconds_since_midnight_);

@ -64,6 +64,9 @@ class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_POLICY) WeeklyTimeChecked {
// Constructs from `time` in local time (as opposed to GMT, PST, etc.).
static WeeklyTimeChecked FromTimeAsLocalTime(base::Time time);
// Constructs from `time_delta`. Opposite of `ToTimeDelta()`.
static WeeklyTimeChecked FromTimeDelta(base::TimeDelta time_delta);
// Convert to base::TimeDelta. (Monday, 0) = 0, (Monday, 5h) = 5h,
// (Tuesday, 0) = 1d, (Tuesday, 5m) = 1d + 5m, etc.
base::TimeDelta ToTimeDelta() const;

@ -112,6 +112,42 @@ TEST(WeeklyTimeCheckedTest, FromTime) {
EXPECT_EQ(w.milliseconds_since_midnight(), 10 * kMillisecondsInHour);
}
TEST(WeeklyTimeCheckedTest, FromTimeDelta) {
// clang-format off
struct TestData {
base::TimeDelta time_delta;
Day day;
int millis;
} test_data[] = {
{base::TimeDelta(), Day::kMonday, 0},
{base::Milliseconds(100), Day::kMonday, 100},
{base::Days(7), Day::kMonday, 0},
{base::Days(8), Day::kTuesday, 0},
{base::Days(16), Day::kWednesday, 0},
{base::Days(16) + base::Milliseconds(100), Day::kWednesday, 100},
// Negative values.
{-base::Days(1), Day::kSunday, 0},
{-base::Days(2), Day::kSaturday, 0},
{-base::Days(3), Day::kFriday, 0},
{-base::Days(7), Day::kMonday, 0},
{-base::Days(8), Day::kSunday, 0},
{-base::Days(1) - base::Hours(1), Day::kSaturday, base::Hours(23).InMilliseconds()},
{-base::Days(1) - base::Hours(23), Day::kSaturday, base::Hours(1).InMilliseconds()},
{-base::Days(6) - base::Hours(1), Day::kMonday, base::Hours(23).InMilliseconds()},
{-base::Days(6) - base::Hours(23), Day::kMonday, base::Hours(1).InMilliseconds()},
{-base::Days(6) - base::Hours(24), Day::kMonday, 0},
};
// clang-format on
int i = 0;
for (const auto& t : test_data) {
auto actual = WeeklyTimeChecked::FromTimeDelta(t.time_delta);
auto expected = WeeklyTimeChecked(t.day, t.millis);
EXPECT_EQ(actual, expected) << "Failed test case #" << i;
i++;
}
}
TEST(WeeklyTimeCheckedTest, ToTimeDelta) {
auto w = WeeklyTimeChecked(Day::kTuesday, 3 * kMillisecondsInHour);
auto td = w.ToTimeDelta();