summaryrefslogtreecommitdiffstats
path: root/chrome/browser/upgrade_detector.cc
blob: f6b68bc8b875f1490545012cbdf62cd79eacc408 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// 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);
}

int UpgradeDetector::GetIconResourceID(UpgradeNotificationIconType type) {
  if (type == UPGRADE_ICON_TYPE_BADGE) {
    // Badges do not exist on Views and Mac OS X.
#if !defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
    switch (upgrade_notification_stage_) {
      case UPGRADE_ANNOYANCE_NONE:
        return 0;
      case UPGRADE_ANNOYANCE_LOW:
        return IDR_UPDATE_BADGE;
      case UPGRADE_ANNOYANCE_ELEVATED:
        return IDR_UPDATE_BADGE2;
      case UPGRADE_ANNOYANCE_HIGH:
        return IDR_UPDATE_BADGE3;
      case UPGRADE_ANNOYANCE_SEVERE:
        return IDR_UPDATE_BADGE3;
      case UPGRADE_ANNOYANCE_CRITICAL:
        return IDR_UPDATE_BADGE3;
    }
#endif
    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_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;
  }
}