Upload upstream chromium 69.0.3497
[platform/framework/web/chromium-efl.git] / chrome / browser / upgrade_detector.cc
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/time/tick_clock.h"
10 #include "chrome/app/vector_icons/vector_icons.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/lifetime/application_lifetime.h"
13 #include "chrome/browser/ui/browser_otr_state.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/prefs/pref_registry_simple.h"
17 #include "components/prefs/pref_service.h"
18 #include "ui/gfx/color_palette.h"
19 #include "ui/gfx/paint_vector_icon.h"
20
21 // How long to wait between checks for whether the user has been idle.
22 static const int kIdleRepeatingTimerWait = 10;  // Minutes (seconds if testing).
23
24 // How much idle time (since last input even was detected) must have passed
25 // until we notify that a critical update has occurred.
26 static const int kIdleAmount = 2;  // Hours (or seconds, if testing).
27
28 bool UseTestingIntervals() {
29   // If a command line parameter specifying how long the upgrade check should
30   // be, we assume it is for testing and switch to using seconds instead of
31   // hours.
32   const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
33   return !cmd_line.GetSwitchValueASCII(
34       switches::kCheckForUpdateIntervalSec).empty();
35 }
36
37 // static
38 void UpgradeDetector::RegisterPrefs(PrefRegistrySimple* registry) {
39   registry->RegisterBooleanPref(prefs::kAttemptedToEnableAutoupdate, false);
40 }
41
42 gfx::Image UpgradeDetector::GetIcon() {
43   SkColor color = gfx::kPlaceholderColor;
44   switch (upgrade_notification_stage_) {
45     case UPGRADE_ANNOYANCE_NONE:
46       return gfx::Image();
47     case UPGRADE_ANNOYANCE_LOW:
48       color = gfx::kGoogleGreen700;
49       break;
50     case UPGRADE_ANNOYANCE_ELEVATED:
51       color = gfx::kGoogleYellow700;
52       break;
53     case UPGRADE_ANNOYANCE_HIGH:
54     case UPGRADE_ANNOYANCE_CRITICAL:
55       color = gfx::kGoogleRed700;
56       break;
57   }
58   DCHECK_NE(gfx::kPlaceholderColor, color);
59
60   return gfx::Image(gfx::CreateVectorIcon(kBrowserToolsUpdateIcon, color));
61 }
62
63 UpgradeDetector::UpgradeDetector(const base::TickClock* tick_clock)
64     : tick_clock_(tick_clock),
65       upgrade_available_(UPGRADE_AVAILABLE_NONE),
66       best_effort_experiment_updates_available_(false),
67       critical_experiment_updates_available_(false),
68       critical_update_acknowledged_(false),
69       is_factory_reset_required_(false),
70       idle_check_timer_(tick_clock_),
71       upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE),
72       notify_upgrade_(false) {
73   // Not all tests provide a PrefService for local_state().
74   PrefService* local_state = g_browser_process->local_state();
75   if (local_state) {
76     pref_change_registrar_.Init(local_state);
77     // base::Unretained is safe here because |this| outlives the registrar.
78     pref_change_registrar_.Add(
79         prefs::kRelaunchNotificationPeriod,
80         base::BindRepeating(
81             &UpgradeDetector::OnRelaunchNotificationPeriodPrefChanged,
82             base::Unretained(this)));
83   }
84 }
85
86 UpgradeDetector::~UpgradeDetector() {
87 }
88
89 void UpgradeDetector::NotifyOutdatedInstall() {
90   for (auto& observer : observer_list_)
91     observer.OnOutdatedInstall();
92 }
93
94 void UpgradeDetector::NotifyOutdatedInstallNoAutoUpdate() {
95   for (auto& observer : observer_list_)
96     observer.OnOutdatedInstallNoAutoUpdate();
97 }
98
99 // static
100 base::TimeDelta UpgradeDetector::GetRelaunchNotificationPeriod() {
101   // Not all tests provide a PrefService for local_state().
102   auto* local_state = g_browser_process->local_state();
103   if (!local_state)
104     return base::TimeDelta();
105   const auto* preference =
106       local_state->FindPreference(prefs::kRelaunchNotificationPeriod);
107   const int value = preference->GetValue()->GetInt();
108   // Enforce the preference's documented minimum value.
109   static constexpr base::TimeDelta kMinValue = base::TimeDelta::FromHours(1);
110   if (preference->IsDefaultValue() || value < kMinValue.InMilliseconds())
111     return base::TimeDelta();
112   return base::TimeDelta::FromMilliseconds(value);
113 }
114
115 void UpgradeDetector::NotifyUpgrade() {
116   // An implementation will request that a notification be sent after dropping
117   // back to the "none" annoyance level if the RelaunchNotificationPeriod
118   // setting changes to a large enough value such that none of the revised
119   // thresholds have been hit. In this case, consumers should not perceive that
120   // an upgrade is available when checking notify_upgrade(). In practice, this
121   // is only the case on desktop Chrome and not Chrome OS, where the lowest
122   // threshold is hit the moment the upgrade is detected.
123   notify_upgrade_ = upgrade_notification_stage_ != UPGRADE_ANNOYANCE_NONE;
124
125   NotifyUpgradeRecommended();
126   if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL) {
127     NotifyOutdatedInstall();
128   } else if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU) {
129     NotifyOutdatedInstallNoAutoUpdate();
130   } else if (upgrade_available_ == UPGRADE_AVAILABLE_CRITICAL ||
131              critical_experiment_updates_available_) {
132     TriggerCriticalUpdate();
133   }
134 }
135
136 void UpgradeDetector::NotifyUpgradeRecommended() {
137   for (auto& observer : observer_list_)
138     observer.OnUpgradeRecommended();
139 }
140
141 void UpgradeDetector::NotifyCriticalUpgradeInstalled() {
142   for (auto& observer : observer_list_)
143     observer.OnCriticalUpgradeInstalled();
144 }
145
146 void UpgradeDetector::NotifyUpdateOverCellularAvailable() {
147   for (auto& observer : observer_list_)
148     observer.OnUpdateOverCellularAvailable();
149 }
150
151 void UpgradeDetector::NotifyUpdateOverCellularOneTimePermissionGranted() {
152   for (auto& observer : observer_list_)
153     observer.OnUpdateOverCellularOneTimePermissionGranted();
154 }
155
156 void UpgradeDetector::TriggerCriticalUpdate() {
157   const base::TimeDelta idle_timer = UseTestingIntervals() ?
158       base::TimeDelta::FromSeconds(kIdleRepeatingTimerWait) :
159       base::TimeDelta::FromMinutes(kIdleRepeatingTimerWait);
160   idle_check_timer_.Start(FROM_HERE, idle_timer, this,
161                           &UpgradeDetector::CheckIdle);
162 }
163
164 void UpgradeDetector::CheckIdle() {
165   // CalculateIdleState expects an interval in seconds.
166   int idle_time_allowed = UseTestingIntervals() ? kIdleAmount :
167                                                   kIdleAmount * 60 * 60;
168
169   CalculateIdleState(
170       idle_time_allowed, base::Bind(&UpgradeDetector::IdleCallback,
171                                     base::Unretained(this)));
172 }
173
174 void UpgradeDetector::IdleCallback(ui::IdleState state) {
175   // Don't proceed while an incognito window is open. The timer will still
176   // keep firing, so this function will get a chance to re-evaluate this.
177   if (chrome::IsIncognitoSessionActive())
178     return;
179
180   switch (state) {
181     case ui::IDLE_STATE_LOCKED:
182       // Computer is locked, auto-restart.
183       idle_check_timer_.Stop();
184       chrome::AttemptRestart();
185       break;
186     case ui::IDLE_STATE_IDLE:
187       // Computer has been idle for long enough, show warning.
188       idle_check_timer_.Stop();
189       NotifyCriticalUpgradeInstalled();
190       break;
191     case ui::IDLE_STATE_ACTIVE:
192     case ui::IDLE_STATE_UNKNOWN:
193       break;
194     default:
195       NOTREACHED();  // Need to add any new value above (either providing
196                      // automatic restart or show notification to user).
197       break;
198   }
199 }
200
201 void UpgradeDetector::AddObserver(UpgradeObserver* observer) {
202   observer_list_.AddObserver(observer);
203 }
204
205 void UpgradeDetector::RemoveObserver(UpgradeObserver* observer) {
206   observer_list_.RemoveObserver(observer);
207 }