Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(656)

Side by Side Diff: chrome/browser/upgrade_detector_impl.cc

Issue 211543008: Show a modified outdated upgrade Bubble for non-enterprise users without auto-update (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/upgrade_detector_impl.h" 5 #include "chrome/browser/upgrade_detector_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/build_time.h" 10 #include "base/build_time.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/singleton.h" 14 #include "base/memory/singleton.h"
15 #include "base/path_service.h" 15 #include "base/path_service.h"
16 #include "base/prefs/pref_service.h"
16 #include "base/process/launch.h" 17 #include "base/process/launch.h"
17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h" 21 #include "base/time/time.h"
21 #include "base/version.h" 22 #include "base/version.h"
22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/google/google_util.h" 24 #include "chrome/browser/google/google_util.h"
24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/chrome_version_info.h" 26 #include "chrome/common/chrome_version_info.h"
27 #include "chrome/common/pref_names.h"
26 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
27 #include "ui/base/resource/resource_bundle.h" 29 #include "ui/base/resource/resource_bundle.h"
28 30
29 #if defined(OS_WIN) 31 #if defined(OS_WIN)
32 #include "base/win/win_util.h"
30 #include "chrome/installer/util/browser_distribution.h" 33 #include "chrome/installer/util/browser_distribution.h"
31 #include "chrome/installer/util/google_update_settings.h" 34 #include "chrome/installer/util/google_update_settings.h"
32 #include "chrome/installer/util/helper.h" 35 #include "chrome/installer/util/helper.h"
33 #include "chrome/installer/util/install_util.h" 36 #include "chrome/installer/util/install_util.h"
34 #elif defined(OS_MACOSX) 37 #elif defined(OS_MACOSX)
35 #include "chrome/browser/mac/keystone_glue.h" 38 #include "chrome/browser/mac/keystone_glue.h"
36 #elif defined(OS_POSIX) 39 #elif defined(OS_POSIX)
37 #include "base/process/launch.h" 40 #include "base/process/launch.h"
38 #endif 41 #endif
39 42
(...skipping 13 matching lines...) Expand all
53 const int kNotifyCycleTimeForTestingMs = 500; // Half a second. 56 const int kNotifyCycleTimeForTestingMs = 500; // Half a second.
54 57
55 // The number of days after which we identify a build/install as outdated. 58 // The number of days after which we identify a build/install as outdated.
56 const uint64 kOutdatedBuildAgeInDays = 12 * 7; 59 const uint64 kOutdatedBuildAgeInDays = 12 * 7;
57 60
58 std::string CmdLineInterval() { 61 std::string CmdLineInterval() {
59 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 62 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
60 return cmd_line.GetSwitchValueASCII(switches::kCheckForUpdateIntervalSec); 63 return cmd_line.GetSwitchValueASCII(switches::kCheckForUpdateIntervalSec);
61 } 64 }
62 65
66 bool SimulatingOutdated() {
67 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
68 return cmd_line.HasSwitch(switches::kSimulateOutdated) ||
69 cmd_line.HasSwitch(switches::kSimulateOutdatedNoAU);
70 }
71
63 bool IsTesting() { 72 bool IsTesting() {
64 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 73 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
65 return cmd_line.HasSwitch(switches::kSimulateUpgrade) || 74 return cmd_line.HasSwitch(switches::kSimulateUpgrade) ||
66 cmd_line.HasSwitch(switches::kCheckForUpdateIntervalSec) || 75 cmd_line.HasSwitch(switches::kCheckForUpdateIntervalSec) ||
67 cmd_line.HasSwitch(switches::kSimulateCriticalUpdate) || 76 cmd_line.HasSwitch(switches::kSimulateCriticalUpdate) ||
68 cmd_line.HasSwitch(switches::kSimulateOutdated); 77 SimulatingOutdated();
69 } 78 }
70 79
71 // How often to check for an upgrade. 80 // How often to check for an upgrade.
72 int GetCheckForUpgradeEveryMs() { 81 int GetCheckForUpgradeEveryMs() {
73 // Check for a value passed via the command line. 82 // Check for a value passed via the command line.
74 int interval_ms; 83 int interval_ms;
75 std::string interval = CmdLineInterval(); 84 std::string interval = CmdLineInterval();
76 if (!interval.empty() && base::StringToInt(interval, &interval_ms)) 85 if (!interval.empty() && base::StringToInt(interval, &interval_ms))
77 return interval_ms * 1000; // Command line value is in seconds. 86 return interval_ms * 1000; // Command line value is in seconds.
78 87
(...skipping 27 matching lines...) Expand all
106 return false; 115 return false;
107 } 116 }
108 117
109 return !InstallUtil::IsPerUserInstall(exe_path.value().c_str()); 118 return !InstallUtil::IsPerUserInstall(exe_path.value().c_str());
110 } 119 }
111 120
112 // This task checks the update policy and calls back the task only if automatic 121 // This task checks the update policy and calls back the task only if automatic
113 // updates are allowed. It also identifies whether we are running an unstable 122 // updates are allowed. It also identifies whether we are running an unstable
114 // channel. 123 // channel.
115 void DetectUpdatability(const base::Closure& callback_task, 124 void DetectUpdatability(const base::Closure& callback_task,
116 bool* is_unstable_channel) { 125 bool* is_unstable_channel,
126 bool* is_autoupdate_on) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
118 128
119 base::string16 app_guid = installer::GetAppGuidForUpdates(IsSystemInstall()); 129 base::string16 app_guid = installer::GetAppGuidForUpdates(IsSystemInstall());
120 DCHECK(!app_guid.empty()); 130 DCHECK(!app_guid.empty());
121 if (GoogleUpdateSettings::AUTOMATIC_UPDATES == 131 // Don't try to turn on autoupdate when we failed previously.
122 GoogleUpdateSettings::GetAppUpdatePolicy(app_guid, NULL)) { 132 if (g_browser_process->local_state() &&
133 !g_browser_process->local_state()->GetBoolean(
134 prefs::kFailedTurningOnAutoupdate)) {
robertshield 2014/03/26 03:20:11 nit: indent. Moreover, I think we should call th
MAD 2014/03/26 19:30:16 Done. Interestingly, the initial name I had was tr
135 *is_autoupdate_on = GoogleUpdateSettings::AUTOMATIC_UPDATES ==
136 GoogleUpdateSettings::GetAppUpdatePolicy(app_guid, NULL);
137 }
138 // Don't show the update bubbles to entreprise users (i.e., on a domain).
139 if (!base::win::IsEnrolledToDomain())
123 CheckForUnstableChannel(callback_task, is_unstable_channel); 140 CheckForUnstableChannel(callback_task, is_unstable_channel);
124 }
125 } 141 }
126 #endif // defined(OS_WIN) 142 #endif // defined(OS_WIN)
127 143
128 } // namespace 144 } // namespace
129 145
130 UpgradeDetectorImpl::UpgradeDetectorImpl() 146 UpgradeDetectorImpl::UpgradeDetectorImpl()
131 : weak_factory_(this), 147 : weak_factory_(this),
132 is_unstable_channel_(false), 148 is_unstable_channel_(false),
149 is_autoupdate_on_(true),
133 build_date_(base::GetBuildTime()) { 150 build_date_(base::GetBuildTime()) {
151 // Start tracking network time updates.
152 network_time_tracker_.Start();
153
134 CommandLine command_line(*CommandLine::ForCurrentProcess()); 154 CommandLine command_line(*CommandLine::ForCurrentProcess());
135 // The different command line switches that affect testing can't be used 155 // The different command line switches that affect testing can't be used
136 // simultaneously, if they do, here's the precedence order, based on the order 156 // simultaneously, if they do, here's the precedence order, based on the order
137 // of the if statements below: 157 // of the if statements below:
138 // - kDisableBackgroundNetworking prevents any of the other command line 158 // - kDisableBackgroundNetworking prevents any of the other command line
139 // switch from being taken into account. 159 // switch from being taken into account.
140 // - kSimulateUpgrade supersedes critical or outdated upgrade switches. 160 // - kSimulateUpgrade supersedes critical or outdated upgrade switches.
141 // - kSimulateCriticalUpdate has precedence over kSimulateOutdated. 161 // - kSimulateCriticalUpdate has precedence over kSimulateOutdated.
142 // - kSimulateOutdated can work on its own, or with a specified date. 162 // - kSimulateOutdatedNoAU has precedence over kSimulateOutdated.
163 // - kSimulateOutdated[NoAu] can work on its own, or with a specified date.
143 if (command_line.HasSwitch(switches::kDisableBackgroundNetworking)) 164 if (command_line.HasSwitch(switches::kDisableBackgroundNetworking))
144 return; 165 return;
145 if (command_line.HasSwitch(switches::kSimulateUpgrade)) { 166 if (command_line.HasSwitch(switches::kSimulateUpgrade)) {
146 UpgradeDetected(UPGRADE_AVAILABLE_REGULAR); 167 UpgradeDetected(UPGRADE_AVAILABLE_REGULAR);
147 return; 168 return;
148 } 169 }
149 if (command_line.HasSwitch(switches::kSimulateCriticalUpdate)) { 170 if (command_line.HasSwitch(switches::kSimulateCriticalUpdate)) {
150 UpgradeDetected(UPGRADE_AVAILABLE_CRITICAL); 171 UpgradeDetected(UPGRADE_AVAILABLE_CRITICAL);
151 return; 172 return;
152 } 173 }
153 if (command_line.HasSwitch(switches::kSimulateOutdated)) { 174 if (SimulatingOutdated()) {
154 // The outdated simulation can work without a value, which means outdated 175 // The outdated simulation can work without a value, which means outdated
155 // now, or with a value that must be a well formed date/time string that 176 // now, or with a value that must be a well formed date/time string that
156 // overrides the build date. 177 // overrides the build date.
157 // Also note that to test with a given time/date, until the network time 178 // Also note that to test with a given time/date, until the network time
158 // tracking moves off of the VariationsService, the "variations-server-url" 179 // tracking moves off of the VariationsService, the "variations-server-url"
159 // command line switch must also be specified for the service to be 180 // command line switch must also be specified for the service to be
160 // available on non GOOGLE_CHROME_BUILD. 181 // available on non GOOGLE_CHROME_BUILD.
161 std::string build_date = command_line.GetSwitchValueASCII( 182 std::string switch_name;
162 switches::kSimulateOutdated); 183 if (command_line.HasSwitch(switches::kSimulateOutdatedNoAU)) {
184 is_autoupdate_on_ = false;
185 switch_name = switches::kSimulateOutdatedNoAU;
186 } else {
187 switch_name = switches::kSimulateOutdated;
188 }
189 std::string build_date = command_line.GetSwitchValueASCII(switch_name);
163 base::Time maybe_build_time; 190 base::Time maybe_build_time;
164 bool result = base::Time::FromString(build_date.c_str(), &maybe_build_time); 191 bool result = base::Time::FromString(build_date.c_str(), &maybe_build_time);
165 if (result && !maybe_build_time.is_null()) { 192 if (result && !maybe_build_time.is_null()) {
166 // We got a valid build date simulation so use it and check for upgrades. 193 // We got a valid build date simulation so use it and check for upgrades.
167 build_date_ = maybe_build_time; 194 build_date_ = maybe_build_time;
168 StartTimerForUpgradeCheck(); 195 StartTimerForUpgradeCheck();
169 } else { 196 } else {
170 // Without a valid date, we simulate that we are already outdated... 197 // Without a valid date, we simulate that we are already outdated...
171 UpgradeDetected(UPGRADE_NEEDED_OUTDATED_INSTALL); 198 UpgradeDetected(
199 is_autoupdate_on_ ? UPGRADE_NEEDED_OUTDATED_INSTALL
200 : UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU);
172 } 201 }
173 return; 202 return;
174 } 203 }
175 204
176 base::Closure start_upgrade_check_timer_task = 205 base::Closure start_upgrade_check_timer_task =
177 base::Bind(&UpgradeDetectorImpl::StartTimerForUpgradeCheck, 206 base::Bind(&UpgradeDetectorImpl::StartTimerForUpgradeCheck,
178 weak_factory_.GetWeakPtr()); 207 weak_factory_.GetWeakPtr());
179 208
180 #if defined(OS_WIN) 209 #if defined(OS_WIN)
181 // Only enable upgrade notifications for official builds. Chromium has no 210 // Only enable upgrade notifications for official builds. Chromium has no
182 // upgrade channel. 211 // upgrade channel.
183 #if defined(GOOGLE_CHROME_BUILD) 212 #if defined(GOOGLE_CHROME_BUILD)
184 // On Windows, there might be a policy preventing updates, so validate 213 // On Windows, there might be a policy preventing updates, so validate
185 // updatability, and then call StartTimerForUpgradeCheck appropriately. 214 // updatability, and then call StartTimerForUpgradeCheck appropriately.
186 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 215 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
187 base::Bind(&DetectUpdatability, 216 base::Bind(&DetectUpdatability,
188 start_upgrade_check_timer_task, 217 start_upgrade_check_timer_task,
189 &is_unstable_channel_)); 218 &is_unstable_channel_,
219 &is_autoupdate_on_));
190 #endif 220 #endif
191 #else 221 #else
192 #if defined(OS_MACOSX) 222 #if defined(OS_MACOSX)
193 // Only enable upgrade notifications if the updater (Keystone) is present. 223 // Only enable upgrade notifications if the updater (Keystone) is present.
194 if (!keystone_glue::KeystoneEnabled()) 224 if (!keystone_glue::KeystoneEnabled()) {
225 is_autoupdate_on_ = false;
195 return; 226 return;
227 }
196 #elif defined(OS_POSIX) 228 #elif defined(OS_POSIX)
197 // Always enable upgrade notifications regardless of branding. 229 // Always enable upgrade notifications regardless of branding.
198 #else 230 #else
199 return; 231 return;
200 #endif 232 #endif
201 // Check whether the build is an unstable channel before starting the timer. 233 // Check whether the build is an unstable channel before starting the timer.
202 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 234 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
203 base::Bind(&CheckForUnstableChannel, 235 base::Bind(&CheckForUnstableChannel,
204 start_upgrade_check_timer_task, 236 start_upgrade_check_timer_task,
205 &is_unstable_channel_)); 237 &is_unstable_channel_));
206
207 // Start tracking network time updates.
208 network_time_tracker_.Start();
209 #endif 238 #endif
210 } 239 }
211 240
212 UpgradeDetectorImpl::~UpgradeDetectorImpl() { 241 UpgradeDetectorImpl::~UpgradeDetectorImpl() {
213 } 242 }
214 243
215 // Static 244 // Static
216 // This task checks the currently running version of Chrome against the 245 // This task checks the currently running version of Chrome against the
217 // installed version. If the installed version is newer, it calls back 246 // installed version. If the installed version is newer, it calls back
218 // UpgradeDetectorImpl::UpgradeDetected using a weak pointer so that it can 247 // UpgradeDetectorImpl::UpgradeDetected using a weak pointer so that it can
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 // We use FILE as the thread to run the upgrade detection code on all 337 // We use FILE as the thread to run the upgrade detection code on all
309 // platforms. For Linux, this is because we don't want to block the UI thread 338 // platforms. For Linux, this is because we don't want to block the UI thread
310 // while launching a background process and reading its output; on the Mac and 339 // while launching a background process and reading its output; on the Mac and
311 // on Windows checking for an upgrade requires reading a file. 340 // on Windows checking for an upgrade requires reading a file.
312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 341 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
313 base::Bind(&UpgradeDetectorImpl::DetectUpgradeTask, 342 base::Bind(&UpgradeDetectorImpl::DetectUpgradeTask,
314 weak_factory_.GetWeakPtr())); 343 weak_factory_.GetWeakPtr()));
315 } 344 }
316 345
317 bool UpgradeDetectorImpl::DetectOutdatedInstall() { 346 bool UpgradeDetectorImpl::DetectOutdatedInstall() {
318 // Only enable the outdated install check if we are running the trial for it, 347 // Don't show the bubble if we have a brand code that is NOT organic, unless
robertshield 2014/03/26 03:20:11 why is this limited to only organic brand codes?
MAD 2014/03/26 19:30:16 It was discussed around here: https://code.google.
319 // unless we are simulating an outdated isntall. 348 // an outdated build is being simulated by command line switches.
320 static bool simulate_outdated = CommandLine::ForCurrentProcess()->HasSwitch( 349 static bool simulate_outdated = SimulatingOutdated();
321 switches::kSimulateOutdated);
322 if (!simulate_outdated) { 350 if (!simulate_outdated) {
323 // Also don't show the bubble if we have a brand code that is NOT organic.
324 std::string brand; 351 std::string brand;
325 if (google_util::GetBrand(&brand) && !google_util::IsOrganic(brand)) 352 if (google_util::GetBrand(&brand) && !google_util::IsOrganic(brand))
326 return false; 353 return false;
327 } 354 }
328 355
329 base::Time network_time; 356 base::Time network_time;
330 base::TimeDelta uncertainty; 357 base::TimeDelta uncertainty;
331 if (!network_time_tracker_.GetNetworkTime(base::TimeTicks::Now(), 358 if (!network_time_tracker_.GetNetworkTime(base::TimeTicks::Now(),
332 &network_time, 359 &network_time,
333 &uncertainty)) { 360 &uncertainty)) {
334 return false; 361 // When network time has not been initialized yet, simply rely on the
362 // machine's current time.
363 network_time = base::Time::Now();
335 } 364 }
336 365
337 if (network_time.is_null() || build_date_.is_null() || 366 if (network_time.is_null() || build_date_.is_null() ||
338 build_date_ > network_time) { 367 build_date_ > network_time) {
339 NOTREACHED(); 368 NOTREACHED();
340 return false; 369 return false;
341 } 370 }
342 371
343 if (network_time - build_date_ > 372 if (network_time - build_date_ >
344 base::TimeDelta::FromDays(kOutdatedBuildAgeInDays)) { 373 base::TimeDelta::FromDays(kOutdatedBuildAgeInDays)) {
345 UpgradeDetected(UPGRADE_NEEDED_OUTDATED_INSTALL); 374 UpgradeDetected(is_autoupdate_on_ ? UPGRADE_NEEDED_OUTDATED_INSTALL
375 : UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU);
346 return true; 376 return true;
347 } 377 }
348 // If we simlated an outdated install with a date, we don't want to keep 378 // If we simlated an outdated install with a date, we don't want to keep
349 // checking for version upgrades, which happens on non-official builds. 379 // checking for version upgrades, which happens on non-official builds.
350 return simulate_outdated; 380 return simulate_outdated;
351 } 381 }
352 382
353 void UpgradeDetectorImpl::UpgradeDetected(UpgradeAvailable upgrade_available) { 383 void UpgradeDetectorImpl::UpgradeDetected(UpgradeAvailable upgrade_available) {
354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
355 upgrade_available_ = upgrade_available; 385 upgrade_available_ = upgrade_available;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 456
427 // static 457 // static
428 UpgradeDetectorImpl* UpgradeDetectorImpl::GetInstance() { 458 UpgradeDetectorImpl* UpgradeDetectorImpl::GetInstance() {
429 return Singleton<UpgradeDetectorImpl>::get(); 459 return Singleton<UpgradeDetectorImpl>::get();
430 } 460 }
431 461
432 // static 462 // static
433 UpgradeDetector* UpgradeDetector::GetInstance() { 463 UpgradeDetector* UpgradeDetector::GetInstance() {
434 return UpgradeDetectorImpl::GetInstance(); 464 return UpgradeDetectorImpl::GetInstance();
435 } 465 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698