Home | History | Annotate | Download | only in browser
      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