OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/browser/background_fetch/background_fetch_job_controller.h" | 5 #include "content/browser/background_fetch/background_fetch_job_controller.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 ~Core() final { | 34 ~Core() final { |
35 for (const auto& pair : downloads_) | 35 for (const auto& pair : downloads_) |
36 pair.first->RemoveObserver(this); | 36 pair.first->RemoveObserver(this); |
37 } | 37 } |
38 | 38 |
39 // Returns a weak pointer that can be used to talk to |this|. | 39 // Returns a weak pointer that can be used to talk to |this|. |
40 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } | 40 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } |
41 | 41 |
42 // Starts fetching the |request| with the download manager. | 42 // Starts fetching the |request| with the download manager. |
43 void StartRequest(const BackgroundFetchRequestInfo& request) { | 43 void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request) { |
44 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 44 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
45 DCHECK(request_context_); | 45 DCHECK(request_context_); |
| 46 DCHECK(request); |
46 | 47 |
47 DownloadManager* download_manager = | 48 DownloadManager* download_manager = |
48 BrowserContext::GetDownloadManager(browser_context_); | 49 BrowserContext::GetDownloadManager(browser_context_); |
49 DCHECK(download_manager); | 50 DCHECK(download_manager); |
50 | 51 |
51 std::unique_ptr<DownloadUrlParameters> download_parameters( | 52 std::unique_ptr<DownloadUrlParameters> download_parameters( |
52 base::MakeUnique<DownloadUrlParameters>(request.GetURL(), | 53 base::MakeUnique<DownloadUrlParameters>(request->GetURL(), |
53 request_context_.get())); | 54 request_context_.get())); |
54 | 55 |
55 // TODO(peter): The |download_parameters| should be populated with all the | 56 // TODO(peter): The |download_parameters| should be populated with all the |
56 // properties set in the |request|'s ServiceWorkerFetchRequest member. | 57 // properties set in the |request|'s ServiceWorkerFetchRequest member. |
57 | 58 |
58 download_parameters->set_callback(base::Bind( | 59 download_parameters->set_callback(base::Bind(&Core::DidStartRequest, |
59 &Core::DidStartRequest, weak_ptr_factory_.GetWeakPtr(), request)); | 60 weak_ptr_factory_.GetWeakPtr(), |
| 61 std::move(request))); |
60 | 62 |
61 download_manager->DownloadUrl(std::move(download_parameters)); | 63 download_manager->DownloadUrl(std::move(download_parameters)); |
62 } | 64 } |
63 | 65 |
64 // DownloadItem::Observer overrides: | 66 // DownloadItem::Observer overrides: |
65 void OnDownloadUpdated(DownloadItem* item) override { | 67 void OnDownloadUpdated(DownloadItem* item) override { |
66 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 68 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
67 | 69 |
68 auto iter = downloads_.find(item); | 70 auto iter = downloads_.find(item); |
69 DCHECK(iter != downloads_.end()); | 71 DCHECK(iter != downloads_.end()); |
70 | 72 |
71 const BackgroundFetchRequestInfo& request = iter->second; | 73 const scoped_refptr<BackgroundFetchRequestInfo>& request = iter->second; |
72 | 74 |
73 switch (item->GetState()) { | 75 switch (item->GetState()) { |
74 case DownloadItem::DownloadState::COMPLETE: | 76 case DownloadItem::DownloadState::COMPLETE: |
75 // TODO(peter): Populate the responses' information in the |request|. | 77 // TODO(peter): Populate the responses' information in the |request|. |
76 | 78 |
77 item->RemoveObserver(this); | 79 item->RemoveObserver(this); |
78 | 80 |
79 // Inform the host about |host| having completed. | 81 // Inform the host about |host| having completed. |
80 BrowserThread::PostTask( | 82 BrowserThread::PostTask( |
81 BrowserThread::IO, FROM_HERE, | 83 BrowserThread::IO, FROM_HERE, |
(...skipping 24 matching lines...) Expand all Loading... |
106 DCHECK_EQ(downloads_.count(item), 1u); | 108 DCHECK_EQ(downloads_.count(item), 1u); |
107 downloads_.erase(item); | 109 downloads_.erase(item); |
108 | 110 |
109 item->RemoveObserver(this); | 111 item->RemoveObserver(this); |
110 } | 112 } |
111 | 113 |
112 private: | 114 private: |
113 // Called when the download manager has started the given |request|. The | 115 // Called when the download manager has started the given |request|. The |
114 // |download_item| continues to be owned by the download system. The | 116 // |download_item| continues to be owned by the download system. The |
115 // |interrupt_reason| will indicate when a request could not be started. | 117 // |interrupt_reason| will indicate when a request could not be started. |
116 void DidStartRequest(const BackgroundFetchRequestInfo& request, | 118 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, |
117 DownloadItem* download_item, | 119 DownloadItem* download_item, |
118 DownloadInterruptReason interrupt_reason) { | 120 DownloadInterruptReason interrupt_reason) { |
119 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 121 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
120 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); | 122 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); |
121 DCHECK(download_item); | 123 DCHECK(download_item); |
122 | 124 |
123 // TODO(peter): The above two DCHECKs are assumptions our implementation | 125 // TODO(peter): The above two DCHECKs are assumptions our implementation |
124 // currently makes, but are not fit for production. We need to handle such | 126 // currently makes, but are not fit for production. We need to handle such |
125 // failures gracefully. | 127 // failures gracefully. |
126 | 128 |
127 // Register for updates on the download's progress. | 129 // Register for updates on the download's progress. |
128 download_item->AddObserver(this); | 130 download_item->AddObserver(this); |
129 | 131 |
130 // Inform the host about the |request| having started. | 132 // Inform the host about the |request| having started. |
131 BrowserThread::PostTask( | 133 BrowserThread::PostTask( |
132 BrowserThread::IO, FROM_HERE, | 134 BrowserThread::IO, FROM_HERE, |
133 base::Bind(&BackgroundFetchJobController::DidStartRequest, io_parent_, | 135 base::Bind(&BackgroundFetchJobController::DidStartRequest, io_parent_, |
134 request, download_item->GetGuid())); | 136 request, download_item->GetGuid())); |
135 | 137 |
136 // Associate the |download_item| with the |request| so that we can retrieve | 138 // Associate the |download_item| with the |request| so that we can retrieve |
137 // it's information when further updates happen. | 139 // it's information when further updates happen. |
138 downloads_.insert(std::make_pair(download_item, request)); | 140 downloads_.insert(std::make_pair(download_item, std::move(request))); |
139 } | 141 } |
140 | 142 |
141 // Weak reference to the BackgroundFetchJobController instance that owns us. | 143 // Weak reference to the BackgroundFetchJobController instance that owns us. |
142 base::WeakPtr<BackgroundFetchJobController> io_parent_; | 144 base::WeakPtr<BackgroundFetchJobController> io_parent_; |
143 | 145 |
144 // The BrowserContext that owns the JobController, and thereby us. | 146 // The BrowserContext that owns the JobController, and thereby us. |
145 BrowserContext* browser_context_; | 147 BrowserContext* browser_context_; |
146 | 148 |
147 // The URL request context to use when issuing the requests. | 149 // The URL request context to use when issuing the requests. |
148 scoped_refptr<net::URLRequestContextGetter> request_context_; | 150 scoped_refptr<net::URLRequestContextGetter> request_context_; |
149 | 151 |
150 // Map from DownloadItem* to the request info for the in-progress downloads. | 152 // Map from DownloadItem* to the request info for the in-progress downloads. |
151 std::unordered_map<DownloadItem*, BackgroundFetchRequestInfo> downloads_; | 153 std::unordered_map<DownloadItem*, scoped_refptr<BackgroundFetchRequestInfo>> |
| 154 downloads_; |
152 | 155 |
153 base::WeakPtrFactory<Core> weak_ptr_factory_; | 156 base::WeakPtrFactory<Core> weak_ptr_factory_; |
154 | 157 |
155 DISALLOW_COPY_AND_ASSIGN(Core); | 158 DISALLOW_COPY_AND_ASSIGN(Core); |
156 }; | 159 }; |
157 | 160 |
158 BackgroundFetchJobController::BackgroundFetchJobController( | 161 BackgroundFetchJobController::BackgroundFetchJobController( |
159 const BackgroundFetchRegistrationId& registration_id, | 162 const BackgroundFetchRegistrationId& registration_id, |
160 const BackgroundFetchOptions& options, | 163 const BackgroundFetchOptions& options, |
161 BackgroundFetchDataManager* data_manager, | 164 BackgroundFetchDataManager* data_manager, |
(...skipping 12 matching lines...) Expand all Loading... |
174 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), browser_context, | 177 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), browser_context, |
175 std::move(request_context))); | 178 std::move(request_context))); |
176 | 179 |
177 // Get a WeakPtr over which we can talk to the |ui_core_|. | 180 // Get a WeakPtr over which we can talk to the |ui_core_|. |
178 ui_core_ptr_ = ui_core_->GetWeakPtr(); | 181 ui_core_ptr_ = ui_core_->GetWeakPtr(); |
179 } | 182 } |
180 | 183 |
181 BackgroundFetchJobController::~BackgroundFetchJobController() = default; | 184 BackgroundFetchJobController::~BackgroundFetchJobController() = default; |
182 | 185 |
183 void BackgroundFetchJobController::Start( | 186 void BackgroundFetchJobController::Start( |
184 std::vector<BackgroundFetchRequestInfo> initial_requests) { | 187 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { |
185 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
186 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); | 189 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); |
187 DCHECK_EQ(state_, State::INITIALIZED); | 190 DCHECK_EQ(state_, State::INITIALIZED); |
188 | 191 |
189 state_ = State::FETCHING; | 192 state_ = State::FETCHING; |
190 | 193 |
191 for (const BackgroundFetchRequestInfo& request : initial_requests) | 194 for (const auto& request : initial_requests) |
192 StartRequest(request); | 195 StartRequest(request); |
193 } | 196 } |
194 | 197 |
195 void BackgroundFetchJobController::StartRequest( | 198 void BackgroundFetchJobController::StartRequest( |
196 const BackgroundFetchRequestInfo& request) { | 199 scoped_refptr<BackgroundFetchRequestInfo> request) { |
197 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 200 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
198 DCHECK_EQ(state_, State::FETCHING); | 201 DCHECK_EQ(state_, State::FETCHING); |
199 BrowserThread::PostTask( | 202 BrowserThread::PostTask( |
200 BrowserThread::UI, FROM_HERE, | 203 BrowserThread::UI, FROM_HERE, |
201 base::Bind(&Core::StartRequest, ui_core_ptr_, request)); | 204 base::Bind(&Core::StartRequest, ui_core_ptr_, std::move(request))); |
202 } | 205 } |
203 | 206 |
204 void BackgroundFetchJobController::DidStartRequest( | 207 void BackgroundFetchJobController::DidStartRequest( |
205 const BackgroundFetchRequestInfo& request, | 208 scoped_refptr<BackgroundFetchRequestInfo> request, |
206 const std::string& download_guid) { | 209 const std::string& download_guid) { |
207 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 210 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
208 data_manager_->MarkRequestAsStarted(registration_id_, request, download_guid); | 211 data_manager_->MarkRequestAsStarted(registration_id_, request.get(), |
| 212 download_guid); |
209 } | 213 } |
210 | 214 |
211 void BackgroundFetchJobController::DidCompleteRequest( | 215 void BackgroundFetchJobController::DidCompleteRequest( |
212 const BackgroundFetchRequestInfo& request) { | 216 scoped_refptr<BackgroundFetchRequestInfo> request) { |
213 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 217 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
214 | 218 |
215 // The DataManager must acknowledge that it stored the data and that there are | 219 // The DataManager must acknowledge that it stored the data and that there are |
216 // no more pending requests to avoid marking this job as completed too early. | 220 // no more pending requests to avoid marking this job as completed too early. |
217 pending_completed_file_acknowledgements_++; | 221 pending_completed_file_acknowledgements_++; |
218 | 222 |
219 data_manager_->MarkRequestAsCompleteAndGetNextRequest( | 223 data_manager_->MarkRequestAsCompleteAndGetNextRequest( |
220 registration_id_, request, | 224 registration_id_, request.get(), |
221 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, | 225 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, |
222 weak_ptr_factory_.GetWeakPtr())); | 226 weak_ptr_factory_.GetWeakPtr())); |
223 } | 227 } |
224 | 228 |
225 void BackgroundFetchJobController::DidGetNextRequest( | 229 void BackgroundFetchJobController::DidGetNextRequest( |
226 const base::Optional<BackgroundFetchRequestInfo>& request) { | 230 scoped_refptr<BackgroundFetchRequestInfo> request) { |
227 DCHECK_LE(pending_completed_file_acknowledgements_, 1); | 231 DCHECK_LE(pending_completed_file_acknowledgements_, 1); |
228 pending_completed_file_acknowledgements_--; | 232 pending_completed_file_acknowledgements_--; |
229 | 233 |
230 // If a |request| has been given, start downloading the file and bail. | 234 // If a |request| has been given, start downloading the file and bail. |
231 if (request) { | 235 if (request) { |
232 StartRequest(request.value()); | 236 StartRequest(std::move(request)); |
233 return; | 237 return; |
234 } | 238 } |
235 | 239 |
236 // If there are outstanding completed file acknowlegements, bail as well. | 240 // If there are outstanding completed file acknowlegements, bail as well. |
237 if (pending_completed_file_acknowledgements_ > 0) | 241 if (pending_completed_file_acknowledgements_ > 0) |
238 return; | 242 return; |
239 | 243 |
240 state_ = State::COMPLETED; | 244 state_ = State::COMPLETED; |
241 | 245 |
242 // Otherwise the job this controller is responsible for has completed. | 246 // Otherwise the job this controller is responsible for has completed. |
(...skipping 11 matching lines...) Expand all Loading... |
254 | 258 |
255 // TODO(harkness): Abort all in-progress downloads. | 259 // TODO(harkness): Abort all in-progress downloads. |
256 | 260 |
257 state_ = State::ABORTED; | 261 state_ = State::ABORTED; |
258 | 262 |
259 // Inform the owner of the controller about the job having completed. | 263 // Inform the owner of the controller about the job having completed. |
260 std::move(completed_callback_).Run(this); | 264 std::move(completed_callback_).Run(this); |
261 } | 265 } |
262 | 266 |
263 } // namespace content | 267 } // namespace content |
OLD | NEW |