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 #ifndef CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TYPES_H_
6 #define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TYPES_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/optional.h"
12 #include "base/time/time.h"
13 #include "components/services/app_service/public/mojom/types.mojom.h"
14 
15 namespace chromeos {
16 namespace app_time {
17 
18 // Type of usage restriction that can be applied to the installed app.
19 enum class AppRestriction {
20   kUnknown,
21   // Installed app is not available for the user.
22   kBlocked,
23   // Daily time limit is enforced. Installed app will become unavailable for
24   // the user after time limit is reached on a given day.
25   kTimeLimit,
26 };
27 
28 // State of the app. Used for activity recording and status reporting. The enum
29 // values are persisted in user pref service. Existing values should never be
30 // deleted or reordered. New states should be appended at the end.
31 enum class AppState {
32   // App is available for the user.
33   kAvailable = 0,
34   // App cannot be restricted. Used for important system apps.
35   kAlwaysAvailable = 1,
36   // App is not available for the user because of being blocked.
37   kBlocked = 2,
38   // App is not available for the user because daily time limit was reached.
39   kLimitReached = 3,
40   // App is uninstalled. Activity might still be preserved and reported for
41   // recently uninstalled apps.
42   kUninstalled = 4,
43 };
44 
45 // Type of notification to show the child user.
46 enum class AppNotification {
47   kUnknown,
48 
49   // Five minutes left before the application's time limit is reached.
50   kFiveMinutes,
51 
52   // One minjute left before the application's time limit is reached.
53   kOneMinute,
54 
55   // Application's time limit reached.
56   kTimeLimitReached,
57 
58   // Application's time limit has been updated by parents.
59   kTimeLimitChanged,
60 
61   // Application is blocked.
62   kBlocked,
63 
64   // Application is unblocked.
65   kAvailable
66 };
67 
68 enum class ChromeAppActivityState {
69   // The browser is active and hosts urls in its active tab which are not
70   // allowlisted.
71   kActive,
72 
73   // Same as |kActive| except the urls the browser hosts are allowlisted.
74   kActiveAllowlisted,
75 
76   // The browser window is not active.
77   kInactive,
78 };
79 
80 // Identifies an app for app time limits.
81 // Different types of use different identifier format. ARC++ apps are identified
82 // by Android package name. Other types of apps use 32 character long Chrome
83 // specific app id.
84 class AppId {
85  public:
86   AppId(apps::mojom::AppType app_type, const std::string& app_id);
87   AppId(const AppId&);
88   AppId& operator=(const AppId&);
89   AppId(AppId&&);
90   AppId& operator=(AppId&&);
91   ~AppId();
92 
app_type()93   apps::mojom::AppType app_type() const { return app_type_; }
app_id()94   const std::string& app_id() const { return app_id_; }
95 
96   bool operator==(const AppId&) const;
97   bool operator!=(const AppId&) const;
98   bool operator<(const AppId&) const;
99   friend std::ostream& operator<<(std::ostream&, const AppId&);
100 
101  private:
102   apps::mojom::AppType app_type_ = apps::mojom::AppType::kUnknown;
103 
104   // Package name for |ARC| apps, 32 character long Chrome specific app id
105   // otherwise.
106   std::string app_id_;
107 };
108 
109 struct PauseAppInfo {
110   PauseAppInfo(const AppId& app, base::TimeDelta limit, bool show_dialog);
111 
112   AppId app_id;
113   base::TimeDelta daily_limit;
114   bool show_pause_dialog = true;
115 };
116 
117 // Represents restriction that can be applied to an installed app.
118 class AppLimit {
119  public:
120   // Creates AppLimit.
121   // |daily_limit| can only be set when |restriction| is kTimeLimit.
122   // |daily_limit| needs to be in range of [0, 24] hours.
123   AppLimit(AppRestriction restriction,
124            base::Optional<base::TimeDelta> daily_limit,
125            base::Time last_updated);
126   AppLimit(const AppLimit&);
127   AppLimit& operator=(const AppLimit&);
128   AppLimit(AppLimit&&);
129   AppLimit& operator=(AppLimit&&);
130   ~AppLimit();
131 
restriction()132   AppRestriction restriction() const { return restriction_; }
last_updated()133   base::Time last_updated() const { return last_updated_; }
daily_limit()134   const base::Optional<base::TimeDelta>& daily_limit() const {
135     return daily_limit_;
136   }
137 
138  private:
139   // Usage restriction applied to the app.
140   AppRestriction restriction_ = AppRestriction::kUnknown;
141 
142   // Daily usage limit. Only set |restriction| is kTimeLimit.
143   // Has to be between 0 and 24 hours.
144   base::Optional<base::TimeDelta> daily_limit_;
145 
146   // UTC timestamp for the last time the limit was updated.
147   base::Time last_updated_;
148 };
149 
150 // Contains information about app usage.
151 class AppActivity {
152  public:
153   class ActiveTime {
154    public:
155     static const base::TimeDelta kActiveTimeMergePrecision;
156 
157     // If |t1| and |t2| overlap or are within |kActiveTimeMergePrecision| of
158     // each other, this static method creates a new ActiveTime with the earlier
159     // of |t1|'s or |t2|'s |active_from| and the later of |t1|'s or |t2|'s
160     // |active_to_|.
161     static base::Optional<ActiveTime> Merge(const ActiveTime& t1,
162                                             const ActiveTime& t2);
163 
164     ActiveTime(base::Time start, base::Time end);
165     ActiveTime(const ActiveTime& rhs);
166     ActiveTime& operator=(const ActiveTime& rhs);
167 
168     bool operator==(const ActiveTime&) const;
169     bool operator!=(const ActiveTime&) const;
170 
171     // Returns whether |timestamp| is included in this time period.
172     bool Contains(base::Time timestamp) const;
173 
174     // Returns whether |timestamp| is earlier than this time period's start.
175     bool IsEarlierThan(base::Time timestamp) const;
176 
177     // Returns whether |timestamp| is later than this time period's end.
178     bool IsLaterThan(base::Time timestamp) const;
179 
active_from()180     base::Time active_from() const { return active_from_; }
181     void set_active_from(base::Time active_from);
active_to()182     base::Time active_to() const { return active_to_; }
183     void set_active_to(base::Time active_to);
184 
185    private:
186     base::Time active_from_;
187     base::Time active_to_;
188   };
189 
190   // Creates AppActivity and sets current |app_state_|.
191   explicit AppActivity(AppState app_state);
192   AppActivity(AppState app_state, base::TimeDelta running_active_time);
193   AppActivity(const AppActivity&);
194   AppActivity& operator=(const AppActivity&);
195   AppActivity(AppActivity&&);
196   AppActivity& operator=(AppActivity&&);
197   ~AppActivity();
198 
199   void SetAppState(AppState app_state);
200   void SetAppActive(base::Time timestamp);
201   void SetAppInactive(base::Time timestamp);
202 
203   // Called when reset time has been reached.
204   // Resets |running_active_time_|.
205   // If the application is currently running, uses |timestamp| as current time
206   // to log activity.
207   void ResetRunningActiveTime(base::Time timestamp);
208 
209   base::TimeDelta RunningActiveTime() const;
210 
211   // Updates |active_times_| to include the current activity. If the app is
212   // active, it saves the activitity until |timestamp|.
213   void CaptureOngoingActivity(base::Time timestamp);
214 
215   // Caller takes ownership of |active_times_| i.e. |active_times_| is moved and
216   // thus becomes empty after this method is called. Called from
217   // AppActivityRegistry::SaveAppActivity when the app activity is going to be
218   // saved in user preference.
219   std::vector<ActiveTime> TakeActiveTimes();
220 
is_active()221   bool is_active() const { return is_active_; }
app_state()222   AppState app_state() const { return app_state_; }
active_times()223   const std::vector<ActiveTime>& active_times() const { return active_times_; }
last_notification()224   AppNotification last_notification() const { return last_notification_; }
225 
set_last_notification(AppNotification notification)226   void set_last_notification(AppNotification notification) {
227     last_notification_ = notification;
228   }
229 
230   // Chrome and web apps share the same time limit. Therefore, we need to have a
231   // consistent |running_active_time_| across all web apps and chrome.
set_running_active_time(base::TimeDelta time)232   void set_running_active_time(base::TimeDelta time) {
233     DCHECK(!is_active_);
234     running_active_time_ = time;
235   }
236 
237  private:
238   // boolean to specify if the application is active.
239   bool is_active_ = false;
240 
241   AppNotification last_notification_ = AppNotification::kUnknown;
242 
243   // Current state of the app.
244   // There might be relevant activity recoded for app that was uninstalled
245   // recently.
246   AppState app_state_ = AppState::kAvailable;
247 
248   // Keeps the sum of the active times since the last reset.
249   base::TimeDelta running_active_time_;
250 
251   // The time app was active.
252   std::vector<ActiveTime> active_times_;
253 
254   // Time tick for the last time the activity was updated.
255   base::TimeTicks last_updated_time_ticks_;
256 };
257 
258 }  // namespace app_time
259 }  // namespace chromeos
260 
261 #endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TYPES_H_
262