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

Side by Side Diff: chrome/browser/ui/webui/help/version_updater_win.cc

Issue 10698106: Switch about box to web ui on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added GetForegroundWindow Created 8 years, 5 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
(Empty)
1 // Use of this source code is governed by a BSD-style license that can be
2 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 // found in the LICENSE file.
4
5 #include "base/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/string16.h"
9 #include "base/version.h"
10 #include "base/win/windows_version.h"
11 #include "base/win/win_util.h"
12 #include "chrome/browser/google/google_update.h"
13 #include "chrome/browser/lifetime/application_lifetime.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/webui/help/version_updater.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/installer/util/browser_distribution.h"
18 #include "chrome/installer/util/install_util.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/user_metrics.h"
21 #include "grit/chromium_strings.h"
22 #include "grit/generated_resources.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/views/widget/widget.h"
25
26 using content::BrowserThread;
27 using content::UserMetricsAction;
28
29 namespace {
30
31 // Windows implementation of version update functionality, used by the WebUI
32 // About/Help page.
33 class VersionUpdaterWin : public VersionUpdater,
34 public GoogleUpdateStatusListener {
35 private:
36 friend class VersionReader;
37 friend class VersionUpdater;
38
39 // Clients must use VersionUpdater::Create().
40 VersionUpdaterWin();
41 virtual ~VersionUpdaterWin();
42
43 // VersionUpdater implementation.
44 virtual void CheckForUpdate(const StatusCallback& callback) OVERRIDE;
45 virtual void RelaunchBrowser() const OVERRIDE;
46
47 // GoogleUpdateStatusListener implementation.
48 virtual void OnReportResults(GoogleUpdateUpgradeResult result,
49 GoogleUpdateErrorCode error_code,
50 const string16& error_message,
51 const string16& version) OVERRIDE;
52
53 // Update the UI to show the status of the upgrade.
54 void UpdateStatus(GoogleUpdateUpgradeResult result,
55 GoogleUpdateErrorCode error_code,
56 const string16& error_message);
57
58 // Got the intalled version so the handling of the UPGRADE_ALREADY_UP_TO_DATE
59 // result case can now be completeb on the UI thread.
60 void GotInstalledVersion(const Version* version);
61
62 // Little helper function to reset google_updater_.
63 void SetGoogleUpdater();
64
65 // The class that communicates with Google Update to find out if an update is
66 // available and asks it to start an upgrade.
67 scoped_refptr<GoogleUpdate> google_updater_;
68
69 // Used for callbacks.
70 base::WeakPtrFactory<VersionUpdaterWin> weak_factory_;
71
72 // Callback used to communicate update status to the client.
73 StatusCallback callback_;
74
75 DISALLOW_COPY_AND_ASSIGN(VersionUpdaterWin);
76 };
77
78 // We use this class to read the version on the FILE thread and then call back
79 // the version updater in the UI thread. We use a class so that we can control
80 // the lifespan of the Version independently of the lifespan of the version
81 // updater, which may die while asynchonicity is happening, thus the usage of
82 // the WeakPtr, which can only be used from the thread that created it.
83 class VersionReader
84 : public base::RefCountedThreadSafe<VersionReader> {
85 public:
86 explicit VersionReader(
87 const base::WeakPtr<VersionUpdaterWin>& version_updater)
88 : version_updater_(version_updater) {
89 }
90
91 void GetVersionFromFileThread() {
92 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
93 installed_version_.reset(InstallUtil::GetChromeVersion(dist, false));
94 if (!installed_version_.get()) {
95 // User-level Chrome is not installed, check system-level.
96 installed_version_.reset(InstallUtil::GetChromeVersion(dist, true));
97 }
98 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
99 &VersionReader::SetVersionInUIThread, this));
100 }
101
102 void SetVersionInUIThread() {
103 if (version_updater_.get() != NULL)
104 version_updater_->GotInstalledVersion(installed_version_.get());
105 }
106
107 private:
108 friend class base::RefCountedThreadSafe<VersionReader>;
109
110 base::WeakPtr<VersionUpdaterWin> version_updater_;
111 scoped_ptr<Version> installed_version_;
112 };
113
114 VersionUpdaterWin::VersionUpdaterWin()
115 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
116 SetGoogleUpdater();
117 }
118
119 VersionUpdaterWin::~VersionUpdaterWin() {
120 // The Google Updater will hold a pointer to us until it reports status, so we
121 // need to let it know that we will no longer be listening.
122 if (google_updater_)
123 google_updater_->set_status_listener(NULL);
124 }
125
126 void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) {
127 callback_ = callback;
128
129 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
130 // off. So, in this case we just want the About box to not mention
131 // on-demand updates. Silent updates (in the background) should still
132 // work as before - enabling UAC or installing the latest service pack
133 // for Vista is another option.
134 if (!(base::win::GetVersion() == base::win::VERSION_VISTA &&
135 (base::win::OSInfo::GetInstance()->service_pack().major == 0) &&
136 !base::win::UserAccountControlIsEnabled())) {
137 // This could happen if we already got results, but the page got refreshed.
138 if (!google_updater_)
139 SetGoogleUpdater();
140 UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR, string16());
141 google_updater_->CheckForUpdate(false); // Don't upgrade yet.
142 }
143 }
144
145 void VersionUpdaterWin::RelaunchBrowser() const {
146 browser::AttemptRestart();
147 }
148
149 void VersionUpdaterWin::OnReportResults(
150 GoogleUpdateUpgradeResult result, GoogleUpdateErrorCode error_code,
151 const string16& error_message, const string16& version) {
152 // Drop the last reference to the object so that it gets cleaned up here.
153 google_updater_ = NULL;
154 UpdateStatus(result, error_code, error_message);
155 }
156
157 void VersionUpdaterWin::UpdateStatus(GoogleUpdateUpgradeResult result,
158 GoogleUpdateErrorCode error_code,
159 const string16& error_message) {
160 // For Chromium builds it would show an error message.
161 // But it looks weird because in fact there is no error,
162 // just the update server is not available for non-official builds.
163 #if defined(GOOGLE_CHROME_BUILD)
164 Status status = UPDATED;
165 string16 message;
166
167 switch (result) {
168 case UPGRADE_CHECK_STARTED: {
169 content::RecordAction(UserMetricsAction("UpgradeCheck_Started"));
170 status = CHECKING;
171 break;
172 }
173 case UPGRADE_STARTED: {
174 content::RecordAction(UserMetricsAction("Upgrade_Started"));
175 status = UPDATING;
176 break;
177 }
178 case UPGRADE_IS_AVAILABLE: {
179 content::RecordAction(
180 UserMetricsAction("UpgradeCheck_UpgradeIsAvailable"));
181 DCHECK(!google_updater_); // Should have been nulled out already.
182 SetGoogleUpdater();
183 UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR, string16());
184 google_updater_->CheckForUpdate(true); // Upgrade now.
185 return;
186 }
187 case UPGRADE_ALREADY_UP_TO_DATE: {
188 // Google Update reported that Chrome is up-to-date.
189 // We need to confirm we are running the updated version.
190 // But we must defer version reading to the file thread...
191 // We'll handle the rest of this case within GotInstalledVersion below.
192 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
193 &VersionReader::GetVersionFromFileThread,
194 new VersionReader(weak_factory_.GetWeakPtr())));
195 return;
196 }
197 case UPGRADE_SUCCESSFUL: {
198 content::RecordAction(UserMetricsAction("UpgradeCheck_Upgraded"));
199 status = NEARLY_UPDATED;
200 break;
201 }
202 case UPGRADE_ERROR: {
203 content::RecordAction(UserMetricsAction("UpgradeCheck_Error"));
204 status = FAILED;
205 if (error_code != GOOGLE_UPDATE_DISABLED_BY_POLICY) {
206 message =
207 l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code);
208 } else {
209 message =
210 l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY);
211 }
212 if (!error_message.empty()) {
213 message +=
214 l10n_util::GetStringFUTF16(IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK,
215 error_message);
216 }
217 break;
218 }
219 }
220
221 // TODO(mad): Get proper progress value instead of passing 0.
222 // http://crbug.com/136117
223 callback_.Run(status, 0, message);
224 #endif // defined(GOOGLE_CHROME_BUILD)
225 }
226
227 void VersionUpdaterWin::GotInstalledVersion(const Version* version) {
228 // This must be called on the UI thread so that we can call callback_.
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230
231 // Make sure that we are running the latest version and if not,
232 // notify the user by setting the status to NEARLY_UPDATED.
233 //
234 // The extra version check is necessary on Windows because the application
235 // may be already up to date on disk though the running app is still
236 // out of date.
237 chrome::VersionInfo version_info;
238 scoped_ptr<Version> running_version(
239 Version::GetVersionFromString(version_info.Version()));
240 if (!version || (version->CompareTo(*running_version) <= 0)) {
241 content::RecordAction(
242 UserMetricsAction("UpgradeCheck_AlreadyUpToDate"));
243 callback_.Run(UPDATED, 0, string16());
244 } else {
245 content::RecordAction(UserMetricsAction("UpgradeCheck_AlreadyUpgraded"));
246 callback_.Run(NEARLY_UPDATED, 0, string16());
247 }
248 }
249
250 void VersionUpdaterWin::SetGoogleUpdater() {
251 google_updater_ = new GoogleUpdate();
252 google_updater_->set_status_listener(this);
253 }
254
255 } // namespace
256
257 VersionUpdater* VersionUpdater::Create() {
258 return new VersionUpdaterWin;
259 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698