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 30 matching lines...) Expand all Loading... |
41 class BackgroundFetchJobController::Core : public DownloadItem::Observer { | 41 class BackgroundFetchJobController::Core : public DownloadItem::Observer { |
42 public: | 42 public: |
43 Core(const base::WeakPtr<BackgroundFetchJobController>& io_parent, | 43 Core(const base::WeakPtr<BackgroundFetchJobController>& io_parent, |
44 const BackgroundFetchRegistrationId& registration_id, | 44 const BackgroundFetchRegistrationId& registration_id, |
45 BrowserContext* browser_context, | 45 BrowserContext* browser_context, |
46 scoped_refptr<net::URLRequestContextGetter> request_context) | 46 scoped_refptr<net::URLRequestContextGetter> request_context) |
47 : io_parent_(io_parent), | 47 : io_parent_(io_parent), |
48 registration_id_(registration_id), | 48 registration_id_(registration_id), |
49 browser_context_(browser_context), | 49 browser_context_(browser_context), |
50 request_context_(std::move(request_context)), | 50 request_context_(std::move(request_context)), |
51 weak_ptr_factory_(this) {} | 51 weak_ptr_factory_(this) { |
| 52 // Although the Core lives only on the UI thread, it is constructed on IO. |
| 53 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 54 } |
52 | 55 |
53 ~Core() final { | 56 ~Core() final { |
| 57 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
54 for (const auto& pair : downloads_) | 58 for (const auto& pair : downloads_) |
55 pair.first->RemoveObserver(this); | 59 pair.first->RemoveObserver(this); |
56 } | 60 } |
57 | 61 |
58 // Returns a weak pointer that can be used to talk to |this|. | 62 // Returns a weak pointer that can be used to talk to |this|. Must only be |
59 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } | 63 // called on the UI thread, unless the Core is guaranteed not to be destroyed |
| 64 // in parallel with this call. |
| 65 base::WeakPtr<Core> GetWeakPtrOnUI() { |
| 66 return weak_ptr_factory_.GetWeakPtr(); |
| 67 } |
60 | 68 |
61 // Starts fetching the |request| with the download manager. | 69 // Starts fetching the |request| with the download manager. |
62 void StartRequest( | 70 void StartRequest( |
63 scoped_refptr<BackgroundFetchRequestInfo> request, | 71 scoped_refptr<BackgroundFetchRequestInfo> request, |
64 const net::NetworkTrafficAnnotationTag& traffic_annotation) { | 72 const net::NetworkTrafficAnnotationTag& traffic_annotation) { |
65 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 73 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
66 DCHECK(request_context_); | 74 DCHECK(request_context_); |
67 DCHECK(request); | 75 DCHECK(request); |
68 | 76 |
69 DownloadManager* download_manager = | 77 DownloadManager* download_manager = |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 void OnDownloadUpdated(DownloadItem* download_item) override { | 125 void OnDownloadUpdated(DownloadItem* download_item) override { |
118 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 126 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
119 | 127 |
120 auto iter = downloads_.find(download_item); | 128 auto iter = downloads_.find(download_item); |
121 DCHECK(iter != downloads_.end()); | 129 DCHECK(iter != downloads_.end()); |
122 | 130 |
123 scoped_refptr<BackgroundFetchRequestInfo> request = iter->second; | 131 scoped_refptr<BackgroundFetchRequestInfo> request = iter->second; |
124 | 132 |
125 switch (download_item->GetState()) { | 133 switch (download_item->GetState()) { |
126 case DownloadItem::DownloadState::COMPLETE: | 134 case DownloadItem::DownloadState::COMPLETE: |
127 request->PopulateResponseFromDownloadItem(download_item); | 135 request->PopulateResponseFromDownloadItemOnUI(download_item); |
| 136 BrowserThread::PostTask( |
| 137 BrowserThread::IO, FROM_HERE, |
| 138 base::Bind(&BackgroundFetchRequestInfo::SetResponseDataPopulated, |
| 139 request)); |
128 download_item->RemoveObserver(this); | 140 download_item->RemoveObserver(this); |
129 | 141 |
130 // Inform the host about |host| having completed. | 142 // Inform the host about |host| having completed. |
131 BrowserThread::PostTask( | 143 BrowserThread::PostTask( |
132 BrowserThread::IO, FROM_HERE, | 144 BrowserThread::IO, FROM_HERE, |
133 base::Bind(&BackgroundFetchJobController::DidCompleteRequest, | 145 base::Bind(&BackgroundFetchJobController::DidCompleteRequest, |
134 io_parent_, std::move(request))); | 146 io_parent_, std::move(request))); |
135 | 147 |
136 // Clear the local state for the |request|, it no longer is our concern. | 148 // Clear the local state for the |request|, it no longer is our concern. |
137 downloads_.erase(iter); | 149 downloads_.erase(iter); |
(...skipping 26 matching lines...) Expand all Loading... |
164 // Called when the download manager has started the given |request|. The | 176 // Called when the download manager has started the given |request|. The |
165 // |download_item| continues to be owned by the download system. The | 177 // |download_item| continues to be owned by the download system. The |
166 // |interrupt_reason| will indicate when a request could not be started. | 178 // |interrupt_reason| will indicate when a request could not be started. |
167 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, | 179 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, |
168 DownloadItem* download_item, | 180 DownloadItem* download_item, |
169 DownloadInterruptReason interrupt_reason) { | 181 DownloadInterruptReason interrupt_reason) { |
170 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 182 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
171 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); | 183 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); |
172 DCHECK(download_item); | 184 DCHECK(download_item); |
173 | 185 |
174 request->PopulateDownloadState(download_item, interrupt_reason); | 186 request->PopulateDownloadStateOnUI(download_item, interrupt_reason); |
| 187 BrowserThread::PostTask( |
| 188 BrowserThread::IO, FROM_HERE, |
| 189 base::Bind(&BackgroundFetchRequestInfo::SetDownloadStatePopulated, |
| 190 request)); |
175 | 191 |
176 // TODO(peter): The above two DCHECKs are assumptions our implementation | 192 // TODO(peter): The above two DCHECKs are assumptions our implementation |
177 // currently makes, but are not fit for production. We need to handle such | 193 // currently makes, but are not fit for production. We need to handle such |
178 // failures gracefully. | 194 // failures gracefully. |
179 | 195 |
180 // Register for updates on the download's progress. | 196 // Register for updates on the download's progress. |
181 download_item->AddObserver(this); | 197 download_item->AddObserver(this); |
182 | 198 |
183 // Inform the host about the |request| having started. | 199 // Inform the host about the |request| having started. |
184 BrowserThread::PostTask( | 200 BrowserThread::PostTask( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 completed_callback_(std::move(completed_callback)), | 242 completed_callback_(std::move(completed_callback)), |
227 traffic_annotation_(traffic_annotation), | 243 traffic_annotation_(traffic_annotation), |
228 weak_ptr_factory_(this) { | 244 weak_ptr_factory_(this) { |
229 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 245 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
230 | 246 |
231 // Create the core, containing the internal functionality that will have to | 247 // Create the core, containing the internal functionality that will have to |
232 // be run on the UI thread. It will respond to this class with a weak pointer. | 248 // be run on the UI thread. It will respond to this class with a weak pointer. |
233 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), registration_id, | 249 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), registration_id, |
234 browser_context, std::move(request_context))); | 250 browser_context, std::move(request_context))); |
235 | 251 |
236 // Get a WeakPtr over which we can talk to the |ui_core_|. | 252 // Get a WeakPtr over which we can talk to the |ui_core_|. Normally it would |
237 ui_core_ptr_ = ui_core_->GetWeakPtr(); | 253 // be unsafe to obtain a weak pointer on the IO thread from a factory that |
| 254 // lives on the UI thread, but it's ok in this constructor since the Core |
| 255 // can't be destroyed before this constructor finishes. |
| 256 ui_core_ptr_ = ui_core_->GetWeakPtrOnUI(); |
238 } | 257 } |
239 | 258 |
240 BackgroundFetchJobController::~BackgroundFetchJobController() = default; | 259 BackgroundFetchJobController::~BackgroundFetchJobController() { |
| 260 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 261 }; |
241 | 262 |
242 void BackgroundFetchJobController::Start( | 263 void BackgroundFetchJobController::Start( |
243 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { | 264 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { |
244 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
245 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); | 266 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); |
246 DCHECK_EQ(state_, State::INITIALIZED); | 267 DCHECK_EQ(state_, State::INITIALIZED); |
247 | 268 |
248 state_ = State::FETCHING; | 269 state_ = State::FETCHING; |
249 | 270 |
250 for (const auto& request : initial_requests) | 271 for (const auto& request : initial_requests) |
(...skipping 26 matching lines...) Expand all Loading... |
277 pending_completed_file_acknowledgements_++; | 298 pending_completed_file_acknowledgements_++; |
278 | 299 |
279 data_manager_->MarkRequestAsCompleteAndGetNextRequest( | 300 data_manager_->MarkRequestAsCompleteAndGetNextRequest( |
280 registration_id_, request.get(), | 301 registration_id_, request.get(), |
281 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, | 302 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, |
282 weak_ptr_factory_.GetWeakPtr())); | 303 weak_ptr_factory_.GetWeakPtr())); |
283 } | 304 } |
284 | 305 |
285 void BackgroundFetchJobController::DidGetNextRequest( | 306 void BackgroundFetchJobController::DidGetNextRequest( |
286 scoped_refptr<BackgroundFetchRequestInfo> request) { | 307 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 308 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
287 DCHECK_LE(pending_completed_file_acknowledgements_, 1); | 309 DCHECK_LE(pending_completed_file_acknowledgements_, 1); |
288 pending_completed_file_acknowledgements_--; | 310 pending_completed_file_acknowledgements_--; |
289 | 311 |
290 // If a |request| has been given, start downloading the file and bail. | 312 // If a |request| has been given, start downloading the file and bail. |
291 if (request) { | 313 if (request) { |
292 StartRequest(std::move(request)); | 314 StartRequest(std::move(request)); |
293 return; | 315 return; |
294 } | 316 } |
295 | 317 |
296 // If there are outstanding completed file acknowlegements, bail as well. | 318 // If there are outstanding completed file acknowlegements, bail as well. |
(...skipping 17 matching lines...) Expand all Loading... |
314 | 336 |
315 // TODO(harkness): Abort all in-progress downloads. | 337 // TODO(harkness): Abort all in-progress downloads. |
316 | 338 |
317 state_ = State::ABORTED; | 339 state_ = State::ABORTED; |
318 | 340 |
319 // Inform the owner of the controller about the job having completed. | 341 // Inform the owner of the controller about the job having completed. |
320 std::move(completed_callback_).Run(this); | 342 std::move(completed_callback_).Run(this); |
321 } | 343 } |
322 | 344 |
323 } // namespace content | 345 } // namespace content |
OLD | NEW |