File: app_activity_registry.h

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 (338 lines) | stat: -rw-r--r-- 13,391 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_CHILD_ACCOUNTS_TIME_LIMITS_APP_ACTIVITY_REGISTRY_H_
#define CHROME_BROWSER_ASH_CHILD_ACCOUNTS_TIME_LIMITS_APP_ACTIVITY_REGISTRY_H_

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/child_accounts/time_limits/app_activity_report_interface.h"
#include "chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.h"
#include "chrome/browser/ash/child_accounts/time_limits/app_types.h"

namespace base {
class UnguessableToken;
}  // namespace base

namespace enterprise_management {
class ChildStatusReportRequest;
}  // namespace enterprise_management

class PrefRegistrySimple;
class PrefService;

namespace ash {
namespace app_time {

class AppTimeLimitsAllowlistPolicyWrapper;
class AppTimeNotificationDelegate;
class PersistedAppInfo;

// Keeps track of app activity and time limits information.
// Stores app activity between user session. Information about uninstalled apps
// are removed from the registry after activity was uploaded to server or after
// 30 days if upload did not happen.
class AppActivityRegistry : public AppServiceWrapper::EventListener {
 public:
  // Used for tests to get internal implementation details.
  class TestApi {
   public:
    explicit TestApi(AppActivityRegistry* registry);
    ~TestApi();

    const std::optional<AppLimit>& GetAppLimit(const AppId& app_id) const;
    std::optional<base::TimeDelta> GetTimeLeft(const AppId& app_id) const;
    void SaveAppActivity();

   private:
    const raw_ptr<AppActivityRegistry, DanglingUntriaged> registry_;
  };

  // Interface for the observers interested in the changes of apps state.
  class AppStateObserver : public base::CheckedObserver {
   public:
    AppStateObserver() = default;
    AppStateObserver(const AppStateObserver&) = delete;
    AppStateObserver& operator=(const AppStateObserver&) = delete;
    ~AppStateObserver() override = default;

    // Called when state of the app with |app_id| changed to |kLimitReached|.
    // |was_active| indicates whether the app was active before reaching the
    // limit.
    virtual void OnAppLimitReached(const AppId& app_id,
                                   base::TimeDelta time_limit,
                                   bool was_active) = 0;

    // Called when state of the app with |app_id| is no longer |kLimitReached|.
    virtual void OnAppLimitRemoved(const AppId& app_id) = 0;

    // Called when new app was installed.
    virtual void OnAppInstalled(const AppId& app_id) = 0;
  };

  static void RegisterProfilePrefs(PrefRegistrySimple* registry);

  AppActivityRegistry(AppServiceWrapper* app_service_wrapper,
                      AppTimeNotificationDelegate* notification_delegate,
                      PrefService* pref_service);
  AppActivityRegistry(const AppActivityRegistry&) = delete;
  AppActivityRegistry& operator=(const AppActivityRegistry&) = delete;
  ~AppActivityRegistry() override;

  // AppServiceWrapper::EventListener:
  void OnAppInstalled(const AppId& app_id) override;
  void OnAppUninstalled(const AppId& app_id) override;
  void OnAppAvailable(const AppId& app_id) override;
  void OnAppBlocked(const AppId& app_id) override;
  void OnAppActive(const AppId& app_id,
                   const base::UnguessableToken& instance_id,
                   base::Time timestamp) override;
  void OnAppInactive(const AppId& app_id,
                     const base::UnguessableToken& instance_id,
                     base::Time timestamp) override;
  void OnAppDestroyed(const AppId& app_id,
                      const base::UnguessableToken& instance_id,
                      base::Time timestamp) override;

  bool IsAppInstalled(const AppId& app_id) const;
  bool IsAppAvailable(const AppId& app_id) const;
  bool IsAppBlocked(const AppId& app_id) const;
  bool IsAppTimeLimitReached(const AppId& app_id) const;
  bool IsAppActive(const AppId& app_id) const;
  bool IsAllowlistedApp(const AppId& app_id) const;

  // Manages AppStateObservers.
  void AddAppStateObserver(AppStateObserver* observer);
  void RemoveAppStateObserver(AppStateObserver* observer);

