| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/system/automatic_reboot_manager.h" | 5 #include "chrome/browser/chromeos/system/automatic_reboot_manager.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 #include <sys/types.h> | 9 #include <sys/types.h> |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "base/prefs/pref_registry_simple.h" | 25 #include "base/prefs/pref_registry_simple.h" |
| 26 #include "base/prefs/pref_service.h" | 26 #include "base/prefs/pref_service.h" |
| 27 #include "base/single_thread_task_runner.h" | 27 #include "base/single_thread_task_runner.h" |
| 28 #include "base/strings/string_number_conversions.h" | 28 #include "base/strings/string_number_conversions.h" |
| 29 #include "base/thread_task_runner_handle.h" | 29 #include "base/thread_task_runner_handle.h" |
| 30 #include "base/threading/sequenced_worker_pool.h" | 30 #include "base/threading/sequenced_worker_pool.h" |
| 31 #include "base/threading/thread_restrictions.h" | 31 #include "base/threading/thread_restrictions.h" |
| 32 #include "base/time/tick_clock.h" | 32 #include "base/time/tick_clock.h" |
| 33 #include "chrome/browser/browser_process.h" | 33 #include "chrome/browser/browser_process.h" |
| 34 #include "chrome/browser/chrome_notification_types.h" | 34 #include "chrome/browser/chrome_notification_types.h" |
| 35 #include "chrome/browser/chromeos/system/automatic_reboot_manager_observer.h" |
| 35 #include "chrome/common/pref_names.h" | 36 #include "chrome/common/pref_names.h" |
| 36 #include "chromeos/chromeos_paths.h" | 37 #include "chromeos/chromeos_paths.h" |
| 37 #include "chromeos/chromeos_switches.h" | 38 #include "chromeos/chromeos_switches.h" |
| 38 #include "chromeos/dbus/dbus_thread_manager.h" | 39 #include "chromeos/dbus/dbus_thread_manager.h" |
| 39 #include "components/user_manager/user_manager.h" | 40 #include "components/user_manager/user_manager.h" |
| 40 #include "content/public/browser/browser_thread.h" | 41 #include "content/public/browser/browser_thread.h" |
| 41 #include "content/public/browser/notification_details.h" | 42 #include "content/public/browser/notification_details.h" |
| 42 #include "content/public/browser/notification_service.h" | 43 #include "content/public/browser/notification_service.h" |
| 43 #include "content/public/browser/notification_source.h" | 44 #include "content/public/browser/notification_source.h" |
| 44 #include "ui/wm/core/user_activity_detector.h" | 45 #include "ui/wm/core/user_activity_detector.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // necessary in base::TimeTicks::Now() ticks. | 144 // necessary in base::TimeTicks::Now() ticks. |
| 144 update_reboot_needed_time = boot_time + update_reboot_needed_uptime; | 145 update_reboot_needed_time = boot_time + update_reboot_needed_uptime; |
| 145 has_update_reboot_needed_time = true; | 146 has_update_reboot_needed_time = true; |
| 146 } | 147 } |
| 147 | 148 |
| 148 AutomaticRebootManager::AutomaticRebootManager( | 149 AutomaticRebootManager::AutomaticRebootManager( |
| 149 scoped_ptr<base::TickClock> clock) | 150 scoped_ptr<base::TickClock> clock) |
| 150 : clock_(clock.Pass()), | 151 : clock_(clock.Pass()), |
| 151 have_boot_time_(false), | 152 have_boot_time_(false), |
| 152 have_update_reboot_needed_time_(false), | 153 have_update_reboot_needed_time_(false), |
| 153 reboot_reason_(AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN), | |
| 154 reboot_requested_(false), | 154 reboot_requested_(false), |
| 155 weak_ptr_factory_(this) { | 155 weak_ptr_factory_(this) { |
| 156 local_state_registrar_.Init(g_browser_process->local_state()); | 156 local_state_registrar_.Init(g_browser_process->local_state()); |
| 157 local_state_registrar_.Add(prefs::kUptimeLimit, | 157 local_state_registrar_.Add(prefs::kUptimeLimit, |
| 158 base::Bind(&AutomaticRebootManager::Reschedule, | 158 base::Bind(&AutomaticRebootManager::Reschedule, |
| 159 base::Unretained(this))); | 159 base::Unretained(this))); |
| 160 local_state_registrar_.Add(prefs::kRebootAfterUpdate, | 160 local_state_registrar_.Add(prefs::kRebootAfterUpdate, |
| 161 base::Bind(&AutomaticRebootManager::Reschedule, | 161 base::Bind(&AutomaticRebootManager::Reschedule, |
| 162 base::Unretained(this))); | 162 base::Unretained(this))); |
| 163 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 163 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 const base::TimeDelta& sleep_duration) { | 219 const base::TimeDelta& sleep_duration) { |
| 220 MaybeReboot(true); | 220 MaybeReboot(true); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void AutomaticRebootManager::UpdateStatusChanged( | 223 void AutomaticRebootManager::UpdateStatusChanged( |
| 224 const UpdateEngineClient::Status& status) { | 224 const UpdateEngineClient::Status& status) { |
| 225 // Ignore repeated notifications that a reboot is necessary. This is important | 225 // Ignore repeated notifications that a reboot is necessary. This is important |
| 226 // so that only the time of the first notification is taken into account and | 226 // so that only the time of the first notification is taken into account and |
| 227 // repeated notifications do not postpone the reboot request and grace period. | 227 // repeated notifications do not postpone the reboot request and grace period. |
| 228 if (status.status != UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT || | 228 if (status.status != UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT || |
| 229 have_update_reboot_needed_time_) { | 229 !have_boot_time_ || have_update_reboot_needed_time_) { |
| 230 return; | 230 return; |
| 231 } | 231 } |
| 232 | 232 |
| 233 content::BrowserThread::PostBlockingPoolTask( | 233 content::BrowserThread::PostBlockingPoolTask( |
| 234 FROM_HERE, base::Bind(&SaveUpdateRebootNeededUptime)); | 234 FROM_HERE, base::Bind(&SaveUpdateRebootNeededUptime)); |
| 235 | 235 |
| 236 update_reboot_needed_time_ = clock_->NowTicks(); | 236 update_reboot_needed_time_ = clock_->NowTicks(); |
| 237 have_update_reboot_needed_time_ = true; | 237 have_update_reboot_needed_time_ = true; |
| 238 | 238 |
| 239 Reschedule(); | 239 Reschedule(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 void AutomaticRebootManager::Reschedule() { | 310 void AutomaticRebootManager::Reschedule() { |
| 311 // Safeguard against reboot loops under error conditions: If the boot time is | 311 // Safeguard against reboot loops under error conditions: If the boot time is |
| 312 // unavailable because /proc/uptime could not be read, do nothing. | 312 // unavailable because /proc/uptime could not be read, do nothing. |
| 313 if (!have_boot_time_) | 313 if (!have_boot_time_) |
| 314 return; | 314 return; |
| 315 | 315 |
| 316 // Assume that no reboot has been requested. | 316 // Assume that no reboot has been requested. |
| 317 reboot_requested_ = false; | 317 reboot_requested_ = false; |
| 318 | 318 |
| 319 const base::TimeDelta kZeroTimeDelta; | 319 const base::TimeDelta kZeroTimeDelta; |
| 320 AutomaticRebootManagerObserver::Reason reboot_reason = |
| 321 AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN; |
| 320 | 322 |
| 321 // If an uptime limit is set, calculate the time at which it should cause a | 323 // If an uptime limit is set, calculate the time at which it should cause a |
| 322 // reboot to be requested. | 324 // reboot to be requested. |
| 323 const base::TimeDelta uptime_limit = base::TimeDelta::FromSeconds( | 325 const base::TimeDelta uptime_limit = base::TimeDelta::FromSeconds( |
| 324 local_state_registrar_.prefs()->GetInteger(prefs::kUptimeLimit)); | 326 local_state_registrar_.prefs()->GetInteger(prefs::kUptimeLimit)); |
| 325 base::TimeTicks reboot_request_time = boot_time_ + uptime_limit; | 327 base::TimeTicks reboot_request_time = boot_time_ + uptime_limit; |
| 326 bool have_reboot_request_time = uptime_limit != kZeroTimeDelta; | 328 bool have_reboot_request_time = uptime_limit != kZeroTimeDelta; |
| 327 if (have_reboot_request_time) | 329 if (have_reboot_request_time) |
| 328 reboot_reason_ = AutomaticRebootManagerObserver::REBOOT_REASON_PERIODIC; | 330 reboot_reason = AutomaticRebootManagerObserver::REBOOT_REASON_PERIODIC; |
| 329 | 331 |
| 330 // If the policy to automatically reboot after an update is enabled and an | 332 // If the policy to automatically reboot after an update is enabled and an |
| 331 // update has been applied, set the time at which a reboot should be | 333 // update has been applied, set the time at which a reboot should be |
| 332 // requested to the minimum of its current value and the time when the reboot | 334 // requested to the minimum of its current value and the time when the reboot |
| 333 // became necessary. | 335 // became necessary. |
| 334 if (have_update_reboot_needed_time_ && | 336 if (have_update_reboot_needed_time_ && |
| 335 local_state_registrar_.prefs()->GetBoolean(prefs::kRebootAfterUpdate) && | 337 local_state_registrar_.prefs()->GetBoolean(prefs::kRebootAfterUpdate) && |
| 336 (!have_reboot_request_time || | 338 (!have_reboot_request_time || |
| 337 update_reboot_needed_time_ < reboot_request_time)) { | 339 update_reboot_needed_time_ < reboot_request_time)) { |
| 338 reboot_request_time = update_reboot_needed_time_; | 340 reboot_request_time = update_reboot_needed_time_; |
| 339 have_reboot_request_time = true; | 341 have_reboot_request_time = true; |
| 340 reboot_reason_ = AutomaticRebootManagerObserver::REBOOT_REASON_OS_UPDATE; | 342 reboot_reason = AutomaticRebootManagerObserver::REBOOT_REASON_OS_UPDATE; |
| 341 } | 343 } |
| 342 | 344 |
| 343 // If no reboot should be requested, remove any grace period. | 345 // If no reboot should be requested, remove any grace period. |
| 344 if (!have_reboot_request_time) { | 346 if (!have_reboot_request_time) { |
| 345 grace_start_timer_.reset(); | 347 grace_start_timer_.reset(); |
| 346 grace_end_timer_.reset(); | 348 grace_end_timer_.reset(); |
| 347 return; | 349 return; |
| 348 } | 350 } |
| 349 | 351 |
| 350 // Safeguard against reboot loops: Ensure that the uptime after which a reboot | 352 // Safeguard against reboot loops: Ensure that the uptime after which a reboot |
| (...skipping 15 matching lines...) Expand all Loading... |
| 366 base::TimeDelta::FromMilliseconds(kGracePeriodMs); | 368 base::TimeDelta::FromMilliseconds(kGracePeriodMs); |
| 367 // Set up a timer for the end of the grace period. If the grace period ended | 369 // Set up a timer for the end of the grace period. If the grace period ended |
| 368 // in the past, the timer is still used with its delay set to zero. | 370 // in the past, the timer is still used with its delay set to zero. |
| 369 if (!grace_end_timer_) | 371 if (!grace_end_timer_) |
| 370 grace_end_timer_.reset(new base::OneShotTimer<AutomaticRebootManager>); | 372 grace_end_timer_.reset(new base::OneShotTimer<AutomaticRebootManager>); |
| 371 grace_end_timer_->Start(FROM_HERE, | 373 grace_end_timer_->Start(FROM_HERE, |
| 372 std::max(grace_end_time - now, kZeroTimeDelta), | 374 std::max(grace_end_time - now, kZeroTimeDelta), |
| 373 base::Bind(&AutomaticRebootManager::Reboot, | 375 base::Bind(&AutomaticRebootManager::Reboot, |
| 374 base::Unretained(this))); | 376 base::Unretained(this))); |
| 375 | 377 |
| 378 DCHECK_NE(AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN, |
| 379 reboot_reason); |
| 380 FOR_EACH_OBSERVER(AutomaticRebootManagerObserver, |
| 381 observers_, |
| 382 OnRebootScheduled(reboot_reason)); |
| 376 } | 383 } |
| 377 | 384 |
| 378 void AutomaticRebootManager::RequestReboot() { | 385 void AutomaticRebootManager::RequestReboot() { |
| 379 reboot_requested_ = true; | 386 reboot_requested_ = true; |
| 380 DCHECK_NE(AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN, | |
| 381 reboot_reason_); | |
| 382 FOR_EACH_OBSERVER(AutomaticRebootManagerObserver, | |
| 383 observers_, | |
| 384 OnRebootRequested(reboot_reason_)); | |
| 385 MaybeReboot(false); | 387 MaybeReboot(false); |
| 386 } | 388 } |
| 387 | 389 |
| 388 void AutomaticRebootManager::MaybeReboot(bool ignore_session) { | 390 void AutomaticRebootManager::MaybeReboot(bool ignore_session) { |
| 389 // Do not reboot if any of the following applies: | 391 // Do not reboot if any of the following applies: |
| 390 // * No reboot has been requested. | 392 // * No reboot has been requested. |
| 391 // * A user is interacting with the login screen. | 393 // * A user is interacting with the login screen. |
| 392 // * A session is in progress and |ignore_session| is not set. | 394 // * A session is in progress and |ignore_session| is not set. |
| 393 if (!reboot_requested_ || | 395 if (!reboot_requested_ || |
| 394 (login_screen_idle_timer_ && login_screen_idle_timer_->IsRunning()) || | 396 (login_screen_idle_timer_ && login_screen_idle_timer_->IsRunning()) || |
| (...skipping 12 matching lines...) Expand all Loading... |
| 407 } | 409 } |
| 408 | 410 |
| 409 login_screen_idle_timer_.reset(); | 411 login_screen_idle_timer_.reset(); |
| 410 grace_start_timer_.reset(); | 412 grace_start_timer_.reset(); |
| 411 grace_end_timer_.reset(); | 413 grace_end_timer_.reset(); |
| 412 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); | 414 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); |
| 413 } | 415 } |
| 414 | 416 |
| 415 } // namespace system | 417 } // namespace system |
| 416 } // namespace chromeos | 418 } // namespace chromeos |
| OLD | NEW |