// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/upgrade_detector.h" #include "base/bind.h" #include "base/command_line.h" #include "base/prefs/pref_registry_simple.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/browser_otr_state.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "content/public/browser/notification_service.h" #include "grit/theme_resources.h" // How long to wait between checks for whether the user has been idle. static const int kIdleRepeatingTimerWait = 10; // Minutes (seconds if testing). // How much idle time (since last input even was detected) must have passed // until we notify that a critical update has occurred. static const int kIdleAmount = 2; // Hours (or seconds, if testing). bool UseTestingIntervals() { // If a command line parameter specifying how long the upgrade check should // be, we assume it is for testing and switch to using seconds instead of // hours. const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); return !cmd_line.GetSwitchValueASCII( switches::kCheckForUpdateIntervalSec).empty(); } // static void UpgradeDetector::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(prefs::kRestartLastSessionOnShutdown, false); registry->RegisterBooleanPref(prefs::kWasRestarted, false); registry->RegisterBooleanPref(prefs::kAttemptedToEnableAutoupdate, false); } int UpgradeDetector::GetIconResourceID(UpgradeNotificationIconType type) { if (type == UPGRADE_ICON_TYPE_BADGE) { // TODO(oshima): Badges no longer exist. remove this. NOTREACHED(); return 0; } switch (upgrade_notification_stage_) { case UPGRADE_ANNOYANCE_NONE: return 0; case UPGRADE_ANNOYANCE_LOW: return IDR_UPDATE_MENU_SEVERITY_LOW; case UPGRADE_ANNOYANCE_ELEVATED: return IDR_UPDATE_MENU_SEVERITY_MEDIUM; case UPGRADE_ANNOYANCE_HIGH: return IDR_UPDATE_MENU_SEVERITY_HIGH; case UPGRADE_ANNOYANCE_SEVERE: return IDR_UPDATE_MENU_SEVERITY_HIGH; case UPGRADE_ANNOYANCE_CRITICAL: return IDR_UPDATE_MENU_SEVERITY_HIGH; } NOTREACHED(); return 0; } UpgradeDetector::UpgradeDetector() : upgrade_available_(UPGRADE_AVAILABLE_NONE), critical_update_acknowledged_(false), upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE), notify_upgrade_(false) { } UpgradeDetector::~UpgradeDetector() { } void UpgradeDetector::NotifyUpgradeDetected() { upgrade_detected_time_ = base::Time::Now(); critical_update_acknowledged_ = false; } void UpgradeDetector::NotifyUpgradeRecommended() { notify_upgrade_ = true; content::NotificationService::current()->Notify( chrome::NOTIFICATION_UPGRADE_RECOMMENDED, content::Source<UpgradeDetector>(this), content::NotificationService::NoDetails()); switch (upgrade_available_) { case UPGRADE_NEEDED_OUTDATED_INSTALL: { content::NotificationService::current()->Notify( chrome::NOTIFICATION_OUTDATED_INSTALL, content::Source<UpgradeDetector>(this), content::NotificationService::NoDetails()); break; } case UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU: { content::NotificationService::current()->Notify( chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU, content::Source<UpgradeDetector>(this), content::NotificationService::NoDetails()); break; } case UPGRADE_AVAILABLE_CRITICAL: { int idle_timer = UseTestingIntervals() ? kIdleRepeatingTimerWait : kIdleRepeatingTimerWait * 60; // To minutes. idle_check_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(idle_timer), this, &UpgradeDetector::CheckIdle); break; } default: break; } } void UpgradeDetector::CheckIdle() { // CalculateIdleState expects an interval in seconds. int idle_time_allowed = UseTestingIntervals() ? kIdleAmount : kIdleAmount * 60 * 60; CalculateIdleState( idle_time_allowed, base::Bind(&UpgradeDetector::IdleCallback, base::Unretained(this))); } void UpgradeDetector::IdleCallback(IdleState state) { // Don't proceed while an incognito window is open. The timer will still // keep firing, so this function will get a chance to re-evaluate this. if (chrome::IsOffTheRecordSessionActive()) return; switch (state) { case IDLE_STATE_LOCKED: // Computer is locked, auto-restart. idle_check_timer_.Stop(); chrome::AttemptRestart(); break; case IDLE_STATE_IDLE: // Computer has been idle for long enough, show warning. idle_check_timer_.Stop(); content::NotificationService::current()->Notify( chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED, content::Source<UpgradeDetector>(this), content::NotificationService::NoDetails()); break; case IDLE_STATE_ACTIVE: case IDLE_STATE_UNKNOWN: break; default: NOTREACHED(); // Need to add any new value above (either providing // automatic restart or show notification to user). break; } }