| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 | |
| 5 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_ | |
| 6 #define CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_ | |
| 7 | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/callback.h" | |
| 12 #include "base/files/file_path.h" | |
| 13 #include "base/memory/ref_counted.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/threading/thread_checker.h" | |
| 16 #include "url/gurl.h" | |
| 17 | |
| 18 namespace base { | |
| 19 class SequencedTaskRunner; | |
| 20 class SingleThreadTaskRunner; | |
| 21 } | |
| 22 | |
| 23 namespace net { | |
| 24 class URLRequestContextGetter; | |
| 25 } | |
| 26 | |
| 27 namespace component_updater { | |
| 28 | |
| 29 // Defines a download interface for downloading components, with retrying on | |
| 30 // fallback urls in case of errors. This class implements a chain of | |
| 31 // responsibility design pattern. It can give successors in the chain a chance | |
| 32 // to handle a download request, until one of them succeeds, or there are no | |
| 33 // more urls or successors to try. A callback is always called at the end of | |
| 34 // the download, one time only. | |
| 35 // When multiple urls and downloaders exists, first all the urls are tried, in | |
| 36 // the order they are provided in the StartDownload function argument. After | |
| 37 // that, the download request is routed to the next downloader in the chain. | |
| 38 // The members of this class expect to be called from the main thread only. | |
| 39 class CrxDownloader { | |
| 40 public: | |
| 41 struct DownloadMetrics { | |
| 42 enum Downloader { kNone = 0, kUrlFetcher, kBits }; | |
| 43 | |
| 44 DownloadMetrics(); | |
| 45 | |
| 46 GURL url; | |
| 47 | |
| 48 Downloader downloader; | |
| 49 | |
| 50 int error; | |
| 51 | |
| 52 int64 downloaded_bytes; // -1 means that the byte count is unknown. | |
| 53 int64 total_bytes; | |
| 54 | |
| 55 uint64 download_time_ms; | |
| 56 }; | |
| 57 | |
| 58 // Contains the progress or the outcome of the download. | |
| 59 struct Result { | |
| 60 Result(); | |
| 61 | |
| 62 // Download error: 0 indicates success. | |
| 63 int error; | |
| 64 | |
| 65 // Path of the downloaded file if the download was successful. | |
| 66 base::FilePath response; | |
| 67 | |
| 68 // Number of bytes actually downloaded, not including the bytes downloaded | |
| 69 // as a result of falling back on urls. | |
| 70 int64 downloaded_bytes; | |
| 71 | |
| 72 // Number of bytes expected to be downloaded. | |
| 73 int64 total_bytes; | |
| 74 }; | |
| 75 | |
| 76 // The callback fires only once, regardless of how many urls are tried, and | |
| 77 // how many successors in the chain of downloaders have handled the | |
| 78 // download. The callback interface can be extended if needed to provide | |
| 79 // more visibility into how the download has been handled, including | |
| 80 // specific error codes and download metrics. | |
| 81 typedef base::Callback<void(const Result& result)> DownloadCallback; | |
| 82 | |
| 83 // The callback may fire 0 or many times during a download. Since this | |
| 84 // class implements a chain of responsibility, the callback can fire for | |
| 85 // different urls and different downloaders. The number of actual downloaded | |
| 86 // bytes is not guaranteed to monotonically increment over time. | |
| 87 typedef base::Callback<void(const Result& result)> ProgressCallback; | |
| 88 | |
| 89 // Factory method to create an instance of this class and build the | |
| 90 // chain of responsibility. |is_background_download| specifies that a | |
| 91 // background downloader be used, if the platform supports it. | |
| 92 // |url_fetcher_task_runner| should be an IO capable task runner able to | |
| 93 // support UrlFetcherDownloader. |background_task_runner| should be an | |
| 94 // IO capable thread able to support BackgroundDownloader. | |
| 95 static CrxDownloader* Create( | |
| 96 bool is_background_download, | |
| 97 net::URLRequestContextGetter* context_getter, | |
| 98 scoped_refptr<base::SequencedTaskRunner> url_fetcher_task_runner, | |
| 99 scoped_refptr<base::SingleThreadTaskRunner> background_task_runner); | |
| 100 virtual ~CrxDownloader(); | |
| 101 | |
| 102 void set_progress_callback(const ProgressCallback& progress_callback); | |
| 103 | |
| 104 // Starts the download. One instance of the class handles one download only. | |
| 105 // One instance of CrxDownloader can only be started once, otherwise the | |
| 106 // behavior is undefined. The callback gets invoked if the download can't | |
| 107 // be started. | |
| 108 void StartDownloadFromUrl(const GURL& url, | |
| 109 const DownloadCallback& download_callback); | |
| 110 void StartDownload(const std::vector<GURL>& urls, | |
| 111 const DownloadCallback& download_callback); | |
| 112 | |
| 113 const std::vector<DownloadMetrics> download_metrics() const; | |
| 114 | |
| 115 protected: | |
| 116 explicit CrxDownloader(scoped_ptr<CrxDownloader> successor); | |
| 117 | |
| 118 // Handles the fallback in the case of multiple urls and routing of the | |
| 119 // download to the following successor in the chain. Derived classes must call | |
| 120 // this function after each attempt at downloading the urls provided | |
| 121 // in the StartDownload function. | |
| 122 // In case of errors, |is_handled| indicates that a server side error has | |
| 123 // occured for the current url and the url should not be retried down | |
| 124 // the chain to avoid DDOS of the server. This url will be removed from the | |
| 125 // list of url and never tried again. | |
| 126 void OnDownloadComplete(bool is_handled, | |
| 127 const Result& result, | |
| 128 const DownloadMetrics& download_metrics); | |
| 129 | |
| 130 // Calls the callback when progress is made. | |
| 131 void OnDownloadProgress(const Result& result); | |
| 132 | |
| 133 // Returns the url which is currently being downloaded from. | |
| 134 GURL url() const; | |
| 135 | |
| 136 private: | |
| 137 virtual void DoStartDownload(const GURL& url) = 0; | |
| 138 | |
| 139 base::ThreadChecker thread_checker_; | |
| 140 | |
| 141 std::vector<GURL> urls_; | |
| 142 scoped_ptr<CrxDownloader> successor_; | |
| 143 DownloadCallback download_callback_; | |
| 144 ProgressCallback progress_callback_; | |
| 145 | |
| 146 std::vector<GURL>::iterator current_url_; | |
| 147 | |
| 148 std::vector<DownloadMetrics> download_metrics_; | |
| 149 | |
| 150 DISALLOW_COPY_AND_ASSIGN(CrxDownloader); | |
| 151 }; | |
| 152 | |
| 153 } // namespace component_updater | |
| 154 | |
| 155 #endif // CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_ | |
| OLD | NEW |