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

Side by Side Diff: chrome/browser/google/google_update_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: better ui message when updates are disabled by policy 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 "chrome/browser/google/google_update_win.h" 5 #include "chrome/browser/google/google_update_win.h"
6 6
7 #include <atlbase.h> 7 #include <atlbase.h>
8 #include <atlcom.h> 8 #include <atlcom.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/sparse_histogram.h"
16 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/sequenced_task_runner_helpers.h"
18 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/strings/utf_string_conversions.h"
19 #include "base/task_runner.h" 22 #include "base/task_runner.h"
20 #include "base/thread_task_runner_handle.h" 23 #include "base/thread_task_runner_handle.h"
24 #include "base/time/time.h"
25 #include "base/win/scoped_bstr.h"
21 #include "base/win/windows_version.h" 26 #include "base/win/windows_version.h"
22 #include "chrome/grit/generated_resources.h" 27 #include "chrome/grit/generated_resources.h"
23 #include "chrome/installer/util/browser_distribution.h" 28 #include "chrome/installer/util/browser_distribution.h"
24 #include "chrome/installer/util/google_update_settings.h"
25 #include "chrome/installer/util/helper.h" 29 #include "chrome/installer/util/helper.h"
26 #include "chrome/installer/util/install_util.h" 30 #include "chrome/installer/util/install_util.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "ui/base/l10n/l10n_util.h" 31 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/win/atl_module.h" 32 #include "ui/base/win/atl_module.h"
30 33
31 namespace { 34 namespace {
32 35
33 OnDemandAppsClassFactory* g_google_update_factory = nullptr; 36 GoogleUpdate3ClassFactory* g_google_update_factory = nullptr;
37
38 // Constants from Google Update.
39 const HRESULT GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY = 0x80040813;
40 const HRESULT GOOPDATEINSTALL_E_INSTALLER_FAILED = 0x80040902;
34 41
35 // Check if the currently running instance can be updated by Google Update. 42 // Check if the currently running instance can be updated by Google Update.
36 // Returns GOOGLE_UPDATE_NO_ERROR only if the instance running is a Google 43 // Returns GOOGLE_UPDATE_NO_ERROR only if the instance running is a Google
37 // Chrome distribution installed in a standard location. 44 // Chrome distribution installed in a standard location.
38 GoogleUpdateErrorCode CanUpdateCurrentChrome( 45 GoogleUpdateErrorCode CanUpdateCurrentChrome(
39 const base::FilePath& chrome_exe_path, 46 const base::FilePath& chrome_exe_path,
40 bool system_level) { 47 bool system_level) {
41 #if !defined(GOOGLE_CHROME_BUILD) 48 #if !defined(GOOGLE_CHROME_BUILD)
42 return CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY; 49 return CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY;
43 #else 50 #else
44 DCHECK_NE(InstallUtil::IsPerUserInstall(chrome_exe_path), system_level); 51 DCHECK_NE(InstallUtil::IsPerUserInstall(chrome_exe_path), system_level);
45 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 52 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
46 base::FilePath user_exe_path = installer::GetChromeInstallPath(false, dist); 53 base::FilePath user_exe_path = installer::GetChromeInstallPath(false, dist);
47 base::FilePath machine_exe_path = installer::GetChromeInstallPath(true, dist); 54 base::FilePath machine_exe_path = installer::GetChromeInstallPath(true, dist);
48 if (!base::FilePath::CompareEqualIgnoreCase(chrome_exe_path.value(), 55 if (!base::FilePath::CompareEqualIgnoreCase(chrome_exe_path.value(),
49 user_exe_path.value()) && 56 user_exe_path.value()) &&
50 !base::FilePath::CompareEqualIgnoreCase(chrome_exe_path.value(), 57 !base::FilePath::CompareEqualIgnoreCase(chrome_exe_path.value(),
51 machine_exe_path.value())) { 58 machine_exe_path.value())) {
52 return CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY; 59 return CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY;
53 } 60 }
54 61
55 base::string16 app_guid = installer::GetAppGuidForUpdates(system_level);
56 DCHECK(!app_guid.empty());
57
58 GoogleUpdateSettings::UpdatePolicy update_policy =
59 GoogleUpdateSettings::GetAppUpdatePolicy(app_guid, NULL);
60
61 if (update_policy == GoogleUpdateSettings::UPDATES_DISABLED)
62 return GOOGLE_UPDATE_DISABLED_BY_POLICY;
63
64 if (update_policy == GoogleUpdateSettings::AUTO_UPDATES_ONLY)
65 return GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY;
66
67 return GOOGLE_UPDATE_NO_ERROR; 62 return GOOGLE_UPDATE_NO_ERROR;
68 #endif 63 #endif
69 } 64 }
70 65
71 // Creates an instance of a COM Local Server class using either plain vanilla 66 // Creates an instance of a COM Local Server class using either plain vanilla
72 // CoCreateInstance, or using the Elevation moniker if running on Vista. 67 // CoCreateInstance, or using the Elevation moniker if running on Vista.
73 // hwnd must refer to a foregound window in order to get the UAC prompt 68 // hwnd must refer to a foregound window in order to get the UAC prompt
74 // showing up in the foreground if running on Vista. It can also be NULL if 69 // showing up in the foreground if running on Vista. It can also be NULL if
75 // background UAC prompts are desired. 70 // background UAC prompts are desired.
76 HRESULT CoCreateInstanceAsAdmin(REFCLSID class_id, 71 HRESULT CoCreateInstanceAsAdmin(REFCLSID class_id,
(...skipping 23 matching lines...) Expand all
100 bind_opts.hwnd = hwnd; 95 bind_opts.hwnd = hwnd;
101 96
102 return CoGetObject(elevation_moniker_name.c_str(), &bind_opts, interface_id, 97 return CoGetObject(elevation_moniker_name.c_str(), &bind_opts, interface_id,
103 interface_ptr); 98 interface_ptr);
104 } 99 }
105 100
106 return CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, interface_id, 101 return CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, interface_id,
107 interface_ptr); 102 interface_ptr);
108 } 103 }
109 104
110 HRESULT CreateOnDemandAppsClass( 105 HRESULT CreateGoogleUpdate3Class(
111 bool system_level, 106 bool system_level,
112 bool install_if_newer, 107 bool install_if_newer,
113 gfx::AcceleratedWidget elevation_window, 108 gfx::AcceleratedWidget elevation_window,
114 base::win::ScopedComPtr<IGoogleUpdate>* on_demand) { 109 base::win::ScopedComPtr<IGoogleUpdate3>* google_update) {
115 if (g_google_update_factory) 110 if (g_google_update_factory)
116 return g_google_update_factory->Run(on_demand); 111 return g_google_update_factory->Run(google_update);
117 112
118 // For a user-level install, update checks and updates can both be done by a 113 // For a user-level install, update checks and updates can both be done by a
119 // normal user with the UserAppsClass. 114 // normal user with the UserClass.
120 if (!system_level) 115 if (!system_level)
121 return on_demand->CreateInstance(CLSID_OnDemandUserAppsClass); 116 return google_update->CreateInstance(CLSID_GoogleUpdate3UserClass);
122 117
123 // For a system-level install, update checks can be done by a normal user with 118 // For a system-level install, update checks can be done by a normal user with
124 // the MachineAppsClass. 119 // the ServiceClass.
125 if (!install_if_newer) 120 if (!install_if_newer)
126 return on_demand->CreateInstance(CLSID_OnDemandMachineAppsClass); 121 return google_update->CreateInstance(CLSID_GoogleUpdate3ServiceClass);
127 122
128 // For a system-level install, an update requires Admin privileges for writing 123 // For a system-level install, an update requires Admin privileges for writing
129 // to %ProgramFiles%. Elevate while instantiating the MachineAppsClass. 124 // to %ProgramFiles%. Elevate while instantiating the ServiceClass.
130 return CoCreateInstanceAsAdmin(CLSID_OnDemandMachineAppsClass, 125 return CoCreateInstanceAsAdmin(CLSID_GoogleUpdate3ServiceClass,
131 IID_IGoogleUpdate, elevation_window, 126 IID_IGoogleUpdate3, elevation_window,
132 on_demand->ReceiveVoid()); 127 google_update->ReceiveVoid());
133 } 128 }
134 129
135
136 // GoogleUpdateJobObserver -----------------------------------------------------
137
138 // The GoogleUpdateJobObserver COM class is responsible for receiving status
139 // reports from google Update. It keeps track of the progress as Google Update
140 // notifies this observer and runs a completion callback once Google Update
141 // reports that it is done.
142 class GoogleUpdateJobObserver : public CComObjectRootEx<CComSingleThreadModel>,
143 public IJobObserver {
144 public:
145 BEGIN_COM_MAP(GoogleUpdateJobObserver)
146 COM_INTERFACE_ENTRY(IJobObserver)
147 END_COM_MAP()
148
149 GoogleUpdateJobObserver();
150 virtual ~GoogleUpdateJobObserver();
151
152 // Sets the callback to be invoked when Google Update reports that the job is
153 // done.
154 void set_on_complete_callback(const base::Closure& on_complete_callback) {
155 on_complete_callback_ = on_complete_callback;
156 }
157
158 // Returns the results of the update operation.
159 GoogleUpdateUpgradeResult result() const {
160 // Intermediary steps should never be reported to the client.
161 DCHECK_NE(UPGRADE_STARTED, result_);
162 DCHECK_NE(UPGRADE_CHECK_STARTED, result_);
163 return result_;
164 }
165
166 // Returns which version Google Update found on the server (if a more
167 // recent version was found). Otherwise, this will be blank.
168 base::string16 new_version() const { return new_version_; }
169
170 // Returns the Google Update supplied error string that describes the error
171 // that occurred during the update check/upgrade.
172 base::string16 error_message() const { return error_message_; }
173
174 private:
175 // IJobObserver:
176 STDMETHOD(OnShow)() override;
177 STDMETHOD(OnCheckingForUpdate)() override;
178 STDMETHOD(OnUpdateAvailable)(const TCHAR* version_string) override;
179 STDMETHOD(OnWaitingToDownload)() override;
180 STDMETHOD(OnDownloading)(int time_remaining_ms, int pos) override;
181 STDMETHOD(OnWaitingToInstall)() override;
182 STDMETHOD(OnInstalling)() override;
183 STDMETHOD(OnPause)() override;
184 STDMETHOD(OnComplete)(LegacyCompletionCodes code, const TCHAR* text) override;
185 STDMETHOD(SetEventSink)(IProgressWndEvents* event_sink) override;
186
187 // The task runner associated with the thread in which the job runs.
188 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
189
190 // A callback to be run to complete processing;
191 base::Closure on_complete_callback_;
192
193 // The status/result of the Google Update operation.
194 GoogleUpdateUpgradeResult result_;
195
196 // The version string Google Update found.
197 base::string16 new_version_;
198
199 // An error message, if any.
200 base::string16 error_message_;
201
202 // Allows us control the upgrade process to a small degree. After OnComplete
203 // has been called, this object can not be used.
204 base::win::ScopedComPtr<IProgressWndEvents> event_sink_;
205
206 DISALLOW_COPY_AND_ASSIGN(GoogleUpdateJobObserver);
207 };
208
209 GoogleUpdateJobObserver::GoogleUpdateJobObserver()
210 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
211 result_(UPGRADE_ERROR) {
212 }
213
214 GoogleUpdateJobObserver::~GoogleUpdateJobObserver() {
215 }
216
217 STDMETHODIMP GoogleUpdateJobObserver::OnShow() {
218 return S_OK;
219 }
220
221 STDMETHODIMP GoogleUpdateJobObserver::OnCheckingForUpdate() {
222 result_ = UPGRADE_CHECK_STARTED;
223 return S_OK;
224 }
225
226 STDMETHODIMP GoogleUpdateJobObserver::OnUpdateAvailable(
227 const TCHAR* version_string) {
228 result_ = UPGRADE_IS_AVAILABLE;
229 new_version_ = version_string;
230 return S_OK;
231 }
232
233 STDMETHODIMP GoogleUpdateJobObserver::OnWaitingToDownload() {
234 return S_OK;
235 }
236
237 STDMETHODIMP GoogleUpdateJobObserver::OnDownloading(int time_remaining_ms,
238 int pos) {
239 return S_OK;
240 }
241
242 STDMETHODIMP GoogleUpdateJobObserver::OnWaitingToInstall() {
243 return S_OK;
244 }
245
246 STDMETHODIMP GoogleUpdateJobObserver::OnInstalling() {
247 result_ = UPGRADE_STARTED;
248 return S_OK;
249 }
250
251 STDMETHODIMP GoogleUpdateJobObserver::OnPause() {
252 return S_OK;
253 }
254
255 STDMETHODIMP GoogleUpdateJobObserver::OnComplete(LegacyCompletionCodes code,
256 const TCHAR* text) {
257 if (code == COMPLETION_CODE_ERROR) {
258 error_message_ = text;
259 result_ = UPGRADE_ERROR;
260 } else {
261 // Everything that isn't an error is some form of success. Chrome doesn't
262 // support any of the fancy codes (e.g., COMPLETION_CODE_REBOOT), but they
263 // shouldn't be generated anyway.
264 LOG_IF(DFATAL, (code != COMPLETION_CODE_SUCCESS &&
265 code != COMPLETION_CODE_SUCCESS_CLOSE_UI))
266 << "Unexpected LegacyCompletionCode from IGoogleUpdate: " << code;
267 if (result_ == UPGRADE_STARTED)
268 result_ = UPGRADE_SUCCESSFUL;
269 else if (result_ == UPGRADE_CHECK_STARTED)
270 result_ = UPGRADE_ALREADY_UP_TO_DATE;
271 }
272
273 event_sink_ = NULL;
274
275 task_runner_->PostTask(FROM_HERE, on_complete_callback_);
276 return S_OK;
277 }
278
279 STDMETHODIMP GoogleUpdateJobObserver::SetEventSink(
280 IProgressWndEvents* event_sink) {
281 event_sink_ = event_sink;
282 return S_OK;
283 }
284
285
286 // UpdateCheckDriver ----------------------------------------------------------- 130 // UpdateCheckDriver -----------------------------------------------------------
287 131
288 // A driver that is created and destroyed on the caller's thread and drives 132 // A driver that is created and destroyed on the caller's thread and drives
289 // Google Update on another. 133 // Google Update on another.
290 class UpdateCheckDriver { 134 class UpdateCheckDriver {
291 public: 135 public:
292 // Runs an update check on |task_runner|, invoking |callback| on the caller's 136 // Runs an update check on |task_runner|, invoking |callback| on the caller's
293 // thread upon completion. |task_runner| must run a TYPE_UI message loop if 137 // thread upon completion. |task_runner| must run a TYPE_UI message loop if
294 // the default IGoogleUpdate on-demand COM class is used. 138 // the default IGoogleUpdate on-demand COM class is used.
295 static void RunUpdateCheck(const scoped_refptr<base::TaskRunner>& task_runner, 139 static void RunUpdateCheck(const scoped_refptr<base::TaskRunner>& task_runner,
140 const std::string& locale,
296 bool install_if_newer, 141 bool install_if_newer,
297 gfx::AcceleratedWidget elevation_window, 142 gfx::AcceleratedWidget elevation_window,
298 const UpdateCheckCallback& callback); 143 const UpdateCheckCallback& callback);
299 144
300 private: 145 private:
301 friend class base::DeleteHelper<UpdateCheckDriver>; 146 friend class base::DeleteHelper<UpdateCheckDriver>;
302 147
303 explicit UpdateCheckDriver(const UpdateCheckCallback& callback); 148 UpdateCheckDriver(const scoped_refptr<base::TaskRunner>& task_runner,
149 const std::string& locale,
150 bool install_if_newer,
151 gfx::AcceleratedWidget elevation_window,
152 const UpdateCheckCallback& callback);
304 153
305 // Runs the caller's update check callback with the results of the operation. 154 // Runs the caller's update check callback with the results of the operation.
306 ~UpdateCheckDriver(); 155 ~UpdateCheckDriver();
307 156
308 // Starts an update check. 157 // Starts an update check.
309 void BeginUpdateCheck(bool install_if_newer, 158 void BeginUpdateCheck();
310 gfx::AcceleratedWidget elevation_window);
311 159
312 // Helper function for starting an update check. Returns true if the check was 160 // Helper function for starting an update check. Returns true if the check was
313 // properly started, in which case CompleteUpdateCheck will be invoked upon 161 // properly started.
314 // completion to return results to the caller on its own thread. 162 bool BeginUpdateCheckInternal();
315 bool BeginUpdateCheckInternal(bool install_if_newer,
316 gfx::AcceleratedWidget elevation_window);
317
318 // Invoked when results are in from Google Update.
319 void CompleteUpdateCheck();
320 163
321 // Prepares |results| to return the upgrade error indicated by |error_code| 164 // Prepares |results| to return the upgrade error indicated by |error_code|
Peter Kasting 2015/05/07 22:37:29 What is |results|? Does this mean |result_|?
grt (UTC plus 2) 2015/05/08 18:51:50 Comment revised.
322 // and |hr|. The string " -- system level" is included in the generated error 165 // and |hr|. The string " -- system level" is included in the generated error
323 // message when |system_level| is true. 166 // message when appropriate.
324 void OnUpgradeError(GoogleUpdateErrorCode error_code, 167 void OnUpgradeError(GoogleUpdateErrorCode error_code,
325 HRESULT hr, 168 HRESULT hr,
Peter Kasting 2015/05/07 22:37:28 Nit: Some functions use |hr| and some |hresult| --
grt (UTC plus 2) 2015/05/08 18:51:50 Done.
326 bool system_level); 169 int installer_exit_code,
170 const base::string16& error_string);
171
172 // Returns true if |current_state| and |state_value| can be obtained from the
173 // ongoing update check. Otherwise, populates |hresult| with the reason they
174 // could not be obtained.
Peter Kasting 2015/05/07 22:37:29 Is it possible to simply return the HRESULT, using
grt (UTC plus 2) 2015/05/08 18:51:49 Yes, although I find that the logic in PollGoogleU
175 bool GetCurrentState(base::win::ScopedComPtr<ICurrentState>* current_state,
176 CurrentState* state_value,
177 HRESULT* hresult);
178
179 // Returns true if |current_state| and |state_value| constitute an error state
180 // for the ongoing update check, in which case |error_code| is populated with
181 // one of GOOGLE_UPDATE_ERROR_UPDATING, GOOGLE_UPDATE_DISABLED_BY_POLICY, or
182 // GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR. |hresult| is populated with
183 // the most relevant HRESULT (which may be a value from Google Update; see
184 // https://code.google.com/p/omaha/source/browse/trunk/base/error.h). In case
185 // Chrome's installer failed during execution, |installer_exit_code| may be
186 // populated with its process exit code (see enum installer::InstallStatus in
187 // chrome/installer/util/util_constants.h); otherwise, it will be -1.
188 // |error_string| will be populated with a completion message if one is
189 // provided by Google Update.
190 bool IsErrorState(const base::win::ScopedComPtr<ICurrentState>& current_state,
191 CurrentState state_value,
192 GoogleUpdateErrorCode* error_code,
193 HRESULT* hresult,
194 int* installer_exit_code,
195 base::string16* error_string);
196
197 // Returns true if |current_state| and |state_value| constitute a final state
198 // for the ongoing update check, in which case |upgrade_result| is populated
199 // with one of UPGRADE_ALREADY_UP_TO_DATE or UPGRADE_IS_AVAILABLE (in case a
200 // pure check is being performed rather than an update) or UPGRADE_SUCCESSFUL
201 // (in case an update is being performed). For the UPGRADE_IS_AVAILABLE case,
202 // |new_version| will be populated with the available version, if provided by
203 // Google Update.
204 bool IsFinalState(const base::win::ScopedComPtr<ICurrentState>& current_state,
205 CurrentState state_value,
206 GoogleUpdateUpgradeResult* upgrade_result,
207 base::string16* new_version);
208
209 // Returns true if |current_state| and |state_value| constitute an
210 // intermediate state for the ongoing update check, in which case
211 // |upgrade_result| is populated with UPGRADE_STARTED (in case an update is
212 // being performed) or UPGRADE_CHECK_STARTED (in case a pure check is being
213 // performed rather than an update). |new_version| will be populated with the
214 // version to be installed if it is provided by Google Update for the current
215 // state. |progress| will be populated with a number between 0.0 and 1.0
216 // according to how far Google Update has progressed in the download and
217 // install process.
218 bool IsIntermediateState(
Peter Kasting 2015/05/07 22:37:28 Nit: Somehow conceptually it seems like this shoul
grt (UTC plus 2) 2015/05/08 18:51:49 I have them in this order to match the order in wh
219 const base::win::ScopedComPtr<ICurrentState>& current_state,
220 CurrentState state_value,
221 GoogleUpdateUpgradeResult* upgrade_result,
222 base::string16* new_version,
223 double* progress);
224
225 // Pools Google Update to determine the state of the ongoing check or
Peter Kasting 2015/05/07 22:37:28 Nit: Polls
grt (UTC plus 2) 2015/05/08 18:51:49 Doh!
226 // update. If the process has reached a terminal state, this instance will be
227 // deleted and the caller will be notified of the final status. Otherwise, the
228 // caller will be notified of the intermediate state (iff it differs from a
229 // previuos notification) and another future poll will be scheduled.
Peter Kasting 2015/05/07 22:37:29 Nit: previous
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
230 void PollGoogleUpdate();
231
232 // The task runner on which the update checks runs.
233 scoped_refptr<base::TaskRunner> task_runner_;
327 234
328 // The caller's task runner, on which |result_callback_| will be run. 235 // The caller's task runner, on which |result_callback_| will be run.
329 scoped_refptr<base::SingleThreadTaskRunner> result_runner_; 236 scoped_refptr<base::SingleThreadTaskRunner> result_runner_;
330 237
238 // The UI locale.
239 std::string locale_;
240
241 // False to only check for an update; true to also install one if available.
242 bool install_if_newer_;
Peter Kasting 2015/05/07 22:37:28 Nit: install_update_if_possible_ or install_availa
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
243
244 // A parent window in case any UX is required (e.g., an elevation prompt).
245 gfx::AcceleratedWidget elevation_window_;
246
331 // The caller's callback to be run when the update check is compelte. 247 // The caller's callback to be run when the update check is compelte.
332 UpdateCheckCallback result_callback_; 248 UpdateCheckCallback result_callback_;
333 249
334 // The results of the update check. 250 // True if operating at system-level.
Peter Kasting 2015/05/07 22:37:28 Nit: "...instead of user-level" (I assume)
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
251 bool system_level_;
252
253 // The on-demand updater that is doing the work.
254 base::win::ScopedComPtr<IGoogleUpdate3> google_update_;
255
256 // An app bundle containing the application being updated.
257 base::win::ScopedComPtr<IAppBundle> app_bundle_;
258
259 // The application being updated (Chrome, Chrome Binaries, or Chrome SxS).
260 base::win::ScopedComPtr<IApp> app_;
261
262 // The intermediate status of an ongoing operation that was most recently
263 // reported to the caller.
264 GoogleUpdateUpgradeResult last_result_;
265 double last_progress_;
266
267 // The results of the update check to be logged via UMA and/or reported to the
268 // caller.
335 GoogleUpdateUpgradeResult result_; 269 GoogleUpdateUpgradeResult result_;
336 GoogleUpdateErrorCode error_code_; 270 GoogleUpdateErrorCode error_code_;
337 base::string16 error_message_; 271 base::string16 error_message_;
338 base::string16 version_; 272 base::string16 new_version_;
339 HRESULT hresult_; 273 HRESULT hresult_;
340 274 int installer_exit_code_;
341 // A direct pointer to the job observer by which the driver is notified of
342 // interesting events from Google Update.
343 CComObject<GoogleUpdateJobObserver>* job_observer_;
344
345 // A scoped pointer to |job_observer_| that holds a reference to it, keeping
346 // it alive.
347 base::win::ScopedComPtr<IJobObserver> job_holder_;
348
349 // The on-demand updater that is doing the work.
350 base::win::ScopedComPtr<IGoogleUpdate> on_demand_;
351 275
352 DISALLOW_COPY_AND_ASSIGN(UpdateCheckDriver); 276 DISALLOW_COPY_AND_ASSIGN(UpdateCheckDriver);
353 }; 277 };
354 278
355 // static 279 // static
356 void UpdateCheckDriver::RunUpdateCheck( 280 void UpdateCheckDriver::RunUpdateCheck(
357 const scoped_refptr<base::TaskRunner>& task_runner, 281 const scoped_refptr<base::TaskRunner>& task_runner,
282 const std::string& locale,
358 bool install_if_newer, 283 bool install_if_newer,
359 gfx::AcceleratedWidget elevation_window, 284 gfx::AcceleratedWidget elevation_window,
360 const UpdateCheckCallback& callback) { 285 const UpdateCheckCallback& callback) {
361 // The driver is owned by itself, and will self-destruct when its work is 286 // The driver is owned by itself, and will self-destruct when its work is
362 // done. 287 // done.
363 UpdateCheckDriver* driver = new UpdateCheckDriver(callback); 288 UpdateCheckDriver* driver = new UpdateCheckDriver(
364 task_runner->PostTask( 289 task_runner, locale, install_if_newer, elevation_window, callback);
365 FROM_HERE, 290 task_runner->PostTask(FROM_HERE,
366 base::Bind(&UpdateCheckDriver::BeginUpdateCheck, base::Unretained(driver), 291 base::Bind(&UpdateCheckDriver::BeginUpdateCheck,
367 install_if_newer, elevation_window)); 292 base::Unretained(driver)));
368 } 293 }
369 294
370 // Runs on the caller's thread. 295 // Runs on the caller's thread.
371 UpdateCheckDriver::UpdateCheckDriver(const UpdateCheckCallback& callback) 296 UpdateCheckDriver::UpdateCheckDriver(
372 : result_runner_(base::ThreadTaskRunnerHandle::Get()), 297 const scoped_refptr<base::TaskRunner>& task_runner,
298 const std::string& locale,
299 bool install_if_newer,
300 gfx::AcceleratedWidget elevation_window,
301 const UpdateCheckCallback& callback)
302 : task_runner_(task_runner),
303 result_runner_(base::ThreadTaskRunnerHandle::Get()),
304 locale_(locale),
305 install_if_newer_(install_if_newer),
306 elevation_window_(elevation_window),
373 result_callback_(callback), 307 result_callback_(callback),
308 system_level_(false),
309 last_result_(UPGRADE_ERROR),
310 last_progress_(0.0),
374 result_(UPGRADE_ERROR), 311 result_(UPGRADE_ERROR),
375 error_code_(GOOGLE_UPDATE_NO_ERROR), 312 error_code_(GOOGLE_UPDATE_NO_ERROR),
376 hresult_(S_OK), 313 hresult_(S_OK),
377 job_observer_(nullptr) { 314 installer_exit_code_(-1) {
378 } 315 }
379 316
380 UpdateCheckDriver::~UpdateCheckDriver() { 317 UpdateCheckDriver::~UpdateCheckDriver() {
381 DCHECK(result_runner_->BelongsToCurrentThread()); 318 DCHECK(result_runner_->BelongsToCurrentThread());
382 // If there is an error, then error_code must not be blank, and vice versa. 319 // If there is an error, then error_code must not be blank, and vice versa.
383 DCHECK_NE(result_ == UPGRADE_ERROR, error_code_ == GOOGLE_UPDATE_NO_ERROR); 320 DCHECK_NE(result_ == UPGRADE_ERROR, error_code_ == GOOGLE_UPDATE_NO_ERROR);
384 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpgradeResult", result_, 321 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpgradeResult", result_,
385 NUM_UPGRADE_RESULTS); 322 NUM_UPGRADE_RESULTS);
386 if (result_ == UPGRADE_ERROR) { 323 if (result_ == UPGRADE_ERROR) {
387 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpdateErrorCode", error_code_, 324 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpdateErrorCode", error_code_,
388 NUM_ERROR_CODES); 325 NUM_ERROR_CODES);
389 if (hresult_ != S_OK) 326 if (FAILED(hresult_))
390 UMA_HISTOGRAM_SPARSE_SLOWLY("GoogleUpdate.ErrorHresult", hresult_); 327 UMA_HISTOGRAM_SPARSE_SLOWLY("GoogleUpdate.ErrorHresult", hresult_);
328 if (installer_exit_code_ != -1) {
329 UMA_HISTOGRAM_SPARSE_SLOWLY("GoogleUpdate.InstallerExitCode",
330 installer_exit_code_);
331 }
391 } 332 }
392 result_callback_.Run(result_, error_code_, error_message_, version_); 333 result_callback_.Run(result_, 0.0, error_code_, error_message_, new_version_);
393 } 334 }
394 335
395 void UpdateCheckDriver::BeginUpdateCheck( 336 void UpdateCheckDriver::BeginUpdateCheck() {
396 bool install_if_newer,
397 gfx::AcceleratedWidget elevation_window) {
398 // Return results immediately if the driver is not waiting for Google Update. 337 // Return results immediately if the driver is not waiting for Google Update.
399 if (!BeginUpdateCheckInternal(install_if_newer, elevation_window)) 338 if (!BeginUpdateCheckInternal())
400 result_runner_->DeleteSoon(FROM_HERE, this); 339 result_runner_->DeleteSoon(FROM_HERE, this);
401 } 340 }
402 341
403 bool UpdateCheckDriver::BeginUpdateCheckInternal( 342 bool UpdateCheckDriver::BeginUpdateCheckInternal() {
404 bool install_if_newer,
405 gfx::AcceleratedWidget elevation_window) {
406 base::FilePath chrome_exe; 343 base::FilePath chrome_exe;
407 if (!PathService::Get(base::DIR_EXE, &chrome_exe)) 344 if (!PathService::Get(base::DIR_EXE, &chrome_exe))
408 NOTREACHED(); 345 NOTREACHED();
409 346
410 const bool system_level = !InstallUtil::IsPerUserInstall(chrome_exe); 347 system_level_ = !InstallUtil::IsPerUserInstall(chrome_exe);
Peter Kasting 2015/05/07 22:37:29 Nit: Maybe we should make the bool member be |per_
grt (UTC plus 2) 2015/05/08 18:51:50 I agree that it seems backward, but system_level i
Peter Kasting 2015/05/09 02:19:01 OK; I would still suggest "system_level_install_"
grt (UTC plus 2) 2015/05/12 20:21:51 Done.
411 348
412 // The failures handled here are: 349 // CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY is handled here.
Peter Kasting 2015/05/07 22:37:28 Nit: This maybe should go inside the conditional
grt (UTC plus 2) 2015/05/08 18:51:50 It turns out that this comment was a lie. I've rea
413 // CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY, 350 error_code_ = CanUpdateCurrentChrome(chrome_exe, system_level_);
414 // GOOGLE_UPDATE_DISABLED_BY_POLICY, and
415 // GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY.
416 error_code_ = CanUpdateCurrentChrome(chrome_exe, system_level);
417 if (error_code_ != GOOGLE_UPDATE_NO_ERROR) { 351 if (error_code_ != GOOGLE_UPDATE_NO_ERROR) {
418 // These failures are handled in the UX with custom messages. 352 // This failure is handled in the UX with a custom message.
419 result_ = UPGRADE_ERROR; 353 result_ = UPGRADE_ERROR;
420 return false; 354 return false;
421 } 355 }
422 356
423 // Make sure ATL is initialized in this module. 357 // Make sure ATL is initialized in this module.
424 ui::win::CreateATLModuleIfNeeded(); 358 ui::win::CreateATLModuleIfNeeded();
425 359
426 HRESULT hr = 360 // A failure to create the main update class is reported with this code:
427 CComObject<GoogleUpdateJobObserver>::CreateInstance(&job_observer_); 361 GoogleUpdateErrorCode error_code = GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND;
428 if (hr != S_OK) { 362 HRESULT hr = S_OK;
429 // Most of the error messages come straight from Google Update. This one is 363 do {
Peter Kasting 2015/05/07 22:37:28 A do { } while(false) construction here just so yo
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
430 // deemed worthy enough to also warrant its own error. 364 hr = CreateGoogleUpdate3Class(system_level_, install_if_newer_,
431 OnUpgradeError(GOOGLE_UPDATE_JOB_SERVER_CREATION_FAILED, hr, false); 365 elevation_window_, &google_update_);
366 if (FAILED(hr)) {
367 DLOG(ERROR) << "failed to create GoogleUpdate3 class " << std::hex << hr;
Peter Kasting 2015/05/07 22:37:28 Logging is uncommon in Chromium code and the old c
grt (UTC plus 2) 2015/05/08 18:51:50 All of these are DLOG, so there's no bloat. That s
368 break;
369 }
370
371 // The class was created, so all subsequent errors are reported as:
372 error_code = GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR;
373 base::string16 app_guid = installer::GetAppGuidForUpdates(system_level_);
374 DCHECK(!app_guid.empty());
375
376 base::win::ScopedComPtr<IDispatch> dispatch;
377 hr = google_update_->createAppBundle(dispatch.Receive());
378 if (FAILED(hr))
379 break;
380 hr = dispatch.QueryInterface(app_bundle_.Receive());
381 if (FAILED(hr))
382 break;
383 dispatch.Release();
Peter Kasting 2015/05/07 22:37:28 Nit: I tend to think it's clearer to use something
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
384
385 if (!locale_.empty()) {
386 hr = app_bundle_->put_displayLanguage(
387 base::win::ScopedBstr(base::UTF8ToUTF16(locale_).c_str()));
388 DLOG_IF(ERROR, FAILED(hr)) << std::hex << hr;
389 }
Peter Kasting 2015/05/07 22:37:29 Nit: Maybe blank line below this? Not sure, but i
grt (UTC plus 2) 2015/05/08 18:51:50 Done.
390 // This doesn't work. Perhaps it isn't needed since elevation is done by
Peter Kasting 2015/05/07 22:37:29 What does "doesn't work" mean? Also, how is this
grt (UTC plus 2) 2015/05/08 18:51:49 Causes Google Update to crash. :-(
391 // Chrome.
392 // hr = app_bundle_->put_parentHWND(
393 // reinterpret_cast<ULONG_PTR>(elevation_window_));
394 // DLOG_IF(ERROR, FAILED(hr)) << std::hex << hr;
395 hr = app_bundle_->initialize();
396 if (FAILED(hr)) {
397 DLOG(ERROR) << "initialize failed " << std::hex << hr;
398 break;
399 }
400 hr = app_bundle_->createInstalledApp(
401 base::win::ScopedBstr(app_guid.c_str()), dispatch.Receive());
402 if (FAILED(hr)) {
403 DLOG(ERROR) << "createInstalledApp failed " << std::hex << hr;
404 break;
405 }
406 hr = dispatch.QueryInterface(app_.Receive());
407 if (FAILED(hr))
408 break;
409 hr = app_bundle_->checkForUpdate();
410 DLOG_IF(ERROR, FAILED(hr)) << "checkForUpdate failed " << std::hex << hr;
411 } while (false);
412
413 if (FAILED(hr)) {
414 OnUpgradeError(error_code, hr, -1, base::string16());
432 return false; 415 return false;
433 } 416 }
434 // Hold a reference on the observer for the lifetime of the driver. 417
435 job_holder_ = job_observer_; 418 task_runner_->PostTask(
436 419 FROM_HERE,
437 job_observer_->set_on_complete_callback(base::Bind( 420 base::Bind(&UpdateCheckDriver::PollGoogleUpdate, base::Unretained(this)));
438 &UpdateCheckDriver::CompleteUpdateCheck, base::Unretained(this))); 421
439 422 return true;
440 hr = CreateOnDemandAppsClass(system_level, install_if_newer, elevation_window, 423 }
441 &on_demand_); 424
442 if (hr != S_OK) { 425 bool UpdateCheckDriver::GetCurrentState(
443 OnUpgradeError(GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND, hr, system_level); 426 base::win::ScopedComPtr<ICurrentState>* current_state,
427 CurrentState* state_value,
428 HRESULT* hresult) {
429 base::win::ScopedComPtr<IDispatch> dispatch;
430 *hresult = app_->get_currentState(dispatch.Receive());
431 if (FAILED(*hresult)) {
432 DLOG(ERROR) << "failed getting currentState " << std::hex << *hresult;
444 return false; 433 return false;
445 } 434 }
446 435 *hresult = dispatch.QueryInterface(current_state->Receive());
447 base::string16 app_guid = installer::GetAppGuidForUpdates(system_level); 436 if (FAILED(*hresult)) {
448 DCHECK(!app_guid.empty()); 437 DLOG(ERROR) << "failed getting ICurrentState " << std::hex << *hresult;
449
450 if (install_if_newer)
451 hr = on_demand_->Update(app_guid.c_str(), job_observer_);
452 else
453 hr = on_demand_->CheckForUpdate(app_guid.c_str(), job_observer_);
454
455 if (hr != S_OK) {
456 OnUpgradeError(GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR, hr,
457 system_level);
458 return false; 438 return false;
459 } 439 }
440 dispatch.Release();
Peter Kasting 2015/05/07 22:37:28 Why is this call needed?
grt (UTC plus 2) 2015/05/08 18:51:49 For consistency with the previous uses of IDispatc
Peter Kasting 2015/05/09 02:19:01 I guess the question is more, either a Release() o
grt (UTC plus 2) 2015/05/12 20:21:51 Done.
441 LONG value = 0;
442 *hresult = (*current_state)->get_stateValue(&value);
443 if (FAILED(*hresult)) {
444 DLOG(ERROR) << "failed getting state value " << std::hex << *hresult;
445 return false;
446 }
447 *state_value = static_cast<CurrentState>(value);
460 return true; 448 return true;
461 } 449 }
462 450
463 void UpdateCheckDriver::CompleteUpdateCheck() { 451 bool UpdateCheckDriver::IsErrorState(
464 result_ = job_observer_->result(); 452 const base::win::ScopedComPtr<ICurrentState>& current_state,
465 if (result_ == UPGRADE_ERROR) { 453 CurrentState state_value,
466 error_code_ = GOOGLE_UPDATE_ERROR_UPDATING; 454 GoogleUpdateErrorCode* error_code,
467 error_message_ = job_observer_->error_message(); 455 HRESULT* hresult,
468 } else { 456 int* installer_exit_code,
469 version_ = job_observer_->new_version(); 457 base::string16* error_string) {
458 if (state_value == STATE_ERROR) {
459 // In general, errors reported by Google Update fall under this category
460 // (see special case below).
461 *error_code = GOOGLE_UPDATE_ERROR_UPDATING;
462
463 // In general, the exit code of Chrome's installer is unknown (see special
464 // case below).
465 *installer_exit_code = -1;
466
467 // Report the error_code provided by Google Update if possible, or the
468 // reason it wasn't possible otherwise.
469 LONG long_value = 0;
470 *hresult = current_state->get_errorCode(&long_value);
471 if (SUCCEEDED(*hresult))
472 *hresult = long_value;
473
474 // Special cases:
475 // - Use a custom error code if Google Update repoted that the update was
476 // disabled by a Group Policy setting.
477 // - Extract the exit code of Chrome's installer if Google Update repoted
478 // that the update failed becuase of a failure in the installer.
Peter Kasting 2015/05/07 22:37:28 Nit: because
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
479 LONG code = 0;
480 if (*hresult == GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY) {
481 *error_code = GOOGLE_UPDATE_DISABLED_BY_POLICY;
482 } else if (*hresult == GOOPDATEINSTALL_E_INSTALLER_FAILED &&
483 SUCCEEDED(current_state->get_installerResultCode(&code))) {
484 *installer_exit_code = code;
485 }
486
487 base::win::ScopedBstr message;
488 if (SUCCEEDED(current_state->get_completionMessage(message.Receive())))
489 error_string->assign(message, message.Length());
490
491 return true;
492 }
493 if (state_value == STATE_UPDATE_AVAILABLE && install_if_newer_) {
494 *hresult = app_bundle_->install();
495 if (FAILED(*hresult)) {
496 DLOG(ERROR) << "install() failed " << std::hex << *hresult;
497 // Report a failure to start the install as a general error while trying
498 // to interact with Google Update.
499 *error_code = GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR;
500 *installer_exit_code = -1;
501 return true;
502 }
503 // Return false for handling in IsIntermediateState.
504 }
505 return false;
506 }
507
508 bool UpdateCheckDriver::IsFinalState(
509 const base::win::ScopedComPtr<ICurrentState>& current_state,
510 CurrentState state_value,
511 GoogleUpdateUpgradeResult* upgrade_result,
512 base::string16* new_version) {
513 if (state_value == STATE_UPDATE_AVAILABLE && !install_if_newer_) {
514 base::win::ScopedBstr version;
515 *upgrade_result = UPGRADE_IS_AVAILABLE;
516 if (SUCCEEDED(current_state->get_availableVersion(version.Receive())))
517 new_version->assign(version, version.Length());
518 return true;
519 } else if (state_value == STATE_INSTALL_COMPLETE) {
Peter Kasting 2015/05/07 22:37:28 Nit: No else after return (2 places)
grt (UTC plus 2) 2015/05/08 18:51:50 Done.
520 DCHECK(install_if_newer_);
521 *upgrade_result = UPGRADE_SUCCESSFUL;
522 return true;
523 } else if (state_value == STATE_NO_UPDATE) {
524 *upgrade_result = UPGRADE_ALREADY_UP_TO_DATE;
525 return true;
526 }
527 return false;
528 }
529
530 bool UpdateCheckDriver::IsIntermediateState(
531 const base::win::ScopedComPtr<ICurrentState>& current_state,
532 CurrentState state_value,
533 GoogleUpdateUpgradeResult* upgrade_result,
534 base::string16* new_version,
535 double* progress) {
536 // ERROR will have been handled in IsErrorState. UPDATE_AVAILABLE, and
537 // NO_UPDATE will have been handled in IsFinalState if not doing an install,
538 // as will STATE_INSTALL_COMPLETE when doing an install. All other states
539 // following UPDATE_AVAILABLE will only happen when an install is to be done.
540 DCHECK(state_value < STATE_UPDATE_AVAILABLE || install_if_newer_);
541 *upgrade_result = install_if_newer_ ? UPGRADE_STARTED : UPGRADE_CHECK_STARTED;
542 *progress = 0.0;
543
544 switch (state_value) {
545 case STATE_INIT:
546 case STATE_WAITING_TO_CHECK_FOR_UPDATE:
547 case STATE_CHECKING_FOR_UPDATE:
548 break;
549
550 case STATE_UPDATE_AVAILABLE: {
551 base::win::ScopedBstr version;
552 if (SUCCEEDED(current_state->get_availableVersion(version.Receive())))
553 new_version->assign(version, version.Length());
554 break;
555 }
556
557 case STATE_WAITING_TO_DOWNLOAD:
558 case STATE_RETRYING_DOWNLOAD:
559 break;
560
561 case STATE_DOWNLOADING: {
562 ULONG bytes_downloaded = 0;
563 ULONG total_bytes = 0;
564 if (SUCCEEDED(current_state->get_bytesDownloaded(&bytes_downloaded)) &&
565 SUCCEEDED(current_state->get_totalBytesToDownload(&total_bytes)) &&
566 total_bytes) {
567 // Divide by two, as 0-50% is downloading.
568 *progress = (static_cast<double>(bytes_downloaded) /
569 static_cast<double>(total_bytes)) /
570 2.0;
571 }
572 break;
573 }
574
575 case STATE_DOWNLOAD_COMPLETE:
576 case STATE_EXTRACTING:
577 case STATE_APPLYING_DIFFERENTIAL_PATCH:
578 case STATE_READY_TO_INSTALL:
579 case STATE_WAITING_TO_INSTALL:
580 *progress = 0.5;
581 break;
582
583 case STATE_INSTALLING: {
584 *progress = 0.5;
585 LONG install_progress = 0;
586 if (SUCCEEDED(current_state->get_installProgress(&install_progress)) &&
587 install_progress >= 0 && install_progress <= 100) {
Peter Kasting 2015/05/07 22:37:28 Seems like the effect of this is to clamp all out-
grt (UTC plus 2) 2015/05/08 18:51:49 I can't say if a flaw in Google Update will ever c
Peter Kasting 2015/05/09 02:19:01 OK, fair enough.
588 // 50-100% is installing.
589 *progress = (100.0 + install_progress) / 200.0;
590 }
591 break;
592 }
593
594 case STATE_INSTALL_COMPLETE:
595 case STATE_PAUSED:
596 case STATE_NO_UPDATE:
597 case STATE_ERROR:
598 default:
599 NOTREACHED();
600 UMA_HISTOGRAM_SPARSE_SLOWLY("GoogleUpdate.UnexpectedState", state_value);
601 return false;
602 }
603 return true;
604 }
605
606 void UpdateCheckDriver::PollGoogleUpdate() {
607 base::win::ScopedComPtr<ICurrentState> state;
608 CurrentState state_value = STATE_INIT;
609 HRESULT hr = S_OK;
610
Peter Kasting 2015/05/07 22:37:28 Nit: This blank line and the two below seem a bit
grt (UTC plus 2) 2015/05/08 18:51:49 Removed.
611 GoogleUpdateErrorCode error_code = GOOGLE_UPDATE_NO_ERROR;
612 int installer_exit_code = -1;
613 base::string16 error_string;
614
615 GoogleUpdateUpgradeResult upgrade_result = UPGRADE_ERROR;
616 base::string16 new_version;
617
618 double progress = 0.0;
619
620 if (!GetCurrentState(&state, &state_value, &hr)) {
621 OnUpgradeError(GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR, hr, -1,
622 base::string16());
623 } else if (IsErrorState(state, state_value, &error_code, &hr,
624 &installer_exit_code, &error_string)) {
625 OnUpgradeError(error_code, hr, installer_exit_code, error_string);
626 } else if (IsFinalState(state, state_value, &upgrade_result, &new_version)) {
627 result_ = upgrade_result;
628 error_code_ = GOOGLE_UPDATE_NO_ERROR;
629 error_message_.clear();
630 if (!new_version.empty())
631 new_version_ = new_version;
632 hresult_ = S_OK;
633 installer_exit_code_ = -1;
634 } else if (IsIntermediateState(state, state_value, &upgrade_result,
635 &new_version, &progress)) {
636 if (!new_version.empty())
637 new_version_ = new_version;
638 // Give the caller this status update if it differs from the last one given
639 // and schedule the next check.
640 if (upgrade_result != last_result_ || progress != last_progress_) {
641 last_result_ = upgrade_result;
642 last_progress_ = progress;
643
644 result_runner_->PostTask(
645 FROM_HERE,
646 base::Bind(result_callback_, last_result_, last_progress_,
647 GOOGLE_UPDATE_NO_ERROR, base::string16(), new_version_));
648 }
649
650 task_runner_->PostDelayedTask(
651 FROM_HERE, base::Bind(&UpdateCheckDriver::PollGoogleUpdate,
652 base::Unretained(this)),
653 base::TimeDelta::FromMilliseconds(250L));
Peter Kasting 2015/05/07 22:37:28 Nit: Explicit 'L' suffix not necessary You may wa
grt (UTC plus 2) 2015/05/08 18:51:49 Done.
654 // Early return for this non-terminal state.
655 return;
470 } 656 }
471 657
472 // Release the reference on the COM objects before bouncing back to the 658 // Release the reference on the COM objects before bouncing back to the
473 // caller's thread. 659 // caller's thread.
474 on_demand_.Release(); 660 state.Release();
475 job_holder_.Release(); 661 app_.Release();
476 job_observer_ = nullptr; 662 app_bundle_.Release();
663 google_update_.Release();
477 664
478 result_runner_->DeleteSoon(FROM_HERE, this); 665 result_runner_->DeleteSoon(FROM_HERE, this);
479 } 666 }
480 667
481 void UpdateCheckDriver::OnUpgradeError(GoogleUpdateErrorCode error_code, 668 void UpdateCheckDriver::OnUpgradeError(GoogleUpdateErrorCode error_code,
482 HRESULT hr, 669 HRESULT hr,
483 bool system_level) { 670 int installer_exit_code,
671 const base::string16& error_string) {
484 result_ = UPGRADE_ERROR; 672 result_ = UPGRADE_ERROR;
485 error_code_ = error_code; 673 error_code_ = error_code;
486 hresult_ = hr; 674 hresult_ = hr;
675 installer_exit_code_ = installer_exit_code;
487 base::string16 error_msg = 676 base::string16 error_msg =
488 base::StringPrintf(L"%d: 0x%x", error_code_, hresult_); 677 base::StringPrintf(L"%d: 0x%x", error_code_, hresult_);
489 if (system_level) 678 if (installer_exit_code_ != -1)
679 error_msg += base::StringPrintf(L": %d", installer_exit_code_);
680 if (system_level_)
490 error_msg += L" -- system level"; 681 error_msg += L" -- system level";
491 error_message_ = l10n_util::GetStringFUTF16( 682 if (error_string.empty()) {
492 IDS_ABOUT_BOX_ERROR_UPDATE_CHECK_FAILED, error_msg); 683 error_message_ = l10n_util::GetStringFUTF16(
684 IDS_ABOUT_BOX_ERROR_UPDATE_CHECK_FAILED, error_msg);
685 } else {
686 error_message_ = l10n_util::GetStringFUTF16(
687 IDS_ABOUT_BOX_GOOGLE_UPDATE_ERROR, error_string, error_msg);
688 }
493 } 689 }
494 690
495 } // namespace 691 } // namespace
496 692
497 693
498 // Globals --------------------------------------------------------------------- 694 // Globals ---------------------------------------------------------------------
499 695
500 void BeginUpdateCheck(const scoped_refptr<base::TaskRunner>& task_runner, 696 void BeginUpdateCheck(const scoped_refptr<base::TaskRunner>& task_runner,
697 const std::string& locale,
501 bool install_if_newer, 698 bool install_if_newer,
502 gfx::AcceleratedWidget elevation_window, 699 gfx::AcceleratedWidget elevation_window,
503 const UpdateCheckCallback& callback) { 700 const UpdateCheckCallback& callback) {
504 UpdateCheckDriver::RunUpdateCheck(task_runner, install_if_newer, 701 UpdateCheckDriver::RunUpdateCheck(task_runner, locale, install_if_newer,
505 elevation_window, callback); 702 elevation_window, callback);
506 } 703 }
507 704
508 705
509 // Private API exposed for testing. -------------------------------------------- 706 // Private API exposed for testing. --------------------------------------------
510 707
511 void SetGoogleUpdateFactoryForTesting( 708 void SetGoogleUpdateFactoryForTesting(
512 const OnDemandAppsClassFactory& google_update_factory) { 709 const GoogleUpdate3ClassFactory& google_update_factory) {
513 if (g_google_update_factory) { 710 if (g_google_update_factory) {
514 delete g_google_update_factory; 711 delete g_google_update_factory;
515 g_google_update_factory = nullptr; 712 g_google_update_factory = nullptr;
516 } 713 }
517 if (!google_update_factory.is_null()) { 714 if (!google_update_factory.is_null()) {
518 g_google_update_factory = 715 g_google_update_factory =
519 new OnDemandAppsClassFactory(google_update_factory); 716 new GoogleUpdate3ClassFactory(google_update_factory);
520 } 717 }
521 } 718 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698