1 // Copyright (c) 2012 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/upgrade_detector.h" 6 7 #include "base/bind.h" 8 #include "base/command_line.h" 9 #include "base/prefs/pref_registry_simple.h" 10 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/lifetime/application_lifetime.h" 12 #include "chrome/browser/ui/browser_otr_state.h" 13 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/pref_names.h" 15 #include "content/public/browser/notification_service.h" 16 #include "grit/theme_resources.h" 17 18 // How long to wait between checks for whether the user has been idle. 19 static const int kIdleRepeatingTimerWait = 10; // Minutes (seconds if testing). 20 21 // How much idle time (since last input even was detected) must have passed 22 // until we notify that a critical update has occurred. 23 static const int kIdleAmount = 2; // Hours (or seconds, if testing). 24 25 bool UseTestingIntervals() { 26 // If a command line parameter specifying how long the upgrade check should 27 // be, we assume it is for testing and switch to using seconds instead of 28 // hours. 29 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 30 return !cmd_line.GetSwitchValueASCII( 31 switches::kCheckForUpdateIntervalSec).empty(); 32 } 33 34 // static 35 void UpgradeDetector::RegisterPrefs(PrefRegistrySimple* registry) { 36 registry->RegisterBooleanPref(prefs::kRestartLastSessionOnShutdown, false); 37 registry->RegisterBooleanPref(prefs::kWasRestarted, false); 38 registry->RegisterBooleanPref(prefs::kAttemptedToEnableAutoupdate, false); 39 } 40 41 int UpgradeDetector::GetIconResourceID() { 42 switch (upgrade_notification_stage_) { 43 case UPGRADE_ANNOYANCE_NONE: 44 return 0; 45 case UPGRADE_ANNOYANCE_LOW: 46 return IDR_UPDATE_MENU_SEVERITY_LOW; 47 case UPGRADE_ANNOYANCE_ELEVATED: 48 return IDR_UPDATE_MENU_SEVERITY_MEDIUM; 49 case UPGRADE_ANNOYANCE_HIGH: 50 return IDR_UPDATE_MENU_SEVERITY_HIGH; 51 case UPGRADE_ANNOYANCE_SEVERE: 52 return IDR_UPDATE_MENU_SEVERITY_HIGH; 53 case UPGRADE_ANNOYANCE_CRITICAL: 54 return IDR_UPDATE_MENU_SEVERITY_HIGH; 55 } 56 NOTREACHED(); 57 return 0; 58 } 59 60 UpgradeDetector::UpgradeDetector() 61 : upgrade_available_(UPGRADE_AVAILABLE_NONE), 62 best_effort_experiment_updates_available_(false), 63 critical_experiment_updates_available_(false), 64 critical_update_acknowledged_(false), 65 upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE), 66 notify_upgrade_(false) { 67 } 68 69 UpgradeDetector::~UpgradeDetector() { 70 } 71 72 void UpgradeDetector::NotifyUpgradeRecommended() { 73 notify_upgrade_ = true; 74 75 TriggerNotification(chrome::NOTIFICATION_UPGRADE_RECOMMENDED); 76 if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL) { 77 TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL); 78 } else if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU) { 79 TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU); 80 } else if (upgrade_available_ == UPGRADE_AVAILABLE_CRITICAL || 81 critical_experiment_updates_available_) { 82 TriggerCriticalUpdate(); 83 } 84 } 85 86 void UpgradeDetector::TriggerCriticalUpdate() { 87 const base::TimeDelta idle_timer = UseTestingIntervals() ? 88 base::TimeDelta::FromSeconds(kIdleRepeatingTimerWait) : 89 base::TimeDelta::FromMinutes(kIdleRepeatingTimerWait); 90 idle_check_timer_.Start(FROM_HERE, idle_timer, this, 91 &UpgradeDetector::CheckIdle); 92 } 93 94 void UpgradeDetector::CheckIdle() { 95 // CalculateIdleState expects an interval in seconds. 96 int idle_time_allowed = UseTestingIntervals() ? kIdleAmount : 97 kIdleAmount * 60 * 60; 98 99 CalculateIdleState( 100 idle_time_allowed, base::Bind(&UpgradeDetector::IdleCallback, 101 base::Unretained(this))); 102 } 103 104 void UpgradeDetector::TriggerNotification(chrome::NotificationType type) { 105 content::NotificationService::current()->Notify( 106 type, 107 content::Source<UpgradeDetector>(this), 108 content::NotificationService::NoDetails()); 109 } 110 111 void UpgradeDetector::IdleCallback(IdleState state) { 112 // Don't proceed while an incognito window is open. The timer will still 113 // keep firing, so this function will get a chance to re-evaluate this. 114 if (chrome::IsOffTheRecordSessionActive()) 115 return; 116 117 switch (state) { 118 case IDLE_STATE_LOCKED: 119 // Computer is locked, auto-restart. 120 idle_check_timer_.Stop(); 121 chrome::AttemptRestart(); 122 break; 123 case IDLE_STATE_IDLE: 124 // Computer has been idle for long enough, show warning. 125 idle_check_timer_.Stop(); 126 TriggerNotification(chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED); 127 break; 128 case IDLE_STATE_ACTIVE: 129 case IDLE_STATE_UNKNOWN: 130 break; 131 default: 132 NOTREACHED(); // Need to add any new value above (either providing 133 // automatic restart or show notification to user). 134 break; 135 } 136 } 137