File: graduation_utils.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (148 lines) | stat: -rw-r--r-- 4,342 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/edusumer/graduation_utils.h"

#include <optional>

#include "ash/constants/ash_pref_names.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/prefs/pref_service.h"

namespace ash::graduation {

namespace {
// Dictionary keys used for accessing kGraduationEnablementStatus pref values.
constexpr char kIsEnabledKey[] = "is_enabled";
constexpr char kStartDateKey[] = "start_date";
constexpr char kEndDateKey[] = "end_date";
constexpr char kDayKey[] = "day";
constexpr char kMonthKey[] = "month";
constexpr char kYearKey[] = "year";

// Returns a Time object representing a date at local midnight if the date is
// valid. Returns std::nullopt if the date is invalid.
std::optional<base::Time> GetLocalMidnightTimeForDate(
    const base::Value::Dict* date) {
  CHECK(date);
  std::optional<int> day = date->FindInt(kDayKey);
  std::optional<int> month = date->FindInt(kMonthKey);
  std::optional<int> year = date->FindInt(kYearKey);
  if (!day || !month || !year) {
    return std::nullopt;
  }

  base::Time::Exploded exploded;
  exploded.day_of_month = *day;
  exploded.month = *month;
  exploded.year = *year;
  exploded.hour = 0;
  exploded.minute = 0;
  exploded.second = 0;
  exploded.millisecond = 0;

  base::Time time;
  bool date_exists = base::Time::FromLocalExploded(exploded, &time);
  if (!date_exists) {
    return std::nullopt;
  }
  return time.LocalMidnight();
}

// Returns true if the `is_enabled` key in the policy is set to true.
bool IsPolicyEnabled(const base::Value::Dict& graduation_policy_pref) {
  if (graduation_policy_pref.empty()) {
    return false;
  }

  bool is_enabled =
      graduation_policy_pref.FindBool(kIsEnabledKey).value_or(false);
  return is_enabled;
}
}  // namespace

bool HasUpcomingGraduationEnablementChange(PrefService* pref_service) {
  CHECK(pref_service);
  const base::Value::Dict& graduation_policy_pref =
      pref_service->GetDict(prefs::kGraduationEnablementStatus);
  if (!IsPolicyEnabled(graduation_policy_pref)) {
    return false;
  }

  base::Time current_time = base::Time::Now().LocalMidnight();

  const base::Value::Dict* start_date_dict =
      graduation_policy_pref.FindDict(kStartDateKey);
  bool is_future_start_time = false;

  if (start_date_dict) {
    std::optional<base::Time> start_time =
        GetLocalMidnightTimeForDate(start_date_dict);
    if (!start_time) {
      return false;
    }
    is_future_start_time = current_time < *start_time;
  }

  const base::Value::Dict* end_date_dict =
      graduation_policy_pref.FindDict(kEndDateKey);
  bool is_future_end_time = false;

  if (end_date_dict) {
    std::optional<base::Time> end_time =
        GetLocalMidnightTimeForDate(end_date_dict);
    if (!end_time) {
      return false;
    }
    // Since the app availability period is inclusive of the end date, the app
    // should be enabled until the day after the end date.
    is_future_end_time = current_time <= *end_time;
  }

  return is_future_start_time || is_future_end_time;
}

bool IsEligibleForGraduation(PrefService* pref_service) {
  CHECK(pref_service);
  const base::Value::Dict& graduation_policy_pref =
      pref_service->GetDict(prefs::kGraduationEnablementStatus);
  if (!IsPolicyEnabled(graduation_policy_pref)) {
    return false;
  }

  // Compare the current date at local midnight time to the start and end dates
  // at local midnight time.
  base::Time current_time = base::Time::Now().LocalMidnight();

  const base::Value::Dict* start_date_dict =
      graduation_policy_pref.FindDict(kStartDateKey);
  if (start_date_dict) {
    std::optional<base::Time> start_time =
        GetLocalMidnightTimeForDate(start_date_dict);
    if (!start_time) {
      return false;
    }
    if (current_time < *start_time) {
      return false;
    }
  }

  const base::Value::Dict* end_date_dict =
      graduation_policy_pref.FindDict(kEndDateKey);
  if (end_date_dict) {
    std::optional<base::Time> end_time =
        GetLocalMidnightTimeForDate(end_date_dict);
    if (!end_time) {
      return false;
    }
    if (current_time > *end_time) {
      return false;
    }
  }

  return true;
}
}  // namespace ash::graduation