summaryrefslogtreecommitdiffstats
path: root/chrome/browser/upgrade_detector.cc
blob: eff168d04962e6687eed388418d655d233ead5af (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
// 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() {
  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),
      best_effort_experiment_updates_available_(false),
      critical_experiment_updates_available_(false),
      critical_update_acknowledged_(false),
      upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE),
      notify_upgrade_(false) {
}

UpgradeDetector::~UpgradeDetector() {
}

void UpgradeDetector::NotifyUpgradeRecommended() {
  notify_upgrade_ = true;

  TriggerNotification(chrome::NOTIFICATION_UPGRADE_RECOMMENDED);
  if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL) {
    TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL);
  } else if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU) {
    TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU);
  } else if (upgrade_available_ == UPGRADE_AVAILABLE_CRITICAL ||
             critical_experiment_updates_available_) {
    TriggerCriticalUpdate();
  }
}

void UpgradeDetector::TriggerCriticalUpdate() {
  const base::TimeDelta idle_timer = UseTestingIntervals() ?
      base::TimeDelta::FromSeconds(kIdleRepeatingTimerWait) :
      base::TimeDelta::FromMinutes(kIdleRepeatingTimerWait);
  idle_check_timer_.Start(FROM_HERE, idle_timer, this,
                          &UpgradeDetector::CheckIdle);
}

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::TriggerNotification(chrome::NotificationType type) {
  content::NotificationService::current()->Notify(
      type,
      content::Source<UpgradeDetector>(this),
      content::NotificationService::NoDetails());
}

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();
      TriggerNotification(chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED);
      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;
  }
}