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