Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include <objbase.h> | 9 #include <objbase.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 | 12 |
| 13 #include <string> | 13 #include <string> |
| 14 #include <utility> | 14 #include <utility> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "base/bind.h" | 17 #include "base/bind.h" |
| 18 #include "base/callback.h" | 18 #include "base/callback.h" |
| 19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
| 20 #include "base/location.h" | 20 #include "base/location.h" |
| 21 #include "base/macros.h" | 21 #include "base/macros.h" |
| 22 #include "base/metrics/histogram_macros.h" | 22 #include "base/metrics/histogram_macros.h" |
| 23 #include "base/metrics/sparse_histogram.h" | 23 #include "base/metrics/sparse_histogram.h" |
| 24 #include "base/path_service.h" | 24 #include "base/path_service.h" |
| 25 #include "base/sequenced_task_runner.h" | |
| 25 #include "base/sequenced_task_runner_helpers.h" | 26 #include "base/sequenced_task_runner_helpers.h" |
| 26 #include "base/single_thread_task_runner.h" | |
| 27 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
| 28 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| 29 #include "base/strings/utf_string_conversions.h" | 29 #include "base/strings/utf_string_conversions.h" |
| 30 #include "base/threading/thread_task_runner_handle.h" | 30 #include "base/task_scheduler/post_task.h" |
| 31 #include "base/task_scheduler/task_traits.h" | |
| 32 #include "base/threading/sequenced_task_runner_handle.h" | |
| 31 #include "base/time/time.h" | 33 #include "base/time/time.h" |
| 32 #include "base/version.h" | 34 #include "base/version.h" |
| 33 #include "base/win/scoped_bstr.h" | 35 #include "base/win/scoped_bstr.h" |
| 34 #include "chrome/common/url_constants.h" | 36 #include "chrome/common/url_constants.h" |
| 35 #include "chrome/grit/generated_resources.h" | 37 #include "chrome/grit/generated_resources.h" |
| 36 #include "chrome/install_static/install_util.h" | 38 #include "chrome/install_static/install_util.h" |
| 37 #include "chrome/installer/util/google_update_settings.h" | 39 #include "chrome/installer/util/google_update_settings.h" |
| 38 #include "chrome/installer/util/helper.h" | 40 #include "chrome/installer/util/helper.h" |
| 39 #include "chrome/installer/util/install_util.h" | 41 #include "chrome/installer/util/install_util.h" |
| 40 #include "ui/base/l10n/l10n_util.h" | 42 #include "ui/base/l10n/l10n_util.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 55 // The upgrade happened successfully. | 57 // The upgrade happened successfully. |
| 56 UPGRADE_SUCCESSFUL = 3, | 58 UPGRADE_SUCCESSFUL = 3, |
| 57 // No need to upgrade, Chrome is up to date. | 59 // No need to upgrade, Chrome is up to date. |
| 58 UPGRADE_ALREADY_UP_TO_DATE = 4, | 60 UPGRADE_ALREADY_UP_TO_DATE = 4, |
| 59 // An error occurred. | 61 // An error occurred. |
| 60 UPGRADE_ERROR = 5, | 62 UPGRADE_ERROR = 5, |
| 61 NUM_UPGRADE_STATUS | 63 NUM_UPGRADE_STATUS |
| 62 }; | 64 }; |
| 63 | 65 |
| 64 GoogleUpdate3ClassFactory* g_google_update_factory = nullptr; | 66 GoogleUpdate3ClassFactory* g_google_update_factory = nullptr; |
| 67 scoped_refptr<base::SequencedTaskRunner> g_update_driver_task_runner = nullptr; | |
|
gab
2017/07/19 15:15:24
I think this needs to be a raw pointer to avoid a
calamity
2017/07/20 03:56:20
Done.
| |
| 65 | 68 |
| 66 // The time interval, in milliseconds, between polls to Google Update. This | 69 // The time interval, in milliseconds, between polls to Google Update. This |
| 67 // value was chosen unscientificaly during an informal discussion. | 70 // value was chosen unscientificaly during an informal discussion. |
| 68 const int64_t kGoogleUpdatePollIntervalMs = 250; | 71 const int64_t kGoogleUpdatePollIntervalMs = 250; |
| 69 | 72 |
| 70 const int kGoogleAllowedRetries = 1; | 73 const int kGoogleAllowedRetries = 1; |
| 71 const int kGoogleRetryIntervalSeconds = 5; | 74 const int kGoogleRetryIntervalSeconds = 5; |
| 72 | 75 |
| 73 // Constants from Google Update. | 76 // Constants from Google Update. |
| 74 const HRESULT GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY = 0x80040813; | 77 const HRESULT GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY = 0x80040813; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 return class_factory->CreateInstance( | 193 return class_factory->CreateInstance( |
| 191 nullptr, IID_PPV_ARGS(google_update->GetAddressOf())); | 194 nullptr, IID_PPV_ARGS(google_update->GetAddressOf())); |
| 192 } | 195 } |
| 193 | 196 |
| 194 // UpdateCheckDriver ----------------------------------------------------------- | 197 // UpdateCheckDriver ----------------------------------------------------------- |
| 195 | 198 |
| 196 // A driver that is created and destroyed on the caller's thread and drives | 199 // A driver that is created and destroyed on the caller's thread and drives |
| 197 // Google Update on another. | 200 // Google Update on another. |
| 198 class UpdateCheckDriver { | 201 class UpdateCheckDriver { |
| 199 public: | 202 public: |
| 200 // Runs an update check on |task_runner|, invoking methods of |delegate| on | 203 // Runs an update check, invoking methods of |delegate| on the caller's thread |
| 201 // the caller's thread to report progress and final results. | 204 // to report progress and final results. |
| 202 static void RunUpdateCheck( | 205 static void RunUpdateCheck( |
| 203 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 204 const std::string& locale, | 206 const std::string& locale, |
| 205 bool install_update_if_possible, | 207 bool install_update_if_possible, |
| 206 gfx::AcceleratedWidget elevation_window, | 208 gfx::AcceleratedWidget elevation_window, |
| 207 const base::WeakPtr<UpdateCheckDelegate>& delegate); | 209 const base::WeakPtr<UpdateCheckDelegate>& delegate); |
| 208 | 210 |
| 209 private: | 211 private: |
| 210 friend class base::DeleteHelper<UpdateCheckDriver>; | 212 friend class base::DeleteHelper<UpdateCheckDriver>; |
| 211 | 213 |
| 212 UpdateCheckDriver( | 214 UpdateCheckDriver( |
| 213 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 214 const std::string& locale, | 215 const std::string& locale, |
| 215 bool install_update_if_possible, | 216 bool install_update_if_possible, |
| 216 gfx::AcceleratedWidget elevation_window, | 217 gfx::AcceleratedWidget elevation_window, |
| 217 const base::WeakPtr<UpdateCheckDelegate>& delegate); | 218 const base::WeakPtr<UpdateCheckDelegate>& delegate); |
| 218 | 219 |
| 219 // Invokes a completion or error method on all delegates, as appropriate. | 220 // Invokes a completion or error method on all delegates, as appropriate. |
| 220 ~UpdateCheckDriver(); | 221 ~UpdateCheckDriver(); |
| 221 | 222 |
| 222 // If an UpdateCheckDriver is already running, the delegate is added to the | 223 // If an UpdateCheckDriver is already running, the delegate is added to the |
| 223 // existing one instead of creating a new one. | 224 // existing one instead of creating a new one. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 // update. If the process has reached a terminal state, this instance will be | 302 // update. If the process has reached a terminal state, this instance will be |
| 302 // deleted and the caller will be notified of the final status. Otherwise, the | 303 // deleted and the caller will be notified of the final status. Otherwise, the |
| 303 // caller will be notified of the intermediate state (iff it differs from a | 304 // caller will be notified of the intermediate state (iff it differs from a |
| 304 // previous notification) and another future poll will be scheduled. | 305 // previous notification) and another future poll will be scheduled. |
| 305 void PollGoogleUpdate(); | 306 void PollGoogleUpdate(); |
| 306 | 307 |
| 307 // The global driver instance. Accessed only on the caller's thread. | 308 // The global driver instance. Accessed only on the caller's thread. |
| 308 static UpdateCheckDriver* driver_; | 309 static UpdateCheckDriver* driver_; |
| 309 | 310 |
| 310 // The task runner on which the update checks runs. | 311 // The task runner on which the update checks runs. |
| 311 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 312 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 312 | 313 |
| 313 // The caller's task runner, on which methods of the |delegates_| will be | 314 // The caller's task runner, on which methods of the |delegates_| will be |
| 314 // invoked. | 315 // invoked. |
| 315 scoped_refptr<base::SingleThreadTaskRunner> result_runner_; | 316 scoped_refptr<base::SequencedTaskRunner> result_runner_; |
| 316 | 317 |
| 317 // The UI locale. | 318 // The UI locale. |
| 318 std::string locale_; | 319 std::string locale_; |
| 319 | 320 |
| 320 // False to only check for an update; true to also install one if available. | 321 // False to only check for an update; true to also install one if available. |
| 321 bool install_update_if_possible_; | 322 bool install_update_if_possible_; |
| 322 | 323 |
| 323 // A parent window in case any UX is required (e.g., an elevation prompt). | 324 // A parent window in case any UX is required (e.g., an elevation prompt). |
| 324 gfx::AcceleratedWidget elevation_window_; | 325 gfx::AcceleratedWidget elevation_window_; |
| 325 | 326 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 354 HRESULT hresult_; | 355 HRESULT hresult_; |
| 355 int installer_exit_code_; | 356 int installer_exit_code_; |
| 356 | 357 |
| 357 DISALLOW_COPY_AND_ASSIGN(UpdateCheckDriver); | 358 DISALLOW_COPY_AND_ASSIGN(UpdateCheckDriver); |
| 358 }; | 359 }; |
| 359 | 360 |
| 360 UpdateCheckDriver* UpdateCheckDriver::driver_ = nullptr; | 361 UpdateCheckDriver* UpdateCheckDriver::driver_ = nullptr; |
| 361 | 362 |
| 362 // static | 363 // static |
| 363 void UpdateCheckDriver::RunUpdateCheck( | 364 void UpdateCheckDriver::RunUpdateCheck( |
| 364 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 365 const std::string& locale, | 365 const std::string& locale, |
| 366 bool install_update_if_possible, | 366 bool install_update_if_possible, |
| 367 gfx::AcceleratedWidget elevation_window, | 367 gfx::AcceleratedWidget elevation_window, |
| 368 const base::WeakPtr<UpdateCheckDelegate>& delegate) { | 368 const base::WeakPtr<UpdateCheckDelegate>& delegate) { |
| 369 // Create the driver if it doesn't exist, or add the delegate to the existing | 369 // Create the driver if it doesn't exist, or add the delegate to the existing |
| 370 // one. | 370 // one. |
| 371 if (!driver_) { | 371 if (!driver_) { |
| 372 // The driver is owned by itself, and will self-destruct when its work is | 372 // The driver is owned by itself, and will self-destruct when its work is |
| 373 // done. | 373 // done. |
| 374 driver_ = | 374 driver_ = new UpdateCheckDriver(locale, install_update_if_possible, |
| 375 new UpdateCheckDriver(task_runner, locale, install_update_if_possible, | 375 elevation_window, delegate); |
| 376 elevation_window, delegate); | 376 driver_->task_runner_->PostTask( |
| 377 task_runner->PostTask(FROM_HERE, | 377 FROM_HERE, base::Bind(&UpdateCheckDriver::BeginUpdateCheck, |
| 378 base::Bind(&UpdateCheckDriver::BeginUpdateCheck, | 378 base::Unretained(driver_))); |
| 379 base::Unretained(driver_))); | |
| 380 } else { | 379 } else { |
| 381 DCHECK_EQ(driver_->task_runner_, task_runner); | |
| 382 driver_->AddDelegate(delegate); | 380 driver_->AddDelegate(delegate); |
| 383 } | 381 } |
| 384 } | 382 } |
| 385 | 383 |
| 386 // Runs on the caller's thread. | 384 // Runs on the caller's thread. |
| 387 UpdateCheckDriver::UpdateCheckDriver( | 385 UpdateCheckDriver::UpdateCheckDriver( |
| 388 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 389 const std::string& locale, | 386 const std::string& locale, |
| 390 bool install_update_if_possible, | 387 bool install_update_if_possible, |
| 391 gfx::AcceleratedWidget elevation_window, | 388 gfx::AcceleratedWidget elevation_window, |
| 392 const base::WeakPtr<UpdateCheckDelegate>& delegate) | 389 const base::WeakPtr<UpdateCheckDelegate>& delegate) |
| 393 : task_runner_(std::move(task_runner)), | 390 : task_runner_( |
| 394 result_runner_(base::ThreadTaskRunnerHandle::Get()), | 391 g_update_driver_task_runner |
| 392 ? std::move(g_update_driver_task_runner) | |
| 393 : base::CreateSequencedTaskRunnerWithTraits( | |
| 394 {base::MayBlock(), base::TaskPriority::USER_VISIBLE})), | |
| 395 result_runner_(base::SequencedTaskRunnerHandle::Get()), | |
| 395 locale_(locale), | 396 locale_(locale), |
| 396 install_update_if_possible_(install_update_if_possible), | 397 install_update_if_possible_(install_update_if_possible), |
| 397 elevation_window_(elevation_window), | 398 elevation_window_(elevation_window), |
| 398 delegates_(1, delegate), | 399 delegates_(1, delegate), |
| 399 allowed_retries_(kGoogleAllowedRetries), | 400 allowed_retries_(kGoogleAllowedRetries), |
| 400 system_level_install_(false), | 401 system_level_install_(false), |
| 401 last_reported_progress_(0), | 402 last_reported_progress_(0), |
| 402 status_(UPGRADE_ERROR), | 403 status_(UPGRADE_ERROR), |
| 403 error_code_(GOOGLE_UPDATE_NO_ERROR), | 404 error_code_(GOOGLE_UPDATE_NO_ERROR), |
| 404 hresult_(S_OK), | 405 hresult_(S_OK), |
| 405 installer_exit_code_(-1) {} | 406 installer_exit_code_(-1) {} |
| 406 | 407 |
| 407 UpdateCheckDriver::~UpdateCheckDriver() { | 408 UpdateCheckDriver::~UpdateCheckDriver() { |
| 408 DCHECK(result_runner_->BelongsToCurrentThread()); | |
|
gab
2017/07/19 15:15:24
Why remove these checks? With SequencedTaskRunner
calamity
2017/07/20 03:56:20
Done.
| |
| 409 // If there is an error, then error_code must not be blank, and vice versa. | 409 // If there is an error, then error_code must not be blank, and vice versa. |
| 410 DCHECK_NE(status_ == UPGRADE_ERROR, error_code_ == GOOGLE_UPDATE_NO_ERROR); | 410 DCHECK_NE(status_ == UPGRADE_ERROR, error_code_ == GOOGLE_UPDATE_NO_ERROR); |
| 411 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpgradeResult", status_, | 411 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpgradeResult", status_, |
| 412 NUM_UPGRADE_STATUS); | 412 NUM_UPGRADE_STATUS); |
| 413 if (status_ == UPGRADE_ERROR) { | 413 if (status_ == UPGRADE_ERROR) { |
| 414 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpdateErrorCode", error_code_, | 414 UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpdateErrorCode", error_code_, |
| 415 NUM_ERROR_CODES); | 415 NUM_ERROR_CODES); |
| 416 if (FAILED(hresult_)) | 416 if (FAILED(hresult_)) |
| 417 UMA_HISTOGRAM_SPARSE_SLOWLY("GoogleUpdate.ErrorHresult", hresult_); | 417 UMA_HISTOGRAM_SPARSE_SLOWLY("GoogleUpdate.ErrorHresult", hresult_); |
| 418 if (installer_exit_code_ != -1) { | 418 if (installer_exit_code_ != -1) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 433 else if (install_update_if_possible_) | 433 else if (install_update_if_possible_) |
| 434 delegate->OnUpgradeComplete(new_version_); | 434 delegate->OnUpgradeComplete(new_version_); |
| 435 else | 435 else |
| 436 delegate->OnUpdateCheckComplete(new_version_); | 436 delegate->OnUpdateCheckComplete(new_version_); |
| 437 } | 437 } |
| 438 } | 438 } |
| 439 } | 439 } |
| 440 | 440 |
| 441 void UpdateCheckDriver::AddDelegate( | 441 void UpdateCheckDriver::AddDelegate( |
| 442 const base::WeakPtr<UpdateCheckDelegate>& delegate) { | 442 const base::WeakPtr<UpdateCheckDelegate>& delegate) { |
| 443 DCHECK(result_runner_->BelongsToCurrentThread()); | |
| 444 delegates_.push_back(delegate); | 443 delegates_.push_back(delegate); |
| 445 } | 444 } |
| 446 | 445 |
| 447 void UpdateCheckDriver::NotifyUpgradeProgress( | 446 void UpdateCheckDriver::NotifyUpgradeProgress( |
| 448 int progress, | 447 int progress, |
| 449 const base::string16& new_version) { | 448 const base::string16& new_version) { |
| 450 DCHECK(result_runner_->BelongsToCurrentThread()); | |
| 451 | 449 |
| 452 for (const auto& delegate : delegates_) { | 450 for (const auto& delegate : delegates_) { |
| 453 if (delegate) | 451 if (delegate) |
| 454 delegate->OnUpgradeProgress(progress, new_version); | 452 delegate->OnUpgradeProgress(progress, new_version); |
| 455 } | 453 } |
| 456 } | 454 } |
| 457 | 455 |
| 458 void UpdateCheckDriver::BeginUpdateCheck() { | 456 void UpdateCheckDriver::BeginUpdateCheck() { |
| 459 GoogleUpdateErrorCode error_code = GOOGLE_UPDATE_NO_ERROR; | 457 GoogleUpdateErrorCode error_code = GOOGLE_UPDATE_NO_ERROR; |
| 460 HRESULT hresult = BeginUpdateCheckInternal(&error_code); | 458 HRESULT hresult = BeginUpdateCheckInternal(&error_code); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 IDS_ABOUT_BOX_GOOGLE_UPDATE_ERROR, error_string, html_error_msg); | 850 IDS_ABOUT_BOX_GOOGLE_UPDATE_ERROR, error_string, html_error_msg); |
| 853 } | 851 } |
| 854 } | 852 } |
| 855 | 853 |
| 856 } // namespace | 854 } // namespace |
| 857 | 855 |
| 858 | 856 |
| 859 // Globals --------------------------------------------------------------------- | 857 // Globals --------------------------------------------------------------------- |
| 860 | 858 |
| 861 void BeginUpdateCheck( | 859 void BeginUpdateCheck( |
| 862 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 863 const std::string& locale, | 860 const std::string& locale, |
| 864 bool install_update_if_possible, | 861 bool install_update_if_possible, |
| 865 gfx::AcceleratedWidget elevation_window, | 862 gfx::AcceleratedWidget elevation_window, |
| 866 const base::WeakPtr<UpdateCheckDelegate>& delegate) { | 863 const base::WeakPtr<UpdateCheckDelegate>& delegate) { |
| 867 UpdateCheckDriver::RunUpdateCheck(std::move(task_runner), locale, | 864 UpdateCheckDriver::RunUpdateCheck(locale, install_update_if_possible, |
| 868 install_update_if_possible, | |
| 869 elevation_window, delegate); | 865 elevation_window, delegate); |
| 870 } | 866 } |
| 871 | 867 |
| 872 | 868 |
| 873 // Private API exposed for testing. -------------------------------------------- | 869 // Private API exposed for testing. -------------------------------------------- |
| 874 | 870 |
| 875 void SetGoogleUpdateFactoryForTesting( | 871 void SetGoogleUpdateFactoryForTesting( |
| 876 const GoogleUpdate3ClassFactory& google_update_factory) { | 872 const GoogleUpdate3ClassFactory& google_update_factory) { |
| 877 if (g_google_update_factory) { | 873 if (g_google_update_factory) { |
| 878 delete g_google_update_factory; | 874 delete g_google_update_factory; |
| 879 g_google_update_factory = nullptr; | 875 g_google_update_factory = nullptr; |
| 880 } | 876 } |
| 881 if (!google_update_factory.is_null()) { | 877 if (!google_update_factory.is_null()) { |
| 882 g_google_update_factory = | 878 g_google_update_factory = |
| 883 new GoogleUpdate3ClassFactory(google_update_factory); | 879 new GoogleUpdate3ClassFactory(google_update_factory); |
| 884 } | 880 } |
| 885 } | 881 } |
| 882 | |
| 883 // TODO(calamity): Remove once a MockTimer is implemented in | |
| 884 // ScopedTaskEnvironment. See https://crbug.com/708584. | |
| 885 void SetUpdateDriverTaskRunnerForTesting( | |
| 886 scoped_refptr<base::SequencedTaskRunner> task_runner) { | |
| 887 g_update_driver_task_runner = std::move(task_runner); | |
| 888 } | |
| OLD | NEW |