1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.h"
6 
7 #include <algorithm>
8 
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/syslog_logging.h"
14 #include "base/system/sys_info.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "base/time/time.h"
17 #include "chromeos/dbus/power/power_manager_client.h"
18 #include "components/policy/proto/device_management_backend.pb.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
20 
21 namespace policy {
22 
DeviceCommandRebootJob(chromeos::PowerManagerClient * power_manager_client)23 DeviceCommandRebootJob::DeviceCommandRebootJob(
24     chromeos::PowerManagerClient* power_manager_client)
25     : power_manager_client_(power_manager_client) {
26   CHECK(power_manager_client_);
27 }
28 
~DeviceCommandRebootJob()29 DeviceCommandRebootJob::~DeviceCommandRebootJob() {
30 }
31 
GetType() const32 enterprise_management::RemoteCommand_Type DeviceCommandRebootJob::GetType()
33     const {
34   return enterprise_management::RemoteCommand_Type_DEVICE_REBOOT;
35 }
36 
RunImpl(CallbackWithResult succeeded_callback,CallbackWithResult failed_callback)37 void DeviceCommandRebootJob::RunImpl(CallbackWithResult succeeded_callback,
38                                      CallbackWithResult failed_callback) {
39   SYSLOG(INFO) << "Running reboot command.";
40 
41   // Determines the time delta between the command having been issued and the
42   // boot time of the system.
43   const base::TimeDelta uptime = base::SysInfo::Uptime();
44   const base::TimeTicks boot_time = base::TimeTicks::Now() - uptime;
45   const base::TimeDelta delta = boot_time - issued_time();
46   // If the reboot command was issued before the system booted, we inform the
47   // server that the reboot succeeded. Otherwise, the reboot must still be
48   // performed and we invoke it.
49   if (delta > base::TimeDelta()) {
50     SYSLOG(WARNING) << "Ignoring reboot command issued " << delta
51                     << " before current boot time";
52     base::ThreadTaskRunnerHandle::Get()->PostTask(
53         FROM_HERE, base::BindOnce(std::move(succeeded_callback), nullptr));
54     return;
55   }
56 
57   SYSLOG(INFO) << "Rebooting immediately.";
58   power_manager_client_->RequestRestart(power_manager::REQUEST_RESTART_OTHER,
59                                         "policy device command");
60 }
61 
62 }  // namespace policy
63