1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_UPDATE_CLIENT_BACKGROUND_DOWNLOADER_WIN_H_
#define COMPONENTS_UPDATE_CLIENT_BACKGROUND_DOWNLOADER_WIN_H_
#include <windows.h>
#include <bits.h>
#include <wrl/client.h>
#include <memory>
#include "base/functional/callback_forward.h"
#include "base/functional/function_ref.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/update_client/crx_downloader.h"
namespace base {
class FilePath;
class SequencedTaskRunner;
} // namespace base
namespace update_client {
// Implements a downloader in terms of the BITS service. The public interface
// of this class and the CrxDownloader overrides are expected to be called
// from the main sequence. The rest of the class code runs on a sequenced
// task runner which is initialized by default as an MTA by the thread pool.
//
// This class manages a COM client for Windows BITS. The client uses polling,
// triggered by an one-shot timer, to get state updates from BITS. Since the
// timer has sequence affinity for the main sequence, the callbacks from the
// timer are delegated to a sequenced task runner, which handles all client COM
// interaction with the BITS service.
class BackgroundDownloader : public CrxDownloader {
public:
explicit BackgroundDownloader(scoped_refptr<CrxDownloader> successor);
private:
friend class BackgroundDownloaderWinTest;
FRIEND_TEST_ALL_PREFIXES(BackgroundDownloaderWinTest, CleansStaleDownloads);
FRIEND_TEST_ALL_PREFIXES(BackgroundDownloaderWinTest, RetainsRecentDownloads);
// Overrides for CrxDownloader.
~BackgroundDownloader() override;
base::OnceClosure DoStartDownload(const GURL& url) override;
// Called asynchronously on the |com_task_runner_| at different stages during
// the download. |OnDownloading| can be called multiple times.
// |EndDownload| switches the execution flow from the |com_task_runner_| to
// the main sequence.
void BeginDownload(const GURL& url);
void OnDownloading();
void EndDownload(HRESULT hr);
HRESULT BeginDownloadHelper(const GURL& url);
// Handles the job state transitions to a final state. Returns true always
// since the download has reached a final state and no further processing for
// this download is needed.
bool OnStateTransferred();
bool OnStateError();
bool OnStateCancelled();
bool OnStateAcknowledged();
// Handles the transition to a transient state where the job is in the
// queue but not actively transferring data. Returns true if the download has
// been in this state for too long and it will be abandoned, or false, if
// further processing for this download is needed.
bool OnStateQueued();
// Handles the job state transition to a transient error state, which may or
// may not be considered final, depending on the error. Returns true if
// the state is final, or false, if the download is allowed to continue.
bool OnStateTransientError();
// Handles the job state corresponding to transferring data. Returns false
// always since this is never a final state.
bool OnStateTransferring();
void StartTimer();
void OnTimer();
// Creates or opens a job for the given url and queues it up. Returns S_OK if
// a new job was created or S_FALSE if an existing job for the |url| was found
// in the BITS queue.
HRESULT QueueBitsJob(const GURL& url,
Microsoft::WRL::ComPtr<IBackgroundCopyJob>* job);
HRESULT CreateOrOpenJob(const GURL& url,
Microsoft::WRL::ComPtr<IBackgroundCopyJob>* job);
HRESULT InitializeNewJob(
const Microsoft::WRL::ComPtr<IBackgroundCopyJob>& job,
const GURL& url);
// Returns true if at the time of the call, it appears that the job
// has not been making progress toward completion.
bool IsStuck();
// Makes the downloaded file available to the caller by renaming the
// temporary file to its destination and removing it from the BITS queue.
HRESULT CompleteJob();
// Returns the number of jobs in the BITS queue which were created by this
// downloader.
HRESULT GetBackgroundDownloaderJobCount(size_t* num_jobs);
// Cleans up incompleted jobs that are too old.
void CleanupStaleJobs();
// Perform a best-effort cleanup up downloads that are too old.
void CleanupStaleDownloads();
// Enumerate the writable temporary directories matching |matcher|.
void EnumerateDownloadDirs(
const base::FilePath::StringType& matcher,
base::FunctionRef<void(const base::FilePath& dir)> callback);
// This sequence checker is bound to the main sequence.
SEQUENCE_CHECKER(sequence_checker_);
SEQUENCE_CHECKER(com_sequence_checker_);
// Executes blocking COM calls to BITS.
scoped_refptr<base::SequencedTaskRunner> com_task_runner_;
// The timer has sequence affinity. This member is created and destroyed
// on the main task runner.
std::unique_ptr<base::OneShotTimer> timer_;
// Valid only in the MTA associated with `com_task_runner_`;
Microsoft::WRL::ComPtr<IBackgroundCopyManager> bits_manager_;
Microsoft::WRL::ComPtr<IBackgroundCopyJob> job_;
// Contains the time when the download of the current url has started.
base::TimeTicks download_start_time_;
// Contains the time when the BITS job is last seen making progress.
base::TimeTicks job_stuck_begin_time_;
// Contains the path of the downloaded file if the download was successful.
base::FilePath response_;
};
} // namespace update_client
#endif // COMPONENTS_UPDATE_CLIENT_BACKGROUND_DOWNLOADER_WIN_H_
|