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