| // Copyright 2015 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_REMOTE_COMMANDS_DEVICE_COMMAND_REBOOT_JOB_H_ |
| #define CHROME_BROWSER_ASH_POLICY_REMOTE_COMMANDS_DEVICE_COMMAND_REBOOT_JOB_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/functional/callback.h" |
| #include "base/location.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 "chromeos/dbus/power/power_manager_client.h" |
| #include "components/policy/core/common/remote_commands/remote_command_job.h" |
| |
| namespace ash { |
| class LoginState; |
| class SessionTerminationManager; |
| } // namespace ash |
| |
| namespace base { |
| class Clock; |
| class TickClock; |
| } // namespace base |
| |
| namespace policy { |
| |
| class RebootNotificationsScheduler; |
| |
| // Reboots a device with regards to its current mode. See |
| // go/cros-reboot-command-dd for detailed design. Handles the following cases: |
| // * If the device was booted after the command was issued: does not reboot and |
| // reports success. |
| // * If the power manager service is unavailable, reports failure. |
| // * If the devices runs in a kiosk mode, reports success and reboots |
| // immediately. |
| // * If the device runs in a regular mode: |
| // * If there is no logged in user, reports success and reboots immediately. |
| // * If a user is logged in, notifies the user, waits for a timeout, reports |
| // success and reboots. |
| // * If the user signs out during the timeout, reports success and reboots. |
| class DeviceCommandRebootJob : public RemoteCommandJob, |
| public chromeos::PowerManagerClient::Observer { |
| public: |
| DeviceCommandRebootJob(); |
| |
| DeviceCommandRebootJob(const DeviceCommandRebootJob&) = delete; |
| DeviceCommandRebootJob& operator=(const DeviceCommandRebootJob&) = delete; |
| |
| ~DeviceCommandRebootJob() override; |
| |
| // RemoteCommandJob: |
| enterprise_management::RemoteCommand_Type GetType() const override; |
| |
| // chromeos::PowerManagerClient::Observer: |
| void PowerManagerBecameAvailable(bool available) override; |
| |
| protected: |
| using GetBootTimeCallback = base::RepeatingCallback<base::TimeTicks()>; |
| |
| // Extended constructor for testing puproses. |
| // Extended constructor for testing puproses. `power_manager_client`, |
| // `loging_state`, `session_termination_manager`, |
| // `in_session_notifications_scheduler`, `clock` and `tick_clock` must |
| // outlive the job. |
| DeviceCommandRebootJob( |
| chromeos::PowerManagerClient* power_manager_client, |
| ash::LoginState* loging_state, |
| ash::SessionTerminationManager* session_termination_manager, |
| RebootNotificationsScheduler* in_session_notifications_scheduler, |
| const base::Clock* clock, |
| const base::TickClock* tick_clock, |
| GetBootTimeCallback get_boot_time_callback); |
| |
| private: |
| // Posts a task with a callback. Command's callbacks cannot be run |
| // synchronously from `RunImpl`. |
| static void RunAsyncCallback(CallbackWithResult callback, |
| ResultType result, |
| base::Location from_where); |
| |
| // RemoteCommandJob: |
| void RunImpl(CallbackWithResult result_callback) override; |
| |
| // Handles reboot with an active user. Shows a reboot notification, waits for |
| // the timeout or sign out, and reboots. |
| void RebootUserSession(); |
| |
| // Called when `session_termination_manager_` is about to reboot on signout. |
| void OnSignout(); |
| |
| // Called when a user clicks reboot button on the reboot dialog. |
| void OnRebootButtonClicked(); |
| |
| void OnRebootTimeoutExpired(); |
| |
| // Reports success and initiates a reboot request with given `reason`. |
| // Shall be called once. |
| void DoReboot(const std::string& reason); |
| |
| // Unsubscribes from events that trigger reboot, e.g. in-session timer. |
| void ResetTriggeringEvents(); |
| |
| // Sends the reboot request to power manager service. Unowned. |
| const base::raw_ptr<chromeos::PowerManagerClient> power_manager_client_; |
| // Checks the availability of `power_manager_client_`. |
| base::ScopedObservation<chromeos::PowerManagerClient, DeviceCommandRebootJob> |
| power_manager_availability_observation_{this}; |
| |
| // Provides information about current logins status and device mode to |
| // determine how to proceed with the reboot. |
| const base::raw_ptr<ash::LoginState> login_state_; |
| |
| // Handles reboot on signout. |
| base::raw_ptr<ash::SessionTerminationManager> session_termination_manager_; |
| |
| // Scheduler for reboot notification and dialog. Unowned. |
| base::raw_ptr<RebootNotificationsScheduler> |
| in_session_notifications_scheduler_; |
| // Timer tracking the delayed reboot event. |
| base::WallClockTimer in_session_reboot_timer_; |
| |
| // Clock to schedule in-user-session reboot delay. Can be mocked for testing. |
| // Unowned. |
| base::raw_ptr<const base::Clock> clock_; |
| |
| // Returns device's boot timestamp. The boot time is not constant and may |
| // change at runtime, e.g. because of time sync. |
| const GetBootTimeCallback get_boot_time_callback_; |
| |
| CallbackWithResult result_callback_; |
| |
| const base::TimeDelta user_session_timeout_; |
| |
| base::WeakPtrFactory<DeviceCommandRebootJob> weak_factory_{this}; |
| }; |
| |
| } // namespace policy |
| |
| #endif // CHROME_BROWSER_ASH_POLICY_REMOTE_COMMANDS_DEVICE_COMMAND_REBOOT_JOB_H_ |