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_
|