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
|
// Copyright 2022 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_POLICY_SCHEDULED_TASK_HANDLER_REBOOT_NOTIFICATIONS_SCHEDULER_H_
#define CHROME_BROWSER_ASH_POLICY_SCHEDULED_TASK_HANDLER_REBOOT_NOTIFICATIONS_SCHEDULER_H_
#include <optional>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/wall_clock_timer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/device_scheduled_reboot/reboot_notification_controller.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/session_manager/core/session_manager.h"
#include "components/session_manager/core/session_manager_observer.h"
namespace base {
class Clock;
class TickClock;
} // namespace base
namespace policy {
// This class schedules timers for showing pending reboot notification and
// dialog when scheduled reboot policy is set. The class also schedules
// post-reboot notification shown to the user after the policy reboot. If the
// full restore service is available for the user profile, post reboot
// notification is integrated with full restore notification. Otherwise, a
// simple post reboot notification is shown.
class RebootNotificationsScheduler
: public session_manager::SessionManagerObserver {
public:
// Represents the source of notification request. `kMaxValue` is used to
// determine the number of items, update it when adding a new item.
enum class Requester {
kScheduledRebootPolicy,
kRebootCommand,
kMaxValue = kRebootCommand
};
using RebootButtonCallback = base::OnceClosure;
RebootNotificationsScheduler();
RebootNotificationsScheduler(const RebootNotificationsScheduler&) = delete;
RebootNotificationsScheduler& operator=(const RebootNotificationsScheduler&) =
delete;
~RebootNotificationsScheduler() override;
// Returns current RebootNotificationsScheduler instance or NULL if it hasn't
// been initialized yet.
static RebootNotificationsScheduler* Get();
// Registers boolean pref for showing post reboot notification.
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
// Schedules timers for showing pending reboot notification and dialog or
// shows them right away if the scheduled reboot time is soon. If there
// already is a scheduled notification, either reschedules notification or
// puts the new one in the pending queue. Always picks the earliest
// notification from the queue and the new one.
void SchedulePendingRebootNotifications(
RebootButtonCallback reboot_button_callback,
const base::Time& reboot_time,
Requester requester);
// Sets pref for showing the post reboot notification for the active user.
void SchedulePostRebootNotification();
// Resets the state of `requester`. If it is the current requester showing
// notifications, takes another requester from the pending queue. Otherwise,
// removes `requester` from the pending queue if present.
void CancelRebootNotifications(Requester requester);
// SessionManagerObserver:
void OnUserSessionStarted(bool is_primary_user) override;
// Shows simple post reboot notification if |show_simple_notification| flag is
// set to true and unsets the pref for showing the post reboot notification.
void MaybeShowPostRebootNotification(bool show_simple_notification);
protected:
RebootNotificationsScheduler(const base::Clock* clock,
const base::TickClock* tick_clock);
// Runs |reboot_callback_| when user clicks on "Reboot now" button of the
// dialog or notification.
void OnRebootButtonClicked();
std::optional<Requester> GetCurrentRequesterForTesting() const;
std::vector<Requester> GetRequestersForTesting() const;
// Sets RebootNotificationsScheduler instance.
static void SetInstance(
RebootNotificationsScheduler* reboot_notifications_scheduler);
private:
// Queue of notification requests prioritized by reboot time from the earliest
// to the latest.
class RequestQueue;
void SchedulePendingRebootNotificationsForCurrentRequester();
virtual void MaybeShowPendingRebootNotification();
virtual void MaybeShowPendingRebootDialog();
// Returns prefs for active profile or nullptr.
virtual PrefService* GetPrefsForActiveProfile() const;
// Returns delay from now until |reboot_time|.
base::TimeDelta GetRebootDelay(const base::Time& reboot_time) const;
// Closes the pending reboot notification and the reboot dialog.
virtual void CloseNotifications();
// Returns true if the full restore service is available for the profile and
// we need to wait for full restore service initialization.
virtual bool ShouldWaitFullRestoreInit() const;
// Resets timers and closes notification and dialog if open.
void ResetNotificationState();
// Returns true if the pref for showing the post reboot notification is set in
// |prefs|.
static bool IsPostRebootPrefSet(PrefService* prefs);
// Pointer to the existing RebootNotificationsScheduler instance (if any). Not
// owned.
static RebootNotificationsScheduler* instance;
std::unique_ptr<RequestQueue> requester_queue_;
// Timers for scheduling notification or dialog displaying.
base::WallClockTimer notification_timer_, dialog_timer_;
// Controller responsible for creating notifications and dialog.
RebootNotificationController notification_controller_;
base::ScopedObservation<session_manager::SessionManager,
session_manager::SessionManagerObserver>
observation_{this};
raw_ptr<const base::Clock> clock_;
base::WeakPtrFactory<RebootNotificationsScheduler> weak_ptr_factory_{this};
};
} // namespace policy
#endif // CHROME_BROWSER_ASH_POLICY_SCHEDULED_TASK_HANDLER_REBOOT_NOTIFICATIONS_SCHEDULER_H_
|