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

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

Issue 1117263002: Switch on-demand update checks to the less-old GoogleUpdate3 API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: chromium tweak Created 5 years, 7 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
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 "base/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/memory/weak_ptr.h" 5 #include "base/memory/weak_ptr.h"
8 #include "base/strings/string16.h" 6 #include "base/strings/string16.h"
9 #include "base/version.h"
10 #include "base/win/win_util.h" 7 #include "base/win/win_util.h"
11 #include "base/win/windows_version.h" 8 #include "base/win/windows_version.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/first_run/upgrade_util_win.h"
12 #include "chrome/browser/google/google_update_win.h" 11 #include "chrome/browser/google/google_update_win.h"
13 #include "chrome/browser/lifetime/application_lifetime.h" 12 #include "chrome/browser/lifetime/application_lifetime.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/webui/help/version_updater.h" 13 #include "chrome/browser/ui/webui/help/version_updater.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/grit/chromium_strings.h"
18 #include "chrome/grit/generated_resources.h" 14 #include "chrome/grit/generated_resources.h"
19 #include "chrome/installer/util/browser_distribution.h"
20 #include "chrome/installer/util/install_util.h"
21 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
22 #include "ui/base/l10n/l10n_util.h" 16 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/gfx/native_widget_types.h" 17 #include "ui/gfx/native_widget_types.h"
24 #include "ui/views/widget/widget.h"
25
26 using content::BrowserThread;
27 18
28 namespace { 19 namespace {
29 20
21 // An EnumThreadWndProc that returns the first visible window via |param|,
22 // stopping the enumeration when one is found.
23 BOOL CALLBACK WindowEnumeration(HWND window, LPARAM param) {
24 if (!IsWindowVisible(window))
25 return TRUE;
26 HWND* returned_window = reinterpret_cast<HWND*>(param);
Peter Kasting 2015/05/09 02:19:02 Nit: I'd probably just inline this into the next l
grt (UTC plus 2) 2015/05/12 20:21:52 Done.
27 *returned_window = window;
28 return FALSE;
29 }
30
31 // Returns a visible Chrome Window, or null if none is found.
32 gfx::AcceleratedWidget FindVisibleWindow() {
33 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
34 HWND window = nullptr;
35 EnumThreadWindows(GetCurrentThreadId(), &WindowEnumeration,
Peter Kasting 2015/05/09 02:19:02 It makes me uncomfortable to have Windows calls do
grt (UTC plus 2) 2015/05/12 20:21:52 Done. There's a slight change in behavior, but aft
36 reinterpret_cast<LPARAM>(&window));
37 return window;
38 }
39
30 // Windows implementation of version update functionality, used by the WebUI 40 // Windows implementation of version update functionality, used by the WebUI
31 // About/Help page. 41 // About/Help page.
32 class VersionUpdaterWin : public VersionUpdater { 42 class VersionUpdaterWin : public VersionUpdater, public UpdateCheckDelegate {
33 private: 43 public:
34 friend class VersionReader;
35 friend class VersionUpdater;
36
37 // Clients must use VersionUpdater::Create().
38 VersionUpdaterWin(); 44 VersionUpdaterWin();
39 ~VersionUpdaterWin() override; 45 ~VersionUpdaterWin() override;
40 46
41 // VersionUpdater implementation. 47 // VersionUpdater
Peter Kasting 2015/05/09 02:19:02 Tiny nit: I'd put a colon after these base class n
grt (UTC plus 2) 2015/05/12 20:21:52 Done.
42 void CheckForUpdate(const StatusCallback& callback) override; 48 void CheckForUpdate(const StatusCallback& callback) override;
43 void RelaunchBrowser() const override; 49 void RelaunchBrowser() const override;
44 50
45 // chrome::UpdateCheckCallback. 51 // UpdateCheckDelegate
46 void OnUpdateCheckResults(GoogleUpdateUpgradeResult result, 52 void OnUpdateCheckComplete(const base::string16& new_version) override;
47 GoogleUpdateErrorCode error_code, 53 void OnUpgradeProgress(int progress,
48 const base::string16& error_message, 54 const base::string16& new_version) override;
49 const base::string16& version); 55 void OnUpgradeComplete(const base::string16& new_version) override;
56 void OnError(GoogleUpdateErrorCode error_code,
57 const base::string16& error_message,
58 const base::string16& new_version) override;
50 59
51 // Update the UI to show the status of the upgrade. 60 private:
52 void UpdateStatus(GoogleUpdateUpgradeResult result,
53 GoogleUpdateErrorCode error_code,
54 const base::string16& error_message);
55
56 // Got the intalled version so the handling of the UPGRADE_ALREADY_UP_TO_DATE
57 // result case can now be completeb on the UI thread.
58 void GotInstalledVersion(const Version& version);
59
60 // Returns a window that can be used for elevation.
61 gfx::AcceleratedWidget GetElevationParent();
62
63 void BeginUpdateCheckOnFileThread(bool install_if_newer); 61 void BeginUpdateCheckOnFileThread(bool install_if_newer);
Peter Kasting 2015/05/09 02:19:02 Nit: Probably want to change the name of |install_
grt (UTC plus 2) 2015/05/12 20:21:52 Done.
64 62
65 // Callback used to communicate update status to the client. 63 // Callback used to communicate update status to the client.
66 StatusCallback callback_; 64 StatusCallback callback_;
67 65
68 // Used for callbacks. 66 // Used for callbacks.
69 base::WeakPtrFactory<VersionUpdaterWin> weak_factory_; 67 base::WeakPtrFactory<VersionUpdaterWin> weak_factory_;
70 68
71 DISALLOW_COPY_AND_ASSIGN(VersionUpdaterWin); 69 DISALLOW_COPY_AND_ASSIGN(VersionUpdaterWin);
72 }; 70 };
73 71
74 // This class is used to read the version on the FILE thread and then call back
75 // the version updater in the UI thread. Using a class helps better control
76 // the lifespan of the Version independently of the lifespan of the version
77 // updater, which may die while asynchonicity is happening, thus the usage of
78 // the WeakPtr, which can only be used from the thread that created it.
79 class VersionReader
80 : public base::RefCountedThreadSafe<VersionReader> {
81 public:
82 explicit VersionReader(
83 const base::WeakPtr<VersionUpdaterWin>& version_updater)
84 : version_updater_(version_updater) {
85 }
86
87 void GetVersionFromFileThread() {
88 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
89 InstallUtil::GetChromeVersion(dist, false, &installed_version_);
90 if (!installed_version_.IsValid()) {
91 // User-level Chrome is not installed, check system-level.
92 InstallUtil::GetChromeVersion(dist, true, &installed_version_);
93 }
94 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
95 &VersionReader::SetVersionInUIThread, this));
96 }
97
98 void SetVersionInUIThread() {
99 if (version_updater_.get() != NULL)
100 version_updater_->GotInstalledVersion(installed_version_);
101 }
102
103 private:
104 friend class base::RefCountedThreadSafe<VersionReader>;
105
106 ~VersionReader() {}
107
108 // The version updater that must be called back when we are done.
109 // We use a weak pointer in case the updater gets destroyed while waiting.
110 base::WeakPtr<VersionUpdaterWin> version_updater_;
111
112 // This is the version that gets read in the FILE thread and set on the
113 // the updater in the UI thread.
114 Version installed_version_;
115 };
116
117 VersionUpdaterWin::VersionUpdaterWin() 72 VersionUpdaterWin::VersionUpdaterWin()
118 : weak_factory_(this) { 73 : weak_factory_(this) {
119 } 74 }
120 75
121 VersionUpdaterWin::~VersionUpdaterWin() { 76 VersionUpdaterWin::~VersionUpdaterWin() {
122 } 77 }
123 78
124 void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) { 79 void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) {
125 callback_ = callback; 80 callback_ = callback;
126 81
127 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned 82 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
128 // off. So, in this case, the version updater must not mention 83 // off. So, in this case, the version updater must not mention
129 // on-demand updates. Silent updates (in the background) should still 84 // on-demand updates. Silent updates (in the background) should still
130 // work as before - enabling UAC or installing the latest service pack 85 // work as before - enabling UAC or installing the latest service pack
131 // for Vista is another option. 86 // for Vista is another option.
132 if (!(base::win::GetVersion() == base::win::VERSION_VISTA && 87 if (!(base::win::GetVersion() == base::win::VERSION_VISTA &&
133 (base::win::OSInfo::GetInstance()->service_pack().major == 0) && 88 (base::win::OSInfo::GetInstance()->service_pack().major == 0) &&
134 !base::win::UserAccountControlIsEnabled())) { 89 !base::win::UserAccountControlIsEnabled())) {
135 UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR, 90 callback_.Run(CHECKING, 0, base::string16());
136 base::string16()); 91 BeginUpdateCheckOnFileThread(false /* !install_if_newer */);
Peter Kasting 2015/05/09 02:19:02 Nit: I'm not in love with these comments when ther
grt (UTC plus 2) 2015/05/12 20:21:52 I've been asked by other reviewers to add these co
137 // Specify false to not upgrade yet.
138 BeginUpdateCheckOnFileThread(false);
139 } 92 }
140 } 93 }
141 94
142 void VersionUpdaterWin::RelaunchBrowser() const { 95 void VersionUpdaterWin::RelaunchBrowser() const {
143 chrome::AttemptRestart(); 96 chrome::AttemptRestart();
144 } 97 }
145 98
146 void VersionUpdaterWin::OnUpdateCheckResults( 99 void VersionUpdaterWin::OnUpdateCheckComplete(
147 GoogleUpdateUpgradeResult result, 100 const base::string16& new_version) {
148 GoogleUpdateErrorCode error_code, 101 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
149 const base::string16& error_message, 102 Status status = CHECKING;
150 const base::string16& version) { 103 if (new_version.empty()) {
151 UpdateStatus(result, error_code, error_message); 104 // Google Update says that no new version is available. Check to see if a
105 // restart is needed for it to take effect.
Peter Kasting 2015/05/09 02:19:02 Nit: Maybe "Check if we need to restart to pick up
grt (UTC plus 2) 2015/05/12 20:21:52 Done.
106 status = upgrade_util::IsRunningOldChrome() ? NEARLY_UPDATED : UPDATED;
107 } else {
108 // Notify the caller that the update is now beginning and initiate it.
109 status = UPDATING;
110 BeginUpdateCheckOnFileThread(true /* install_if_newer */);
111 }
112 callback_.Run(status, 0, base::string16());
152 } 113 }
153 114
154 void VersionUpdaterWin::UpdateStatus(GoogleUpdateUpgradeResult result, 115 void VersionUpdaterWin::OnUpgradeProgress(int progress,
155 GoogleUpdateErrorCode error_code, 116 const base::string16& new_version) {
156 const base::string16& error_message) { 117 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
157 // For Chromium builds it would show an error message. 118 callback_.Run(UPDATING, progress, base::string16());
158 // But it looks weird because in fact there is no error, 119 }
159 // just the update server is not available for non-official builds. 120
121 void VersionUpdaterWin::OnUpgradeComplete(const base::string16& new_version) {
122 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
123 callback_.Run(NEARLY_UPDATED, 0, base::string16());
124 }
125
126 void VersionUpdaterWin::OnError(GoogleUpdateErrorCode error_code,
127 const base::string16& error_message,
128 const base::string16& new_version) {
129 // Chromium builds will unconditionally get a
130 // CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY error since there is no supported
131 // integration with Google Update for Chromium. Ignore the error notification
132 // so that the spinner just spins rather than show an error message when there
Peter Kasting 2015/05/09 02:19:02 Nit: showing
grt (UTC plus 2) 2015/05/12 20:21:52 Done.
133 // is, in fact, no error.
Peter Kasting 2015/05/09 02:19:02 Is there a way to not spin but instead show the "n
grt (UTC plus 2) 2015/05/12 20:21:52 I make a chromium-branded build and found that I w
160 #if defined(GOOGLE_CHROME_BUILD) 134 #if defined(GOOGLE_CHROME_BUILD)
161 Status status = UPDATED; 135 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
162 base::string16 message; 136 base::string16 message;
163 137
164 switch (result) { 138 // Google Update provides a nice message for the policy case. Use this
Peter Kasting 2015/05/09 02:19:02 Nit: "usually provides"? (If it always provided t
grt (UTC plus 2) 2015/05/12 20:21:52 Just being defensive here. I don't believe Google
165 case UPGRADE_CHECK_STARTED: { 139 // generic error for the policy case only if no message from Google Update
166 status = CHECKING; 140 // is present.
167 break; 141 if (error_code != GOOGLE_UPDATE_DISABLED_BY_POLICY || error_message.empty())
168 } 142 message = l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code);
169 case UPGRADE_STARTED: {
170 status = UPDATING;
171 break;
172 }
173 case UPGRADE_IS_AVAILABLE: {
174 UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR, base::string16());
175 // Specify true to upgrade now.
176 BeginUpdateCheckOnFileThread(true);
177 return;
178 }
179 case UPGRADE_ALREADY_UP_TO_DATE: {
180 // Google Update reported that Chrome is up-to-date.
181 // To confirm the updated version is running, the reading
182 // must be done on the file thread. The rest of this case
183 // will be handled within GotInstalledVersion.
184 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
185 &VersionReader::GetVersionFromFileThread,
186 new VersionReader(weak_factory_.GetWeakPtr())));
187 return;
188 }
189 case UPGRADE_SUCCESSFUL: {
190 status = NEARLY_UPDATED;
191 break;
192 }
193 case UPGRADE_ERROR: {
194 status = FAILED;
195 if (error_code == GOOGLE_UPDATE_DISABLED_BY_POLICY) {
196 message =
197 l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY);
198 } else if (error_code == GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY) {
199 message =
200 l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY_MANUAL);
201 } else {
202 message =
203 l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code);
204 }
205 143
206 if (!error_message.empty()) { 144 if (!error_message.empty()) {
207 message += 145 message += l10n_util::GetStringFUTF16(
208 l10n_util::GetStringFUTF16(IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK, 146 IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK, error_message);
209 error_message);
210 }
211 break;
212 }
213 } 147 }
214 148 callback_.Run(FAILED, 0, message);
215 // TODO(mad): Get proper progress value instead of passing 0. 149 #endif
216 // http://crbug.com/136117
217 callback_.Run(status, 0, message);
218 #endif // defined(GOOGLE_CHROME_BUILD)
219 }
220
221 void VersionUpdaterWin::GotInstalledVersion(const Version& version) {
222 // This must be called on the UI thread so that callback_ can be called.
223 DCHECK_CURRENTLY_ON(BrowserThread::UI);
224
225 // Make sure that the latest version is running and if not,
226 // notify the user by setting the status to NEARLY_UPDATED.
227 //
228 // The extra version check is necessary on Windows because the application
229 // may be already up to date on disk though the running app is still
230 // out of date.
231 chrome::VersionInfo version_info;
232 Version running_version(version_info.Version());
233 callback_.Run((version.IsValid() && version.CompareTo(running_version) > 0)
234 ? NEARLY_UPDATED
235 : UPDATED,
236 0,
237 base::string16());
238 }
239
240 BOOL CALLBACK WindowEnumeration(HWND window, LPARAM param) {
241 if (IsWindowVisible(window)) {
242 HWND* returned_window = reinterpret_cast<HWND*>(param);
243 *returned_window = window;
244 return FALSE;
245 }
246 return TRUE;
247 }
248
249 gfx::AcceleratedWidget VersionUpdaterWin::GetElevationParent() {
250 // Look for a visible window belonging to the UI thread.
251 DCHECK_CURRENTLY_ON(BrowserThread::UI);
252 HWND window = NULL;
253 EnumThreadWindows(GetCurrentThreadId(),
254 WindowEnumeration,
255 reinterpret_cast<LPARAM>(&window));
256 return window;
257 } 150 }
258 151
259 void VersionUpdaterWin::BeginUpdateCheckOnFileThread(bool install_if_newer) { 152 void VersionUpdaterWin::BeginUpdateCheckOnFileThread(bool install_if_newer) {
260 scoped_refptr<base::TaskRunner> task_runner( 153 BeginUpdateCheck(content::BrowserThread::GetMessageLoopProxyForThread(
261 content::BrowserThread::GetMessageLoopProxyForThread( 154 content::BrowserThread::FILE),
262 content::BrowserThread::FILE)); 155 g_browser_process->GetApplicationLocale(), install_if_newer,
263 BeginUpdateCheck(task_runner, install_if_newer, GetElevationParent(), 156 FindVisibleWindow(), weak_factory_.GetWeakPtr());
264 base::Bind(&VersionUpdaterWin::OnUpdateCheckResults,
265 weak_factory_.GetWeakPtr()));
266 } 157 }
267 158
268 } // namespace 159 } // namespace
269 160
270 VersionUpdater* VersionUpdater::Create(content::BrowserContext* /* context */) { 161 VersionUpdater* VersionUpdater::Create(content::BrowserContext* /* context */) {
271 return new VersionUpdaterWin; 162 return new VersionUpdaterWin;
272 } 163 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698