Chromium Code Reviews| 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 15 matching lines...) Expand all Loading... | |
| 26 #include "base/prefs/pref_registry_simple.h" | 26 #include "base/prefs/pref_registry_simple.h" |
| 27 #include "base/prefs/pref_service.h" | 27 #include "base/prefs/pref_service.h" |
| 28 #include "base/single_thread_task_runner.h" | 28 #include "base/single_thread_task_runner.h" |
| 29 #include "base/strings/string_number_conversions.h" | 29 #include "base/strings/string_number_conversions.h" |
| 30 #include "base/thread_task_runner_handle.h" | 30 #include "base/thread_task_runner_handle.h" |
| 31 #include "base/threading/sequenced_worker_pool.h" | 31 #include "base/threading/sequenced_worker_pool.h" |
| 32 #include "base/threading/thread_restrictions.h" | 32 #include "base/threading/thread_restrictions.h" |
| 33 #include "base/time/tick_clock.h" | 33 #include "base/time/tick_clock.h" |
| 34 #include "chrome/browser/browser_process.h" | 34 #include "chrome/browser/browser_process.h" |
| 35 #include "chrome/browser/chromeos/login/user_manager.h" | 35 #include "chrome/browser/chromeos/login/user_manager.h" |
| 36 #include "chrome/browser/chromeos/system/automatic_reboot_manager_observer.h" | |
| 37 #include "chrome/browser/profiles/profile_manager.h" | |
| 36 #include "chrome/common/chrome_notification_types.h" | 38 #include "chrome/common/chrome_notification_types.h" |
| 37 #include "chrome/common/pref_names.h" | 39 #include "chrome/common/pref_names.h" |
| 38 #include "chromeos/chromeos_paths.h" | 40 #include "chromeos/chromeos_paths.h" |
| 39 #include "chromeos/chromeos_switches.h" | 41 #include "chromeos/chromeos_switches.h" |
| 40 #include "chromeos/dbus/dbus_thread_manager.h" | 42 #include "chromeos/dbus/dbus_thread_manager.h" |
| 41 #include "content/public/browser/browser_thread.h" | 43 #include "content/public/browser/browser_thread.h" |
| 42 #include "content/public/browser/notification_details.h" | 44 #include "content/public/browser/notification_details.h" |
| 43 #include "content/public/browser/notification_service.h" | 45 #include "content/public/browser/notification_service.h" |
| 44 #include "content/public/browser/notification_source.h" | 46 #include "content/public/browser/notification_source.h" |
| 45 | 47 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 return; | 116 return; |
| 115 file_util::ScopedFD fd_closer(&fd); | 117 file_util::ScopedFD fd_closer(&fd); |
| 116 | 118 |
| 117 std::string update_reboot_needed_uptime = | 119 std::string update_reboot_needed_uptime = |
| 118 base::DoubleToString(uptime.InSecondsF()); | 120 base::DoubleToString(uptime.InSecondsF()); |
| 119 file_util::WriteFileDescriptor(fd, | 121 file_util::WriteFileDescriptor(fd, |
| 120 update_reboot_needed_uptime.c_str(), | 122 update_reboot_needed_uptime.c_str(), |
| 121 update_reboot_needed_uptime.size()); | 123 update_reboot_needed_uptime.size()); |
| 122 } | 124 } |
| 123 | 125 |
| 126 AutomaticRebootManager* instance = NULL; | |
|
bartfab (slow)
2013/06/17 23:30:59
Instead of creating more singletons with implicit
xiyuan
2013/06/20 02:17:12
Done.
| |
| 127 | |
| 124 } // namespace | 128 } // namespace |
| 125 | 129 |
| 126 AutomaticRebootManager::SystemEventTimes::SystemEventTimes() | 130 AutomaticRebootManager::SystemEventTimes::SystemEventTimes() |
| 127 : has_boot_time(false), | 131 : has_boot_time(false), |
| 128 has_update_reboot_needed_time(false) { | 132 has_update_reboot_needed_time(false) { |
| 129 } | 133 } |
| 130 | 134 |
| 131 AutomaticRebootManager::SystemEventTimes::SystemEventTimes( | 135 AutomaticRebootManager::SystemEventTimes::SystemEventTimes( |
| 132 const base::TimeDelta& uptime, | 136 const base::TimeDelta& uptime, |
| 133 const base::TimeDelta& update_reboot_needed_uptime) | 137 const base::TimeDelta& update_reboot_needed_uptime) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 146 has_update_reboot_needed_time = true; | 150 has_update_reboot_needed_time = true; |
| 147 } | 151 } |
| 148 | 152 |
| 149 AutomaticRebootManager::AutomaticRebootManager( | 153 AutomaticRebootManager::AutomaticRebootManager( |
| 150 scoped_ptr<base::TickClock> clock) | 154 scoped_ptr<base::TickClock> clock) |
| 151 : clock_(clock.Pass()), | 155 : clock_(clock.Pass()), |
| 152 have_boot_time_(false), | 156 have_boot_time_(false), |
| 153 have_update_reboot_needed_time_(false), | 157 have_update_reboot_needed_time_(false), |
| 154 reboot_requested_(false), | 158 reboot_requested_(false), |
| 155 weak_ptr_factory_(this) { | 159 weak_ptr_factory_(this) { |
| 160 DCHECK(!instance); | |
|
bartfab (slow)
2013/06/17 23:30:59
This would require #include <base/logging.h>. Howe
xiyuan
2013/06/20 02:17:12
Code removed.
| |
| 161 instance = this; | |
| 162 | |
| 156 local_state_registrar_.Init(g_browser_process->local_state()); | 163 local_state_registrar_.Init(g_browser_process->local_state()); |
| 157 local_state_registrar_.Add(prefs::kUptimeLimit, | 164 local_state_registrar_.Add(prefs::kUptimeLimit, |
| 158 base::Bind(&AutomaticRebootManager::Reschedule, | 165 base::Bind(&AutomaticRebootManager::Reschedule, |
| 159 base::Unretained(this))); | 166 base::Unretained(this))); |
| 160 local_state_registrar_.Add(prefs::kRebootAfterUpdate, | 167 local_state_registrar_.Add(prefs::kRebootAfterUpdate, |
| 161 base::Bind(&AutomaticRebootManager::Reschedule, | 168 base::Bind(&AutomaticRebootManager::Reschedule, |
| 162 base::Unretained(this))); | 169 base::Unretained(this))); |
| 163 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 170 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 164 content::NotificationService::AllSources()); | 171 content::NotificationService::AllSources()); |
| 165 | 172 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 187 content::BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( | 194 content::BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( |
| 188 FROM_HERE, | 195 FROM_HERE, |
| 189 base::Bind(&GetSystemEventTimes, | 196 base::Bind(&GetSystemEventTimes, |
| 190 base::ThreadTaskRunnerHandle::Get(), | 197 base::ThreadTaskRunnerHandle::Get(), |
| 191 base::Bind(&AutomaticRebootManager::Init, | 198 base::Bind(&AutomaticRebootManager::Init, |
| 192 weak_ptr_factory_.GetWeakPtr())), | 199 weak_ptr_factory_.GetWeakPtr())), |
| 193 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 200 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| 194 } | 201 } |
| 195 | 202 |
| 196 AutomaticRebootManager::~AutomaticRebootManager() { | 203 AutomaticRebootManager::~AutomaticRebootManager() { |
| 204 DCHECK(instance == this); | |
|
bartfab (slow)
2013/06/17 23:30:59
Nit: DCHECK_EQ()
xiyuan
2013/06/20 02:17:12
Code removed.
| |
| 205 instance = NULL; | |
| 206 | |
| 197 DBusThreadManager* dbus_thread_manager = DBusThreadManager::Get(); | 207 DBusThreadManager* dbus_thread_manager = DBusThreadManager::Get(); |
| 198 dbus_thread_manager->GetPowerManagerClient()->RemoveObserver(this); | 208 dbus_thread_manager->GetPowerManagerClient()->RemoveObserver(this); |
| 199 dbus_thread_manager->GetUpdateEngineClient()->RemoveObserver(this); | 209 dbus_thread_manager->GetUpdateEngineClient()->RemoveObserver(this); |
| 200 if (ash::Shell::HasInstance()) | 210 if (ash::Shell::HasInstance()) |
| 201 ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); | 211 ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); |
| 202 } | 212 } |
| 203 | 213 |
| 214 AutomaticRebootManager* AutomaticRebootManager::Get() { | |
| 215 return instance; | |
| 216 } | |
| 217 | |
| 218 void AutomaticRebootManager::AddObserver( | |
| 219 AutomaticRebootManagerObserver* observer) { | |
| 220 observers_.AddObserver(observer); | |
| 221 } | |
| 222 | |
| 223 void AutomaticRebootManager::RemoveObserver( | |
| 224 AutomaticRebootManagerObserver* observer) { | |
| 225 observers_.RemoveObserver(observer); | |
| 226 } | |
| 227 | |
| 204 void AutomaticRebootManager::SystemResumed( | 228 void AutomaticRebootManager::SystemResumed( |
| 205 const base::TimeDelta& sleep_duration) { | 229 const base::TimeDelta& sleep_duration) { |
| 206 MaybeReboot(true); | 230 MaybeReboot(true); |
| 207 } | 231 } |
| 208 | 232 |
| 209 void AutomaticRebootManager::UpdateStatusChanged( | 233 void AutomaticRebootManager::UpdateStatusChanged( |
| 210 const UpdateEngineClient::Status& status) { | 234 const UpdateEngineClient::Status& status) { |
| 211 // Ignore repeated notifications that a reboot is necessary. This is important | 235 // Ignore repeated notifications that a reboot is necessary. This is important |
| 212 // so that only the time of the first notification is taken into account and | 236 // so that only the time of the first notification is taken into account and |
| 213 // repeated notifications do not postpone the reboot request and grace period. | 237 // repeated notifications do not postpone the reboot request and grace period. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 void AutomaticRebootManager::Reschedule() { | 320 void AutomaticRebootManager::Reschedule() { |
| 297 // Safeguard against reboot loops under error conditions: If the boot time is | 321 // Safeguard against reboot loops under error conditions: If the boot time is |
| 298 // unavailable because /proc/uptime could not be read, do nothing. | 322 // unavailable because /proc/uptime could not be read, do nothing. |
| 299 if (!have_boot_time_) | 323 if (!have_boot_time_) |
| 300 return; | 324 return; |
| 301 | 325 |
| 302 // Assume that no reboot has been requested. | 326 // Assume that no reboot has been requested. |
| 303 reboot_requested_ = false; | 327 reboot_requested_ = false; |
| 304 | 328 |
| 305 const base::TimeDelta kZeroTimeDelta; | 329 const base::TimeDelta kZeroTimeDelta; |
| 330 AutomaticRebootManagerObserver::Reason reboot_reason = | |
| 331 AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN; | |
| 306 | 332 |
| 307 // If an uptime limit is set, calculate the time at which it should cause a | 333 // If an uptime limit is set, calculate the time at which it should cause a |
| 308 // reboot to be requested. | 334 // reboot to be requested. |
| 309 const base::TimeDelta uptime_limit = base::TimeDelta::FromSeconds( | 335 const base::TimeDelta uptime_limit = base::TimeDelta::FromSeconds( |
| 310 local_state_registrar_.prefs()->GetInteger(prefs::kUptimeLimit)); | 336 local_state_registrar_.prefs()->GetInteger(prefs::kUptimeLimit)); |
| 311 base::TimeTicks reboot_request_time = boot_time_ + uptime_limit; | 337 base::TimeTicks reboot_request_time = boot_time_ + uptime_limit; |
| 312 bool have_reboot_request_time = uptime_limit != kZeroTimeDelta; | 338 bool have_reboot_request_time = uptime_limit != kZeroTimeDelta; |
| 339 if (have_reboot_request_time) | |
| 340 reboot_reason = AutomaticRebootManagerObserver::REBOOT_REASON_PERIODIC; | |
| 313 | 341 |
| 314 // If the policy to automatically reboot after an update is enabled and an | 342 // If the policy to automatically reboot after an update is enabled and an |
| 315 // update has been applied, set the time at which a reboot should be | 343 // update has been applied, set the time at which a reboot should be |
| 316 // requested to the minimum of its current value and the time when the reboot | 344 // requested to the minimum of its current value and the time when the reboot |
| 317 // became necessary. | 345 // became necessary. |
| 318 if (have_update_reboot_needed_time_ && | 346 if (have_update_reboot_needed_time_ && |
| 319 local_state_registrar_.prefs()->GetBoolean(prefs::kRebootAfterUpdate) && | 347 local_state_registrar_.prefs()->GetBoolean(prefs::kRebootAfterUpdate) && |
| 320 (!have_reboot_request_time || | 348 (!have_reboot_request_time || |
| 321 update_reboot_needed_time_ < reboot_request_time)) { | 349 update_reboot_needed_time_ < reboot_request_time)) { |
| 322 reboot_request_time = update_reboot_needed_time_; | 350 reboot_request_time = update_reboot_needed_time_; |
| 323 have_reboot_request_time = true; | 351 have_reboot_request_time = true; |
| 352 reboot_reason = AutomaticRebootManagerObserver::REBOOT_REASON_OS_UPDATE; | |
| 324 } | 353 } |
| 325 | 354 |
| 326 // If no reboot should be requested, remove any grace period. | 355 // If no reboot should be requested, remove any grace period. |
| 327 if (!have_reboot_request_time) { | 356 if (!have_reboot_request_time) { |
| 328 grace_start_timer_.reset(); | 357 grace_start_timer_.reset(); |
| 329 grace_end_timer_.reset(); | 358 grace_end_timer_.reset(); |
| 330 return; | 359 return; |
| 331 } | 360 } |
| 332 | 361 |
| 333 // Safeguard against reboot loops: Ensure that the uptime after which a reboot | 362 // Safeguard against reboot loops: Ensure that the uptime after which a reboot |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 348 const base::TimeTicks grace_end_time = grace_start_time + | 377 const base::TimeTicks grace_end_time = grace_start_time + |
| 349 base::TimeDelta::FromMilliseconds(kGracePeriodMs); | 378 base::TimeDelta::FromMilliseconds(kGracePeriodMs); |
| 350 // Set up a timer for the end of the grace period. If the grace period ended | 379 // Set up a timer for the end of the grace period. If the grace period ended |
| 351 // in the past, the timer is still used with its delay set to zero. | 380 // in the past, the timer is still used with its delay set to zero. |
| 352 if (!grace_end_timer_) | 381 if (!grace_end_timer_) |
| 353 grace_end_timer_.reset(new base::OneShotTimer<AutomaticRebootManager>); | 382 grace_end_timer_.reset(new base::OneShotTimer<AutomaticRebootManager>); |
| 354 grace_end_timer_->Start(FROM_HERE, | 383 grace_end_timer_->Start(FROM_HERE, |
| 355 std::max(grace_end_time - now, kZeroTimeDelta), | 384 std::max(grace_end_time - now, kZeroTimeDelta), |
| 356 base::Bind(&AutomaticRebootManager::Reboot, | 385 base::Bind(&AutomaticRebootManager::Reboot, |
| 357 base::Unretained(this))); | 386 base::Unretained(this))); |
| 387 | |
| 388 DCHECK_NE(AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN, | |
| 389 reboot_reason); | |
| 390 FOR_EACH_OBSERVER(AutomaticRebootManagerObserver, | |
| 391 observers_, | |
| 392 OnRebootScheduled(reboot_reason)); | |
| 358 } | 393 } |
| 359 | 394 |
| 360 void AutomaticRebootManager::RequestReboot() { | 395 void AutomaticRebootManager::RequestReboot() { |
| 361 reboot_requested_ = true; | 396 reboot_requested_ = true; |
| 362 MaybeReboot(false); | 397 MaybeReboot(false); |
| 363 } | 398 } |
| 364 | 399 |
| 365 void AutomaticRebootManager::MaybeReboot(bool ignore_session) { | 400 void AutomaticRebootManager::MaybeReboot(bool ignore_session) { |
| 366 // Do not reboot if any of the following applies: | 401 // Do not reboot if any of the following applies: |
| 367 // * No reboot has been requested. | 402 // * No reboot has been requested. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 384 } | 419 } |
| 385 | 420 |
| 386 login_screen_idle_timer_.reset(); | 421 login_screen_idle_timer_.reset(); |
| 387 grace_start_timer_.reset(); | 422 grace_start_timer_.reset(); |
| 388 grace_end_timer_.reset(); | 423 grace_end_timer_.reset(); |
| 389 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); | 424 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); |
| 390 } | 425 } |
| 391 | 426 |
| 392 } // namespace system | 427 } // namespace system |
| 393 } // namespace chromeos | 428 } // namespace chromeos |
| OLD | NEW |