Avi Drissman | 4a8573c | 2022-09-09 19:35:54 | [diff] [blame] | 1 | // Copyright 2021 The Chromium Authors |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Yeunjoo Choi | d33fdb6 | 2021-07-21 06:57:42 | [diff] [blame] | 5 | #ifndef CHROME_BROWSER_ASH_POLICY_SCHEDULED_TASK_HANDLER_DEVICE_SCHEDULED_REBOOT_HANDLER_H_ |
| 6 | #define CHROME_BROWSER_ASH_POLICY_SCHEDULED_TASK_HANDLER_DEVICE_SCHEDULED_REBOOT_HANDLER_H_ |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 7 | |
| 8 | #include <memory> |
| 9 | |
Artem Sumaneev | 9604473c | 2023-02-22 12:24:17 | [diff] [blame] | 10 | #include "base/memory/raw_ptr.h" |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 11 | #include "base/scoped_observation.h" |
Gabriel Charette | d87f10f | 2022-03-31 00:44:22 | [diff] [blame] | 12 | #include "base/time/time.h" |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 13 | #include "chrome/browser/ash/policy/scheduled_task_handler/reboot_notifications_scheduler.h" |
Yeunjoo Choi | d33fdb6 | 2021-07-21 06:57:42 | [diff] [blame] | 14 | #include "chrome/browser/ash/policy/scheduled_task_handler/scheduled_task_executor.h" |
| 15 | #include "chrome/browser/ash/policy/scheduled_task_handler/scoped_wake_lock.h" |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 16 | #include "chrome/browser/ash/settings/cros_settings.h" |
Henrique Ferreiro | 1eaedc4 | 2022-10-05 15:33:47 | [diff] [blame] | 17 | #include "chromeos/ash/components/settings/timezone_settings.h" |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 18 | #include "chromeos/dbus/power/power_manager_client.h" |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 19 | #include "services/device/public/mojom/wake_lock.mojom-forward.h" |
| 20 | #include "third_party/abseil-cpp/absl/types/optional.h" |
| 21 | #include "third_party/icu/source/i18n/unicode/timezone.h" |
| 22 | |
| 23 | namespace policy { |
| 24 | |
| 25 | // This class listens for changes in the scheduled reboot policy and then |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 26 | // manages recurring reboots based on the policy. |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 27 | class DeviceScheduledRebootHandler |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 28 | : public ash::system::TimezoneSettings::Observer, |
| 29 | chromeos::PowerManagerClient::Observer { |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 30 | public: |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 31 | DeviceScheduledRebootHandler( |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 32 | ash::CrosSettings* cros_settings, |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 33 | std::unique_ptr<ScheduledTaskExecutor> scheduled_task_executor, |
Artem Sumaneev | a6dcac2 | 2023-02-28 13:25:15 | [diff] [blame] | 34 | RebootNotificationsScheduler* notifications_scheduler); |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 35 | DeviceScheduledRebootHandler(const DeviceScheduledRebootHandler&) = delete; |
| 36 | DeviceScheduledRebootHandler& operator=(const DeviceScheduledRebootHandler&) = |
| 37 | delete; |
| 38 | ~DeviceScheduledRebootHandler() override; |
| 39 | |
| 40 | // TODO(https://crbug.com/1228718): Move Timezone observation to |
Yeunjoo Choi | f6e9d4a | 2021-11-10 02:50:28 | [diff] [blame] | 41 | // ScheduledTaskExecutor. ash::system::TimezoneSettings::Observer |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 42 | // implementation. |
| 43 | void TimezoneChanged(const icu::TimeZone& time_zone) override; |
| 44 | |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 45 | // Called when the power manager service becomes available. Reboot timer can |
| 46 | // only be started after this moment. |
| 47 | // chromeos::PowerManagerClient::Observer overrides: |
| 48 | void PowerManagerBecameAvailable(bool available) override; |
| 49 | |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 50 | // The tag associated to register |scheduled_task_executor_|. |
| 51 | static constexpr char kRebootTimerTag[] = "DeviceScheduledRebootHandler"; |
| 52 | |
Sanja Perisic | 345b52b6 | 2022-03-02 10:52:06 | [diff] [blame] | 53 | // Sets reboot delay for testing. |
| 54 | void SetRebootDelayForTest(const base::TimeDelta& reboot_delay); |
| 55 | |
Sanja Perisic | 3e1624a | 2022-08-22 14:22:00 | [diff] [blame] | 56 | // Returns value of |scheduled_reboot_data_|. |
| 57 | absl::optional<ScheduledTaskExecutor::ScheduledTaskData> |
| 58 | GetScheduledRebootDataForTest() const; |
| 59 | |
| 60 | // Returns value of |skip_reboot_|. |
| 61 | bool IsRebootSkippedForTest() const; |
| 62 | |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 63 | protected: |
Artem Sumaneev | 9604473c | 2023-02-22 12:24:17 | [diff] [blame] | 64 | using GetBootTimeCallback = base::RepeatingCallback<base::Time()>; |
| 65 | |
Artem Sumaneev | a6dcac2 | 2023-02-28 13:25:15 | [diff] [blame] | 66 | // Extended constructor for testing purposes. `cros_settings` and |
| 67 | // `notifications_scheduler` must outlive the handler. |
Artem Sumaneev | 9604473c | 2023-02-22 12:24:17 | [diff] [blame] | 68 | DeviceScheduledRebootHandler( |
| 69 | ash::CrosSettings* cros_settings, |
| 70 | std::unique_ptr<ScheduledTaskExecutor> scheduled_task_executor, |
Artem Sumaneev | a6dcac2 | 2023-02-28 13:25:15 | [diff] [blame] | 71 | RebootNotificationsScheduler* notifications_scheduler, |
Artem Sumaneev | 9604473c | 2023-02-22 12:24:17 | [diff] [blame] | 72 | GetBootTimeCallback get_boot_time_callback); |
| 73 | |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 74 | // Called when scheduled timer fires. Triggers a reboot and |
| 75 | // schedules the next reboot based on |scheduled_reboot_data_|. |
| 76 | virtual void OnRebootTimerExpired(); |
| 77 | |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 78 | // Called on button click on the reboot notification or dialog. Executes |
| 79 | // reboot instantly. |
| 80 | virtual void OnRebootButtonClicked(); |
| 81 | |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 82 | // Callback triggered when scheduled reboot setting has changed. |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 83 | virtual void OnScheduledRebootDataChanged(); |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 84 | |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 85 | private: |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 86 | // Calls |scheduled_task_executor_| to start the timer. Requires |
| 87 | // |scheduled_update_check_data_| to be set. |
| 88 | void StartRebootTimer(); |
| 89 | |
| 90 | // Called upon starting reboot timer. Indicates whether or not the |
| 91 | // timer was started successfully. |
| 92 | void OnRebootTimerStartResult(ScopedWakeLock scoped_wake_lock, bool result); |
| 93 | |
| 94 | // Reset all state and cancel all pending tasks |
| 95 | void ResetState(); |
| 96 | |
Sanja Perisic | 345b52b6 | 2022-03-02 10:52:06 | [diff] [blame] | 97 | // Returns random delay between 0 and maximum reboot delay set by |
| 98 | // ash::features::kDeviceForceScheduledRebootMaxDelay feature or |
| 99 | // |reboot_delay_for_testing_| if set. |
| 100 | const base::TimeDelta GetExternalDelay() const; |
| 101 | |
Sanja Perisic | 3c33f77 | 2022-03-04 14:18:54 | [diff] [blame] | 102 | void RebootDevice(const std::string& reboot_description) const; |
| 103 | |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 104 | // Used to retrieve Chrome OS settings. Not owned. |
Artem Sumaneev | 9604473c | 2023-02-22 12:24:17 | [diff] [blame] | 105 | const base::raw_ptr<ash::CrosSettings> cros_settings_; |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 106 | |
| 107 | // Subscription for callback when settings change. |
| 108 | base::CallbackListSubscription cros_settings_subscription_; |
| 109 | |
| 110 | // Currently active scheduled reboot policy. |
| 111 | absl::optional<ScheduledTaskExecutor::ScheduledTaskData> |
| 112 | scheduled_reboot_data_; |
| 113 | |
| 114 | // Timer that is scheduled to check for updates. |
| 115 | std::unique_ptr<ScheduledTaskExecutor> scheduled_task_executor_; |
Sanja Perisic | 345b52b6 | 2022-03-02 10:52:06 | [diff] [blame] | 116 | |
| 117 | // Delay added to scheduled reboot time, used for testing. |
| 118 | absl::optional<base::TimeDelta> reboot_delay_for_testing_; |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 119 | |
Artem Sumaneev | a6dcac2 | 2023-02-28 13:25:15 | [diff] [blame] | 120 | // Scheduler for reboot notification and dialog. Unowned. |
| 121 | base::raw_ptr<RebootNotificationsScheduler> notifications_scheduler_; |
Sanja Perisic | 660ac41 | 2022-03-02 12:07:05 | [diff] [blame] | 122 | |
| 123 | // Indicating if the reboot should be skipped. |
| 124 | bool skip_reboot_ = false; |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 125 | |
Artem Sumaneev | 9604473c | 2023-02-22 12:24:17 | [diff] [blame] | 126 | // Returns device's boot timestamp. The functor is used because the boot time |
| 127 | // is not constant and can change at runtime, e.g. because of the time |
| 128 | // sync. |
| 129 | GetBootTimeCallback get_boot_time_callback_; |
| 130 | |
Sanja Perisic | 5258dd20 | 2022-08-22 21:05:43 | [diff] [blame] | 131 | // Observation of chromeos::PowerManagerClient. |
| 132 | base::ScopedObservation<chromeos::PowerManagerClient, |
| 133 | chromeos::PowerManagerClient::Observer> |
| 134 | observation_{this}; |
Sanja Perisic | 24cabca | 2021-07-14 10:01:12 | [diff] [blame] | 135 | }; |
| 136 | |
| 137 | } // namespace policy |
| 138 | |
Yeunjoo Choi | d33fdb6 | 2021-07-21 06:57:42 | [diff] [blame] | 139 | #endif // CHROME_BROWSER_ASH_POLICY_SCHEDULED_TASK_HANDLER_DEVICE_SCHEDULED_REBOOT_HANDLER_H_ |