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_data_manager.h" | 5 #include "content/browser/background_fetch/background_fetch_data_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <queue> | 8 #include <queue> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 pending_requests_.push(std::move(request)); | 47 pending_requests_.push(std::move(request)); |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 ~RegistrationData() = default; | 51 ~RegistrationData() = default; |
52 | 52 |
53 // Returns whether there are remaining requests on the request queue. | 53 // Returns whether there are remaining requests on the request queue. |
54 bool HasPendingRequests() const { return !pending_requests_.empty(); } | 54 bool HasPendingRequests() const { return !pending_requests_.empty(); } |
55 | 55 |
56 // Consumes a request from the queue that is to be fetched. | 56 // Consumes a request from the queue that is to be fetched. |
57 scoped_refptr<BackgroundFetchRequestInfo> GetPendingRequest() { | 57 scoped_refptr<BackgroundFetchRequestInfo> PopNextPendingRequest() { |
58 DCHECK(!pending_requests_.empty()); | 58 DCHECK(!pending_requests_.empty()); |
59 | 59 |
60 auto request = pending_requests_.front(); | 60 auto request = pending_requests_.front(); |
61 pending_requests_.pop(); | 61 pending_requests_.pop(); |
62 | 62 |
63 // The |request| is considered to be active now. | 63 // The |request| is considered to be active now. |
64 active_requests_.push_back(request); | 64 active_requests_.push_back(request); |
65 | 65 |
66 return request; | 66 return request; |
67 } | 67 } |
68 | 68 |
69 // Marks the |request| as having started with the given |download_guid|. | 69 // Marks the |request| as having started with the given |download_guid|. |
70 // Persistent storage needs to store the association so we can resume fetches | 70 // Persistent storage needs to store the association so we can resume fetches |
71 // after a browser restart, here we just verify that the |request| is active. | 71 // after a browser restart, here we just verify that the |request| is active. |
72 void MarkRequestAsStarted(BackgroundFetchRequestInfo* request, | 72 void MarkRequestAsStarted(BackgroundFetchRequestInfo* request, |
73 const std::string& download_guid) { | 73 const std::string& download_guid) { |
74 const auto iter = std::find_if( | 74 const auto iter = std::find_if( |
75 active_requests_.begin(), active_requests_.end(), | 75 active_requests_.begin(), active_requests_.end(), |
76 [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) { | 76 [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) { |
77 return active_request->request_index() == request->request_index(); | 77 return active_request->request_index() == request->request_index(); |
78 }); | 78 }); |
79 | 79 |
80 // The |request| must have been consumed from this RegistrationData. | 80 // The |request| must have been consumed from this RegistrationData. |
81 DCHECK(iter != active_requests_.end()); | 81 DCHECK(iter != active_requests_.end()); |
82 } | 82 } |
83 | 83 |
84 // Marks the |request| as having completed. Verifies that the |request| is | 84 // Marks the |request| as having completed. Verifies that the |request| is |
85 // currently active and moves it to the |completed_requests_| vector. | 85 // currently active and moves it to the |completed_requests_| vector. |
86 void MarkRequestAsComplete(BackgroundFetchRequestInfo* request) { | 86 bool MarkRequestAsComplete(BackgroundFetchRequestInfo* request) { |
87 const auto iter = std::find_if( | 87 const auto iter = std::find_if( |
88 active_requests_.begin(), active_requests_.end(), | 88 active_requests_.begin(), active_requests_.end(), |
89 [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) { | 89 [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) { |
90 return active_request->request_index() == request->request_index(); | 90 return active_request->request_index() == request->request_index(); |
91 }); | 91 }); |
92 | 92 |
93 // The |request| must have been consumed from this RegistrationData. | 93 // The |request| must have been consumed from this RegistrationData. |
94 DCHECK(iter != active_requests_.end()); | 94 DCHECK(iter != active_requests_.end()); |
95 | 95 |
96 completed_requests_.push_back(*iter); | 96 completed_requests_.push_back(*iter); |
97 active_requests_.erase(iter); | 97 active_requests_.erase(iter); |
| 98 |
| 99 bool has_pending_or_active_requests = |
| 100 !pending_requests_.empty() || !active_requests_.empty(); |
| 101 return has_pending_or_active_requests; |
98 } | 102 } |
99 | 103 |
100 // Returns the vector with all completed requests part of this registration. | 104 // Returns the vector with all completed requests part of this registration. |
101 const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>& | 105 const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>& |
102 GetCompletedRequests() const { | 106 GetCompletedRequests() const { |
103 return completed_requests_; | 107 return completed_requests_; |
104 } | 108 } |
105 | 109 |
106 private: | 110 private: |
107 BackgroundFetchOptions options_; | 111 BackgroundFetchOptions options_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 } | 143 } |
140 | 144 |
141 void BackgroundFetchDataManager::CreateRegistration( | 145 void BackgroundFetchDataManager::CreateRegistration( |
142 const BackgroundFetchRegistrationId& registration_id, | 146 const BackgroundFetchRegistrationId& registration_id, |
143 const std::vector<ServiceWorkerFetchRequest>& requests, | 147 const std::vector<ServiceWorkerFetchRequest>& requests, |
144 const BackgroundFetchOptions& options, | 148 const BackgroundFetchOptions& options, |
145 CreateRegistrationCallback callback) { | 149 CreateRegistrationCallback callback) { |
146 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 150 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
147 | 151 |
148 if (registrations_.find(registration_id) != registrations_.end()) { | 152 if (registrations_.find(registration_id) != registrations_.end()) { |
149 std::move(callback).Run( | 153 std::move(callback).Run(blink::mojom::BackgroundFetchError::DUPLICATED_TAG); |
150 blink::mojom::BackgroundFetchError::DUPLICATED_TAG, | |
151 std::vector<scoped_refptr<BackgroundFetchRequestInfo>>()); | |
152 return; | 154 return; |
153 } | 155 } |
154 | 156 |
155 std::unique_ptr<RegistrationData> registration_data = | 157 // Create the |RegistrationData|, and store it for easy access. |
156 base::MakeUnique<RegistrationData>(requests, options); | 158 registrations_.insert(std::make_pair( |
157 | 159 registration_id, base::MakeUnique<RegistrationData>(requests, options))); |
158 // Create a vector with the initial requests to feed the Job Controller with. | |
159 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests; | |
160 for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; ++i) { | |
161 if (!registration_data->HasPendingRequests()) | |
162 break; | |
163 | |
164 initial_requests.push_back(registration_data->GetPendingRequest()); | |
165 } | |
166 | |
167 // Store the created |registration_data| so that we can easily access it. | |
168 registrations_.insert( | |
169 std::make_pair(registration_id, std::move(registration_data))); | |
170 | 160 |
171 // Inform the |callback| of the newly created registration. | 161 // Inform the |callback| of the newly created registration. |
172 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE, | 162 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); |
173 std::move(initial_requests)); | 163 } |
| 164 |
| 165 void BackgroundFetchDataManager::PopNextRequest( |
| 166 const BackgroundFetchRegistrationId& registration_id, |
| 167 NextRequestCallback callback) { |
| 168 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 169 |
| 170 auto iter = registrations_.find(registration_id); |
| 171 DCHECK(iter != registrations_.end()); |
| 172 |
| 173 RegistrationData* registration_data = iter->second.get(); |
| 174 |
| 175 scoped_refptr<BackgroundFetchRequestInfo> next_request; |
| 176 if (registration_data->HasPendingRequests()) |
| 177 next_request = registration_data->PopNextPendingRequest(); |
| 178 |
| 179 std::move(callback).Run(std::move(next_request)); |
174 } | 180 } |
175 | 181 |
176 void BackgroundFetchDataManager::MarkRequestAsStarted( | 182 void BackgroundFetchDataManager::MarkRequestAsStarted( |
177 const BackgroundFetchRegistrationId& registration_id, | 183 const BackgroundFetchRegistrationId& registration_id, |
178 BackgroundFetchRequestInfo* request, | 184 BackgroundFetchRequestInfo* request, |
179 const std::string& download_guid) { | 185 const std::string& download_guid) { |
180 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 186 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
181 | 187 |
182 auto iter = registrations_.find(registration_id); | 188 auto iter = registrations_.find(registration_id); |
183 DCHECK(iter != registrations_.end()); | 189 DCHECK(iter != registrations_.end()); |
184 | 190 |
185 RegistrationData* registration_data = iter->second.get(); | 191 RegistrationData* registration_data = iter->second.get(); |
186 registration_data->MarkRequestAsStarted(request, download_guid); | 192 registration_data->MarkRequestAsStarted(request, download_guid); |
187 } | 193 } |
188 | 194 |
189 void BackgroundFetchDataManager::MarkRequestAsCompleteAndGetNextRequest( | 195 void BackgroundFetchDataManager::MarkRequestAsComplete( |
190 const BackgroundFetchRegistrationId& registration_id, | 196 const BackgroundFetchRegistrationId& registration_id, |
191 BackgroundFetchRequestInfo* request, | 197 BackgroundFetchRequestInfo* request, |
192 NextRequestCallback callback) { | 198 MarkedCompleteCallback callback) { |
193 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 199 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
194 | 200 |
195 auto iter = registrations_.find(registration_id); | 201 auto iter = registrations_.find(registration_id); |
196 DCHECK(iter != registrations_.end()); | 202 DCHECK(iter != registrations_.end()); |
197 | 203 |
198 RegistrationData* registration_data = iter->second.get(); | 204 RegistrationData* registration_data = iter->second.get(); |
199 registration_data->MarkRequestAsComplete(request); | 205 bool has_pending_or_active_requests = |
| 206 registration_data->MarkRequestAsComplete(request); |
200 | 207 |
201 scoped_refptr<BackgroundFetchRequestInfo> next_request; | 208 std::move(callback).Run(has_pending_or_active_requests); |
202 if (registration_data->HasPendingRequests()) | |
203 next_request = registration_data->GetPendingRequest(); | |
204 | |
205 std::move(callback).Run(std::move(next_request)); | |
206 } | 209 } |
207 | 210 |
208 void BackgroundFetchDataManager::GetSettledFetchesForRegistration( | 211 void BackgroundFetchDataManager::GetSettledFetchesForRegistration( |
209 const BackgroundFetchRegistrationId& registration_id, | 212 const BackgroundFetchRegistrationId& registration_id, |
210 SettledFetchesCallback callback) { | 213 SettledFetchesCallback callback) { |
211 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 214 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
212 | 215 |
213 auto iter = registrations_.find(registration_id); | 216 auto iter = registrations_.find(registration_id); |
214 DCHECK(iter != registrations_.end()); | 217 DCHECK(iter != registrations_.end()); |
215 | 218 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_TAG); | 296 std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_TAG); |
294 return; | 297 return; |
295 } | 298 } |
296 | 299 |
297 registrations_.erase(iter); | 300 registrations_.erase(iter); |
298 | 301 |
299 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); | 302 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); |
300 } | 303 } |
301 | 304 |
302 } // namespace content | 305 } // namespace content |
OLD | NEW |