  // Called from AppTimeController to notify AppActivityRegistry about installed
  // apps which AppActivityRegistry may have missed.
  void SetInstalledApps(const std::vector<AppId>& installed_apps);

  // Returns the total active time for the application since the last time limit
  // reset.
  base::TimeDelta GetActiveTime(const AppId& app_id) const;

  // Web time limit is the time limit set for Chrome browser. It is shared
  // between Chrome and Web apps.
  const std::optional<AppLimit>& GetWebTimeLimit() const;

  AppState GetAppState(const AppId& app_id) const;

  // Returns current time limit for the app identified by |app_id|.
  // Will return nullopt if there is no limit set.
  std::optional<base::TimeDelta> GetTimeLimit(const AppId& app_id) const;

  // Reporting enablement is set if |enabled| has value.
  void SetReportingEnabled(std::optional<bool> enabled);

  void GenerateHiddenApps(
      enterprise_management::ChildStatusReportRequest* report);

  // Populates |report| with collected app activity. Returns whether any data
  // were reported.
  AppActivityReportInterface::ReportParams GenerateAppActivityReport(
      enterprise_management::ChildStatusReportRequest* report);

  // Application activities earlier than |timestamp| have been reported. Clear
  // entries earlier than |timestamp|.
  void OnSuccessfullyReported(base::Time timestamp);

  // Updates time limits for all installed apps.
  // Apps not present in |app_limits| are treated as they do not have limit set.
  // Returns true if a new app limit is observed in any of the applications.
  bool UpdateAppLimits(const std::map<AppId, AppLimit>& app_limits);

  // Sets time limit for app identified with |app_id|.
  // Does not affect limits of any other app. Not specified |app_limit| means
  // that app does not have limit set. Does not affect limits of any other app.
  // Returns true if a new app limit is observed.
  bool SetAppLimit(const AppId& app_id,
                   const std::optional<AppLimit>& app_limit);

  // Sets the app identified with |app_id| as being always available.
  void SetAppAllowlisted(const AppId& app_id);

  // Reset time has been reached at |timestamp|.
  void OnResetTimeReached(base::Time timestamp);

  // Called from WebTimeActivityProvider to update chrome app state.
  void OnChromeAppActivityChanged(ChromeAppActivityState state,
                                  base::Time timestamp);

  // Allowlisted applications changed. Called by AppTimeController.
  void OnTimeLimitAllowlistChanged(
      const AppTimeLimitsAllowlistPolicyWrapper& wrapper);

  // Saves app activity into user preference.
  void SaveAppActivity();

  std::vector<AppId> GetAppsWithAppRestriction(
      AppRestriction restriction) const;

 private:
  struct SystemNotification {
    SystemNotification(std::optional<base::TimeDelta> app_time_limit,
                       AppNotification app_notification);
    SystemNotification(const SystemNotification&);
    SystemNotification& operator=(const SystemNotification&);
    std::optional<base::TimeDelta> time_limit = std::nullopt;
    AppNotification notification = AppNotification::kUnknown;
  };

  // Bundles detailed data stored for a specific app.
  struct AppDetails {
    AppDetails();
    explicit AppDetails(const AppActivity& activity);
    AppDetails(const AppDetails&) = delete;
    AppDetails& operator=(const AppDetails&) = delete;
    ~AppDetails();

    // Resets the time limit check timer.
    void ResetTimeCheck();

    // Checks |limit| and |activity| to determine if the limit was reached.
    bool IsLimitReached() const;

    // Checks if |limit| is equal to |another_limit| with exception for the
    // timestamp (that does not indicate that limit changed).
    bool IsLimitEqual(const std::optional<AppLimit>& another_limit) const;

    // Contains information about current app state and logged activity.
    AppActivity activity{AppState::kAvailable};

    // Contains the set of active instances for the application.
    std::set<base::UnguessableToken> active_instances;

    // The set of instances AppActivityRegistry has requested to be paused, but
    // which have not been paused yet.
    std::set<base::UnguessableToken> paused_instances;

    // Contains information about restriction set for the app.
    std::optional<AppLimit> limit;

    // Timer set up for when the app time limit is expected to be reached and
    // preceding notifications.
    std::unique_ptr<base::OneShotTimer> app_limit_timer;

