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
|
// 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 <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 waiting period, 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);
bool ParseCommandPayload(const std::string& command_payload) override;
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 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 raw_ptr<ash::LoginState> login_state_;
// Handles reboot on signout.
raw_ptr<ash::SessionTerminationManager> session_termination_manager_;
// Scheduler for reboot notification and dialog. Unowned.
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.
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_;
// Delay between execution start in user session and the reboot.
base::TimeDelta user_session_delay_;
base::WeakPtrFactory<DeviceCommandRebootJob> weak_factory_{this};
};
} // namespace policy
#endif // CHROME_BROWSER_ASH_POLICY_REMOTE_COMMANDS_DEVICE_COMMAND_REBOOT_JOB_H_
|