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 } 39 40 int UpgradeDetector::GetIconResourceID(UpgradeNotificationIconType type) { 41 if (type == UPGRADE_ICON_TYPE_BADGE) { 42 // Badges do not exist on Views and Mac OS X. 43 #if !defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) 44 switch (upgrade_notification_stage_) { 45 case UPGRADE_ANNOYANCE_NONE: 46 return 0; 47 case UPGRADE_ANNOYANCE_LOW: 48 return IDR_UPDATE_BADGE; 49 case UPGRADE_ANNOYANCE_ELEVATED: 50 return IDR_UPDATE_BADGE2; 51 case UPGRADE_ANNOYANCE_HIGH: 52 return IDR_UPDATE_BADGE3; 53 case UPGRADE_ANNOYANCE_SEVERE: 54 return IDR_UPDATE_BADGE3; 55 case UPGRADE_ANNOYANCE_CRITICAL: 56 return IDR_UPDATE_BADGE3; 57 } 58 #endif 59 NOTREACHED(); 60 return 0; 61 } 62 63 switch (upgrade_notification_stage_) { 64 case UPGRADE_ANNOYANCE_NONE: 65 return 0; 66 case UPGRADE_ANNOYANCE_LOW: 67 return IDR_UPDATE_MENU_SEVERITY_LOW; 68 case UPGRADE_ANNOYANCE_ELEVATED: 69 return IDR_UPDATE_MENU_SEVERITY_MEDIUM; 70 case UPGRADE_ANNOYANCE_HIGH: 71 return IDR_UPDATE_MENU_SEVERITY_HIGH; 72 case UPGRADE_ANNOYANCE_SEVERE: 73 return IDR_UPDATE_MENU_SEVERITY_HIGH; 74 case UPGRADE_ANNOYANCE_CRITICAL: 75 return IDR_UPDATE_MENU_SEVERITY_HIGH; 76 } 77 NOTREACHED(); 78 return 0; 79 } 80 81 UpgradeDetector::UpgradeDetector() 82 : upgrade_available_(UPGRADE_AVAILABLE_NONE), 83 critical_update_acknowledged_(false), 84 upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE), 85 notify_upgrade_(false) { 86 } 87 88 UpgradeDetector::~UpgradeDetector() { 89 } 90 91 void UpgradeDetector::NotifyUpgradeDetected() { 92 upgrade_detected_time_ = base::Time::Now(); 93 critical_update_acknowledged_ = false; 94 } 95 96 void UpgradeDetector::NotifyUpgradeRecommended() { 97 notify_upgrade_ = true; 98 99 content::NotificationService::current()->Notify( 100 chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 101 content::Source<UpgradeDetector>(this), 102 content::NotificationService::NoDetails()); 103 104 switch (upgrade_available_) { 105 case UPGRADE_NEEDED_OUTDATED_INSTALL: { 106 content::NotificationService::current()->Notify( 107 chrome::NOTIFICATION_OUTDATED_INSTALL, 108 content::Source<UpgradeDetector>(this), 109 content::NotificationService::NoDetails()); 110 break; 111 } 112 case UPGRADE_AVAILABLE_CRITICAL: { 113 int idle_timer = UseTestingIntervals() ? 114 kIdleRepeatingTimerWait : 115 kIdleRepeatingTimerWait * 60; // To minutes. 116 idle_check_timer_.Start(FROM_HERE, 117 base::TimeDelta::FromSeconds(idle_timer), 118 this, &UpgradeDetector::CheckIdle); 119 break; 120 } 121 default: 122 break; 123 } 124 } 125 126 void UpgradeDetector::CheckIdle() { 127 // CalculateIdleState expects an interval in seconds. 128 int idle_time_allowed = UseTestingIntervals() ? kIdleAmount : 129 kIdleAmount * 60 * 60; 130 131 CalculateIdleState( 132 idle_time_allowed, base::Bind(&UpgradeDetector::IdleCallback, 133 base::Unretained(this))); 134 } 135 136 void UpgradeDetector::IdleCallback(IdleState state) { 137 // Don't proceed while an incognito window is open. The timer will still 138 // keep firing, so this function will get a chance to re-evaluate this. 139 if (chrome::IsOffTheRecordSessionActive()) 140 return; 141 142 switch (state) { 143 case IDLE_STATE_LOCKED: 144 // Computer is locked, auto-restart. 145 idle_check_timer_.Stop(); 146 chrome::AttemptRestart(); 147 break; 148 case IDLE_STATE_IDLE: 149 // Computer has been idle for long enough, show warning. 150 idle_check_timer_.Stop(); 151 content::NotificationService::current()->Notify( 152 chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED, 153 content::Source<UpgradeDetector>(this), 154 content::NotificationService::NoDetails()); 155 break; 156 case IDLE_STATE_ACTIVE: 157 case IDLE_STATE_UNKNOWN: 158 break; 159 default: 160 NOTREACHED(); // Need to add any new value above (either providing 161 // automatic restart or show notification to user). 162 break; 163 } 164 } 165