    // Boolean to specify if OnAppInstalled call has been received for this
    // particular application.
    bool received_app_installed_ = false;

    // At the beginning of a session, we may want to send system notifications
    // for applications. This may happen if there is an update in
    // PerAppTimeLimits policy while the user was logged out. In these
    // scenarios, we have to wait until the application is installed.
    std::vector<SystemNotification> pending_notifications_;
  };

  // OnAppReinstalled is called when an application has been uninstalled and
  // then installed again before being removed from app registry.
  void OnAppReinstalled(const AppId& app_id);

  // Removes data older than |timestamp| from the registry.
  // Removes entries for uninstalled apps if there is no more relevant activity
  // data left.
  void CleanRegistry(base::Time timestamp);

  // Adds an ap to the registry if it does not exist.
  void Add(const AppId& app_id);

  // Convenience methods to access state of the app identified by |app_id|.
  // Should only be called if app exists in the registry.
  void SetAppState(const AppId& app_id, AppState app_state);

  // Notifies state observers the application identified by |app_id| has reached
  // its set time limit.
  void NotifyLimitReached(const AppId& app_id, bool was_active);

  // Methods to set the application as active and inactive respectively.
  void SetAppActive(const AppId& app_id, base::Time timestamp);
  void SetAppInactive(const AppId& app_id, base::Time timestamp);

  std::optional<base::TimeDelta> GetTimeLeftForApp(const AppId& app_id) const;

  // Schedules a time limit check for application when it becomes active.
  void ScheduleTimeLimitCheckForApp(const AppId& app_id);

  // Checks the limit and shows notification if needed.
  void CheckTimeLimitForApp(const AppId& app_id);

  // Shows notification about time limit updates for the app if there were
  // relevant changes between |old_limit| and |new_limit|. Returns true if a
  // notification has been made.
  bool ShowLimitUpdatedNotificationIfNeeded(
      const AppId& app_id,
      const std::optional<AppLimit>& old_limit,
      const std::optional<AppLimit>& new_limit);

  base::TimeDelta GetWebActiveRunningTime() const;

  void WebTimeLimitReached(base::Time timestamp);

  // Initializes |activity_registry_| from the stored values in user pref.
  // Installed applications, their AppStates and their running active times will
  // be restored.
  void InitializeRegistryFromPref();
  void InitializeAppActivities();

  // Updates |AppActivity::active_times_| to include the current activity up to
  // |timestamp| then creates the most up to date instance of PersistedAppInfo.
  PersistedAppInfo GetPersistedAppInfoForApp(const AppId& app_id,
                                             base::Time timestamp);

  // Returns true if the last successfully reported time is earlier than 30 days
  // from base::Time::Now();
  bool ShouldCleanUpStoredPref();

  // Sends system notification for the application.
  void SendSystemNotificationsForApp(const AppId& app_id);

  // Shows notification or queues it to be shown later.
  void MaybeShowSystemNotification(const AppId& app_id,
                                   const SystemNotification& notification);

  // Called by AppActivityRegistry::SetAppLimit after the application's limit
  // has been updated.
  void AppLimitUpdated(const AppId& app_id);

  const raw_ptr<PrefService> pref_service_;

  // Owned by AppTimeController.
  const raw_ptr<AppServiceWrapper> app_service_wrapper_;

  // Notification delegate.
  const raw_ptr<AppTimeNotificationDelegate> notification_delegate_;

  // Observers to be notified about app state changes.
  base::ObserverList<AppStateObserver> app_state_observers_;

  std::map<AppId, AppDetails> activity_registry_;

  // Newly installed applications which have not yet been added to the user
  // pref.
  std::vector<AppId> newly_installed_apps_;

  // Repeating timer to trigger saving app activity to pref service.
  base::RepeatingTimer save_data_to_pref_service_;

  // This records the timestamp of the latest set app limit.
  base::Time latest_app_limit_update_;

  // Boolean to capture if app activity data reporting is enabled.
  bool activity_reporting_enabled_ = true;
};

}  // namespace app_time
}  // namespace ash

#endif  // CHROME_BROWSER_ASH_CHILD_ACCOUNTS_TIME_LIMITS_APP_ACTIVITY_REGISTRY_H_