background_downloader_win.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_UPDATE_CLIENT_BACKGROUND_DOWNLOADER_WIN_H_
  5. #define COMPONENTS_UPDATE_CLIENT_BACKGROUND_DOWNLOADER_WIN_H_
  6. #include <bits.h>
  7. #include <windows.h>
  8. #include <wrl/client.h>
  9. #include <memory>
  10. #include "base/memory/ref_counted.h"
  11. #include "base/sequence_checker.h"
  12. #include "base/time/time.h"
  13. #include "base/timer/timer.h"
  14. #include "components/update_client/crx_downloader.h"
  15. namespace base {
  16. class FilePath;
  17. class SequencedTaskRunner;
  18. }
  19. namespace update_client {
  20. // Implements a downloader in terms of the BITS service. The public interface
  21. // of this class and the CrxDownloader overrides are expected to be called
  22. // from the main sequence. The rest of the class code runs on a sequenced
  23. // task runner. The task runner must initialize COM.
  24. //
  25. // This class manages a COM client for Windows BITS. The client uses polling,
  26. // triggered by an one-shot timer, to get state updates from BITS. Since the
  27. // timer has sequence afinity, the callbacks from the timer are delegated to
  28. // a sequenced task runner, which handles all client COM interaction with
  29. // the BITS service.
  30. class BackgroundDownloader : public CrxDownloader {
  31. public:
  32. explicit BackgroundDownloader(scoped_refptr<CrxDownloader> successor);
  33. private:
  34. // Overrides for CrxDownloader.
  35. ~BackgroundDownloader() override;
  36. void DoStartDownload(const GURL& url) override;
  37. // Called asynchronously on the |com_task_runner_| at different stages during
  38. // the download. |OnDownloading| can be called multiple times.
  39. // |EndDownload| switches the execution flow from the |com_task_runner_| to
  40. // the main sequence.
  41. void BeginDownload(const GURL& url);
  42. void OnDownloading();
  43. void EndDownload(HRESULT hr);
  44. HRESULT BeginDownloadHelper(const GURL& url);
  45. // Handles the job state transitions to a final state. Returns true always
  46. // since the download has reached a final state and no further processing for
  47. // this download is needed.
  48. bool OnStateTransferred();
  49. bool OnStateError();
  50. bool OnStateCancelled();
  51. bool OnStateAcknowledged();
  52. // Handles the transition to a transient state where the job is in the
  53. // queue but not actively transferring data. Returns true if the download has
  54. // been in this state for too long and it will be abandoned, or false, if
  55. // further processing for this download is needed.
  56. bool OnStateQueued();
  57. // Handles the job state transition to a transient error state, which may or
  58. // may not be considered final, depending on the error. Returns true if
  59. // the state is final, or false, if the download is allowed to continue.
  60. bool OnStateTransientError();
  61. // Handles the job state corresponding to transferring data. Returns false
  62. // always since this is never a final state.
  63. bool OnStateTransferring();
  64. void StartTimer();
  65. void OnTimer();
  66. // Creates or opens a job for the given url and queues it up. Returns S_OK if
  67. // a new job was created or S_FALSE if an existing job for the |url| was found
  68. // in the BITS queue.
  69. HRESULT QueueBitsJob(const GURL& url,
  70. Microsoft::WRL::ComPtr<IBackgroundCopyJob>* job);
  71. HRESULT CreateOrOpenJob(const GURL& url,
  72. Microsoft::WRL::ComPtr<IBackgroundCopyJob>* job);
  73. HRESULT InitializeNewJob(
  74. const Microsoft::WRL::ComPtr<IBackgroundCopyJob>& job,
  75. const GURL& url);
  76. // Returns true if at the time of the call, it appears that the job
  77. // has not been making progress toward completion.
  78. bool IsStuck();
  79. // Makes the downloaded file available to the caller by renaming the
  80. // temporary file to its destination and removing it from the BITS queue.
  81. HRESULT CompleteJob();
  82. // Revokes the interface pointers from GIT.
  83. HRESULT ClearGit();
  84. // Updates the BITS interface pointers so that the COM functions of these
  85. // interfaces can be called in this COM STA apartment.
  86. HRESULT UpdateInterfacePointers();
  87. // Resets the BITS interface pointers.
  88. void ResetInterfacePointers();
  89. // Returns the number of jobs in the BITS queue which were created by this
  90. // downloader.
  91. HRESULT GetBackgroundDownloaderJobCount(size_t* num_jobs);
  92. // Cleans up incompleted jobs that are too old.
  93. void CleanupStaleJobs();
  94. // This sequence checker is bound to the main sequence.
  95. SEQUENCE_CHECKER(sequence_checker_);
  96. // Executes blocking COM calls to BITS.
  97. scoped_refptr<base::SequencedTaskRunner> com_task_runner_;
  98. // The timer has sequence affinity. This member is created and destroyed
  99. // on the main task runner.
  100. std::unique_ptr<base::OneShotTimer> timer_;
  101. DWORD git_cookie_bits_manager_;
  102. DWORD git_cookie_job_;
  103. // COM interface pointers are valid for the thread that called
  104. // |UpdateInterfacePointers| to get pointers to COM proxies, which are valid
  105. // for that thread only.
  106. Microsoft::WRL::ComPtr<IBackgroundCopyManager> bits_manager_;
  107. Microsoft::WRL::ComPtr<IBackgroundCopyJob> job_;
  108. // Contains the time when the download of the current url has started.
  109. base::TimeTicks download_start_time_;
  110. // Contains the time when the BITS job is last seen making progress.
  111. base::TimeTicks job_stuck_begin_time_;
  112. // Contains the path of the downloaded file if the download was successful.
  113. base::FilePath response_;
  114. };
  115. } // namespace update_client
  116. #endif // COMPONENTS_UPDATE_CLIENT_BACKGROUND_DOWNLOADER_WIN_H_