1 // Copyright 2017 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 #ifndef CHROMEOS_POLICY_WEEKLY_TIME_WEEKLY_TIME_H_
6 #define CHROMEOS_POLICY_WEEKLY_TIME_WEEKLY_TIME_H_
7 
8 #include <memory>
9 
10 #include "base/optional.h"
11 #include "base/time/clock.h"
12 #include "base/time/time.h"
13 #include "base/values.h"
14 #include "chromeos/chromeos_export.h"
15 #include "components/policy/proto/chrome_device_policy.pb.h"
16 
17 namespace policy {
18 
19 // WeeklyTime class contains day of week and time. Day of week is number from 1
20 // to 7 (1 = Monday, 2 = Tuesday, etc.) Time is in milliseconds from the
21 // beginning of the day.
22 class CHROMEOS_EXPORT WeeklyTime {
23  public:
24   // Dictionary value key constants for testing.
25   static const char kDayOfWeek[];
26   static const char kTime[];
27   static const char kTimezoneOffset[];
28 
29   WeeklyTime(int day_of_week,
30              int milliseconds,
31              base::Optional<int> timezone_offset);
32 
33   WeeklyTime(const WeeklyTime& rhs);
34 
35   WeeklyTime& operator=(const WeeklyTime& rhs);
36 
37   bool operator==(const WeeklyTime& rhs) const {
38     return day_of_week_ == rhs.day_of_week() &&
39            milliseconds_ == rhs.milliseconds() &&
40            timezone_offset_ == rhs.timezone_offset();
41   }
42 
43   // Return DictionaryValue in format:
44   // { "day_of_week" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday,
45   // etc.)
46   //   "time" : int # in milliseconds from the beginning of the day.
47   // }
48   std::unique_ptr<base::DictionaryValue> ToValue() const;
49 
day_of_week()50   int day_of_week() const { return day_of_week_; }
51 
milliseconds()52   int milliseconds() const { return milliseconds_; }
53 
timezone_offset()54   base::Optional<int> timezone_offset() const { return timezone_offset_; }
55 
56   // Return duration from |start| till |end| week times. |end| time
57   // is always after |start| time. It's possible because week time is cyclic.
58   // (i.e. [Friday 17:00, Monday 9:00) )
59   // Both WeeklyTimes have to have the same kind of timezone (timezone agnostic
60   // or set timezone).
61   base::TimeDelta GetDurationTo(const WeeklyTime& other) const;
62 
63   // Add milliseconds to WeeklyTime.
64   WeeklyTime AddMilliseconds(int milliseconds) const;
65 
66   // Creates a new WeeklyTime from the current one that has
67   // |timezone_offset_| set to |timezone_offset|. Furthermore, the new
68   // WeeklyTime is offset based on the difference between the timezones. This
69   // function should only take in WeeklyTimes with a defined timezone (i.e. not
70   // nullopt).
71   WeeklyTime ConvertToTimezone(int timezone_offset) const;
72 
73   // Creates a new WeeklyTime that has |timezone_offset_| set to
74   // |timezone_offset|. This function is to be used to set the timezone of
75   // timezone agnostic WeeklyTime objects, i.e. objects where |timezone_offset_|
76   // == nullopt.
77   WeeklyTime ConvertToCustomTimezone(int timezone_offset) const;
78 
79   // Return WeeklyTime structure from WeeklyTimeProto. Return nullptr if
80   // WeeklyTime structure isn't correct.
81   static std::unique_ptr<WeeklyTime> ExtractFromProto(
82       const enterprise_management::WeeklyTimeProto& container,
83       base::Optional<int> timezone_offset);
84 
85   // Return WeeklyTime structure from Value in format:
86   // { "day_of_week" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday,
87   // etc.)
88   //   "time" : int # in milliseconds from the beginning of the day.
89   // }.
90   // Return nullptr if WeeklyTime structure isn't correct.
91   static std::unique_ptr<WeeklyTime> ExtractFromValue(
92       const base::Value* value,
93       base::Optional<int> timezone_offset);
94 
95   // Return the current time in GMT in WeeklyTime structure.
96   static WeeklyTime GetCurrentGmtWeeklyTime(base::Clock* clock);
97 
98   // Return the current time in the system's local time in WeeklyTime structure.
99   static WeeklyTime GetCurrentLocalWeeklyTime(base::Clock* clock);
100 
101  private:
102   // Number of weekday (1 = Monday, 2 = Tuesday, etc.)
103   int day_of_week_;
104 
105   // Time of day in milliseconds from the beginning of the day.
106   int milliseconds_;
107 
108   // Offset from GMT in milliseconds for the timezone that the Weekly Time is
109   // in. If |timezone_offset_| is 0 then it the WeeklyTime will be considered to
110   // be in GMT. If |timezone_offset_| is non-zero, then the WeeklyTime will be
111   // considered to be in the timezone corresponding to that offset. If
112   // |timezone_offset_| is |nullopt|, then it will be interpreted to be in the
113   // system's local timezone.
114   base::Optional<int> timezone_offset_;
115 };
116 
117 }  // namespace policy
118 
119 #endif  // CHROMEOS_POLICY_WEEKLY_TIME_WEEKLY_TIME_H_
120