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 <queue> | 8 #include <queue> |
8 | 9 |
9 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
10 #include "content/browser/background_fetch/background_fetch_constants.h" | 11 #include "content/browser/background_fetch/background_fetch_constants.h" |
11 #include "content/browser/background_fetch/background_fetch_context.h" | 12 #include "content/browser/background_fetch/background_fetch_context.h" |
12 #include "content/browser/background_fetch/background_fetch_job_response_data.h" | |
13 #include "content/browser/background_fetch/background_fetch_request_info.h" | 13 #include "content/browser/background_fetch/background_fetch_request_info.h" |
14 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 14 #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
15 #include "content/public/browser/blob_handle.h" | 15 #include "content/public/browser/blob_handle.h" |
16 #include "content/public/browser/browser_context.h" | 16 #include "content/public/browser/browser_context.h" |
17 #include "content/public/browser/download_interrupt_reasons.h" | 17 #include "content/public/browser/download_interrupt_reasons.h" |
18 #include "content/public/browser/download_item.h" | 18 #include "content/public/browser/download_item.h" |
19 | 19 |
20 namespace content { | 20 namespace content { |
21 | 21 |
22 // The Registration Data class encapsulates the data stored for a particular | 22 // The Registration Data class encapsulates the data stored for a particular |
23 // Background Fetch registration. This roughly matches the on-disk format that | 23 // Background Fetch registration. This roughly matches the on-disk format that |
24 // will be adhered to in the future. | 24 // will be adhered to in the future. |
25 class BackgroundFetchDataManager::RegistrationData { | 25 class BackgroundFetchDataManager::RegistrationData { |
26 public: | 26 public: |
27 RegistrationData(const std::vector<ServiceWorkerFetchRequest>& requests, | 27 RegistrationData(const std::vector<ServiceWorkerFetchRequest>& requests, |
28 const BackgroundFetchOptions& options) | 28 const BackgroundFetchOptions& options) |
29 : options_(options) { | 29 : options_(options) { |
30 int request_index = 0; | 30 int request_index = 0; |
31 | 31 |
32 // Convert the given |requests| to BackgroundFetchRequestInfo objects. | 32 // Convert the given |requests| to BackgroundFetchRequestInfo objects. |
33 for (const ServiceWorkerFetchRequest& request : requests) | 33 for (const ServiceWorkerFetchRequest& request : requests) |
34 requests_.emplace(request_index++, request); | 34 pending_requests_.emplace(request_index++, request); |
35 } | 35 } |
36 | 36 |
37 ~RegistrationData() = default; | 37 ~RegistrationData() = default; |
38 | 38 |
39 // Returns whether there are remaining requests on the request queue. | 39 // Returns whether there are remaining requests on the request queue. |
40 bool HasPendingRequests() const { return !requests_.empty(); } | 40 bool HasPendingRequests() const { return !pending_requests_.empty(); } |
41 | 41 |
42 // Consumes a request from the queue that is to be fetched. | 42 // Consumes a request from the queue that is to be fetched. |
43 BackgroundFetchRequestInfo ConsumeRequest() { | 43 BackgroundFetchRequestInfo GetPendingRequest() { |
44 DCHECK(!requests_.empty()); | 44 DCHECK(!pending_requests_.empty()); |
45 | 45 |
46 BackgroundFetchRequestInfo request = requests_.front(); | 46 BackgroundFetchRequestInfo request = pending_requests_.front(); |
47 requests_.pop(); | 47 pending_requests_.pop(); |
48 | |
49 // The |request| is considered to be active now. | |
50 active_requests_.push_back(request); | |
48 | 51 |
49 return request; | 52 return request; |
50 } | 53 } |
51 | 54 |
55 // Marks the |request| as having started with the given |download_guid|. | |
56 // Persistent storage needs to store the association so we can resume fetches | |
57 // after a browser restart, here we just verify that the |request| is active. | |
58 void MarkRequestAsStarted(const BackgroundFetchRequestInfo& request, | |
59 const std::string& download_guid) { | |
60 const auto iter = std::find_if( | |
61 active_requests_.begin(), active_requests_.end(), | |
62 [&request](const BackgroundFetchRequestInfo& active_request) { | |
63 return active_request.request_index() == request.request_index(); | |
64 }); | |
65 | |
66 // The |request| must have been consumed from this RegistrationData. | |
67 DCHECK(iter != active_requests_.end()); | |
68 } | |
69 | |
70 // Marks the |request| as having completed. Verifies that the |request| is | |
71 // currently active and moves it to the |completed_requests_| vector. | |
72 void MarkRequestAsComplete(const BackgroundFetchRequestInfo& request) { | |
harkness
2017/03/29 22:12:33
Maybe add the file_path and received_bytes to this
Peter Beverloo
2017/03/29 22:20:28
We'll need much more information, so I'd like thos
| |
73 const auto iter = std::find_if( | |
74 active_requests_.begin(), active_requests_.end(), | |
75 [&request](const BackgroundFetchRequestInfo& active_request) { | |
76 return active_request.request_index() == request.request_index(); | |
77 }); | |
78 | |
79 // The |request| must have been consumed from this RegistrationData. | |
80 DCHECK(iter != active_requests_.end()); | |
81 | |
82 active_requests_.erase(iter); | |
83 completed_requests_.push_back(request); | |
84 } | |
85 | |
86 // Returns the vector with all completed requests part of this registration. | |
87 const std::vector<BackgroundFetchRequestInfo>& GetCompletedRequests() const { | |
88 return completed_requests_; | |
89 } | |
90 | |
52 private: | 91 private: |
53 std::queue<BackgroundFetchRequestInfo> requests_; | |
54 BackgroundFetchOptions options_; | 92 BackgroundFetchOptions options_; |
55 | 93 |
94 // TODO(peter): BackgroundFetchRequestInfo should be stored in a | |
95 // unique_ptr, owned by the BackgroundFetchJobController. Right now we | |
96 // can't do that as we need to hold on to copies here. | |
97 std::queue<BackgroundFetchRequestInfo> pending_requests_; | |
98 std::vector<BackgroundFetchRequestInfo> active_requests_; | |
99 | |
100 // TODO(peter): Right now it's safe for this to be a vector because we only | |
101 // allow a single parallel request. That stops when we start allowing more. | |
102 static_assert(kMaximumBackgroundFetchParallelRequests == 1, | |
103 "RegistrationData::completed_requests_ assumes no parallelism"); | |
104 | |
105 std::vector<BackgroundFetchRequestInfo> completed_requests_; | |
106 | |
56 DISALLOW_COPY_AND_ASSIGN(RegistrationData); | 107 DISALLOW_COPY_AND_ASSIGN(RegistrationData); |
57 }; | 108 }; |
58 | 109 |
59 BackgroundFetchDataManager::BackgroundFetchDataManager( | 110 BackgroundFetchDataManager::BackgroundFetchDataManager( |
60 BrowserContext* browser_context) | 111 BrowserContext* browser_context) |
61 : browser_context_(browser_context), weak_ptr_factory_(this) { | 112 : weak_ptr_factory_(this) { |
62 DCHECK(browser_context_); | 113 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
114 DCHECK(browser_context); | |
115 | |
116 // Store the blob storage context for the given |browser_context|. | |
117 blob_storage_context_ = | |
118 make_scoped_refptr(ChromeBlobStorageContext::GetFor(browser_context)); | |
119 DCHECK(blob_storage_context_); | |
63 } | 120 } |
64 | 121 |
65 BackgroundFetchDataManager::~BackgroundFetchDataManager() = default; | 122 BackgroundFetchDataManager::~BackgroundFetchDataManager() = default; |
66 | 123 |
67 void BackgroundFetchDataManager::CreateRegistration( | 124 void BackgroundFetchDataManager::CreateRegistration( |
68 const BackgroundFetchRegistrationId& registration_id, | 125 const BackgroundFetchRegistrationId& registration_id, |
69 const std::vector<ServiceWorkerFetchRequest>& requests, | 126 const std::vector<ServiceWorkerFetchRequest>& requests, |
70 const BackgroundFetchOptions& options, | 127 const BackgroundFetchOptions& options, |
71 CreateRegistrationCallback callback) { | 128 CreateRegistrationCallback callback) { |
72 if (registrations_.find(registration_id) != registrations_.end()) { | 129 if (registrations_.find(registration_id) != registrations_.end()) { |
73 std::move(callback).Run(blink::mojom::BackgroundFetchError::DUPLICATED_TAG, | 130 std::move(callback).Run(blink::mojom::BackgroundFetchError::DUPLICATED_TAG, |
74 std::vector<BackgroundFetchRequestInfo>()); | 131 std::vector<BackgroundFetchRequestInfo>()); |
75 return; | 132 return; |
76 } | 133 } |
77 | 134 |
78 std::unique_ptr<RegistrationData> registration_data = | 135 std::unique_ptr<RegistrationData> registration_data = |
79 base::MakeUnique<RegistrationData>(requests, options); | 136 base::MakeUnique<RegistrationData>(requests, options); |
80 | 137 |
81 // Create a vector with the initial requests to feed the Job Controller with. | 138 // Create a vector with the initial requests to feed the Job Controller with. |
82 std::vector<BackgroundFetchRequestInfo> initial_requests; | 139 std::vector<BackgroundFetchRequestInfo> initial_requests; |
83 for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; ++i) { | 140 for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; ++i) { |
84 if (!registration_data->HasPendingRequests()) | 141 if (!registration_data->HasPendingRequests()) |
85 break; | 142 break; |
86 | 143 |
87 initial_requests.push_back(registration_data->ConsumeRequest()); | 144 initial_requests.push_back(registration_data->GetPendingRequest()); |
88 } | 145 } |
89 | 146 |
90 // Store the created |registration_data| so that we can easily access it. | 147 // Store the created |registration_data| so that we can easily access it. |
91 registrations_.insert( | 148 registrations_.insert( |
92 std::make_pair(registration_id, std::move(registration_data))); | 149 std::make_pair(registration_id, std::move(registration_data))); |
93 | 150 |
94 // Inform the |callback| of the newly created registration. | 151 // Inform the |callback| of the newly created registration. |
95 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE, | 152 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE, |
96 std::move(initial_requests)); | 153 std::move(initial_requests)); |
97 } | 154 } |
98 | 155 |
99 void BackgroundFetchDataManager::MarkRequestAsStarted( | 156 void BackgroundFetchDataManager::MarkRequestAsStarted( |
100 const BackgroundFetchRegistrationId& registration_id, | 157 const BackgroundFetchRegistrationId& registration_id, |
101 const BackgroundFetchRequestInfo& request, | 158 const BackgroundFetchRequestInfo& request, |
102 const std::string& download_guid) { | 159 const std::string& download_guid) { |
103 auto iter = registrations_.find(registration_id); | 160 auto iter = registrations_.find(registration_id); |
104 DCHECK(iter != registrations_.end()); | 161 DCHECK(iter != registrations_.end()); |
105 | 162 |
106 // TODO(peter): Associate the |download_guid| with the |request|. | 163 RegistrationData* registration_data = iter->second.get(); |
164 registration_data->MarkRequestAsStarted(request, download_guid); | |
107 } | 165 } |
108 | 166 |
109 void BackgroundFetchDataManager::MarkRequestAsCompleteAndGetNextRequest( | 167 void BackgroundFetchDataManager::MarkRequestAsCompleteAndGetNextRequest( |
110 const BackgroundFetchRegistrationId& registration_id, | 168 const BackgroundFetchRegistrationId& registration_id, |
111 const BackgroundFetchRequestInfo& request, | 169 const BackgroundFetchRequestInfo& request, |
112 NextRequestCallback callback) { | 170 NextRequestCallback callback) { |
113 auto iter = registrations_.find(registration_id); | 171 auto iter = registrations_.find(registration_id); |
114 DCHECK(iter != registrations_.end()); | 172 DCHECK(iter != registrations_.end()); |
115 | 173 |
116 RegistrationData* registration_data = iter->second.get(); | 174 RegistrationData* registration_data = iter->second.get(); |
117 | 175 registration_data->MarkRequestAsComplete(request); |
118 // TODO(peter): Store the |request| with the |registration_data|. | |
119 | 176 |
120 base::Optional<BackgroundFetchRequestInfo> next_request; | 177 base::Optional<BackgroundFetchRequestInfo> next_request; |
121 if (registration_data->HasPendingRequests()) | 178 if (registration_data->HasPendingRequests()) |
122 next_request = registration_data->ConsumeRequest(); | 179 next_request = registration_data->GetPendingRequest(); |
123 | 180 |
124 std::move(callback).Run(next_request); | 181 std::move(callback).Run(next_request); |
125 } | 182 } |
126 | 183 |
184 void BackgroundFetchDataManager::GetSettledFetchesForRegistration( | |
185 const BackgroundFetchRegistrationId& registration_id, | |
186 SettledFetchesCallback callback) { | |
187 auto iter = registrations_.find(registration_id); | |
188 DCHECK(iter != registrations_.end()); | |
189 | |
190 RegistrationData* registration_data = iter->second.get(); | |
191 DCHECK(!registration_data->HasPendingRequests()); | |
192 | |
193 const std::vector<BackgroundFetchRequestInfo>& requests = | |
194 registration_data->GetCompletedRequests(); | |
195 | |
196 std::vector<BackgroundFetchSettledFetch> settled_fetches; | |
197 settled_fetches.reserve(requests.size()); | |
198 | |
199 std::vector<std::unique_ptr<BlobHandle>> blob_handles; | |
200 | |
201 for (const auto& request : requests) { | |
202 BackgroundFetchSettledFetch settled_fetch; | |
203 settled_fetch.request = request.fetch_request(); | |
204 | |
205 settled_fetch.response.url_list.push_back(request.GetURL()); | |
206 // TODO: settled_fetch.response.status_code | |
207 // TODO: settled_fetch.response.status_text | |
208 // TODO: settled_fetch.response.response_type | |
209 // TODO: settled_fetch.response.headers | |
210 | |
211 if (request.received_bytes() > 0) { | |
212 DCHECK(!request.file_path().empty()); | |
213 | |
214 std::unique_ptr<BlobHandle> blob_handle = | |
215 blob_storage_context_->CreateFileBackedBlob( | |
216 request.file_path(), 0 /* offset */, request.received_bytes(), | |
217 base::Time() /* expected_modification_time */); | |
218 | |
219 // TODO(peter): Appropriately handle !blob_handle | |
220 if (blob_handle) { | |
221 settled_fetch.response.blob_uuid = blob_handle->GetUUID(); | |
222 settled_fetch.response.blob_size = request.received_bytes(); | |
223 | |
224 blob_handles.push_back(std::move(blob_handle)); | |
225 } | |
226 } | |
227 | |
228 // TODO: settled_fetch.response.error | |
229 // TODO: settled_fetch.response.response_time | |
230 // TODO: settled_fetch.response.cors_exposed_header_names | |
231 | |
232 settled_fetches.push_back(settled_fetch); | |
233 } | |
234 | |
235 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE, | |
236 std::move(settled_fetches), std::move(blob_handles)); | |
237 } | |
238 | |
127 void BackgroundFetchDataManager::DeleteRegistration( | 239 void BackgroundFetchDataManager::DeleteRegistration( |
128 const BackgroundFetchRegistrationId& registration_id, | 240 const BackgroundFetchRegistrationId& registration_id, |
129 DeleteRegistrationCallback callback) { | 241 DeleteRegistrationCallback callback) { |
130 auto iter = registrations_.find(registration_id); | 242 auto iter = registrations_.find(registration_id); |
131 if (iter == registrations_.end()) { | 243 if (iter == registrations_.end()) { |
132 std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_TAG); | 244 std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_TAG); |
133 return; | 245 return; |
134 } | 246 } |
135 | 247 |
136 registrations_.erase(iter); | 248 registrations_.erase(iter); |
137 | 249 |
138 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); | 250 std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE); |
139 } | 251 } |
140 | 252 |
141 void BackgroundFetchDataManager::WriteJobToStorage( | |
142 std::unique_ptr<BackgroundFetchJobInfo> job_info, | |
143 std::vector<std::unique_ptr<BackgroundFetchRequestInfo>> request_infos) { | |
144 // TODO(harkness): Check for job_guid clash. | |
145 const std::string job_guid = job_info->guid(); | |
146 job_map_[job_guid] = std::move(job_info); | |
147 | |
148 // Make an explicit copy of the original requests | |
149 // TODO(harkness): Replace this with actually writing to storage. | |
150 std::vector<BackgroundFetchRequestInfo> requests; | |
151 for (const auto& request_info : request_infos) { | |
152 requests.emplace_back(*(request_info.get())); | |
153 } | |
154 request_map_[job_guid] = std::move(requests); | |
155 | |
156 // |request_infos| will be destroyed when it leaves scope here. | |
157 } | |
158 | |
159 void BackgroundFetchDataManager::WriteRequestToStorage( | |
160 const std::string& job_guid, | |
161 BackgroundFetchRequestInfo* request_info) { | |
162 std::vector<BackgroundFetchRequestInfo>& request_infos = | |
163 request_map_[job_guid]; | |
164 | |
165 // Copy the updated |request_info| over the in-memory version. | |
166 for (size_t i = 0; i < request_infos.size(); i++) { | |
167 if (request_infos[i].guid() == request_info->guid()) | |
168 request_infos[i] = *request_info; | |
169 } | |
170 } | |
171 | |
172 std::unique_ptr<BackgroundFetchRequestInfo> | |
173 BackgroundFetchDataManager::GetRequestInfo(const std::string& job_guid, | |
174 size_t request_index) { | |
175 // Explicitly create a copy. When this is persisted to StorageWorkerStorage, | |
176 // the request_map_ will not exist. | |
177 auto iter = request_map_.find(job_guid); | |
178 DCHECK(iter != request_map_.end()); | |
179 const std::vector<BackgroundFetchRequestInfo>& request_infos = iter->second; | |
180 | |
181 DCHECK(request_index <= request_infos.size()); | |
182 return base::MakeUnique<BackgroundFetchRequestInfo>( | |
183 request_infos[request_index]); | |
184 } | |
185 | |
186 void BackgroundFetchDataManager::GetJobResponse( | |
187 const std::string& job_guid, | |
188 const BackgroundFetchResponseCompleteCallback& callback) { | |
189 BrowserThread::PostTaskAndReplyWithResult( | |
190 BrowserThread::UI, FROM_HERE, | |
191 base::Bind(&ChromeBlobStorageContext::GetFor, browser_context_), | |
192 base::Bind(&BackgroundFetchDataManager::DidGetBlobStorageContext, | |
193 weak_ptr_factory_.GetWeakPtr(), job_guid, callback)); | |
194 } | |
195 | |
196 void BackgroundFetchDataManager::DidGetBlobStorageContext( | |
197 const std::string& job_guid, | |
198 const BackgroundFetchResponseCompleteCallback& callback, | |
199 ChromeBlobStorageContext* blob_context) { | |
200 DCHECK(blob_context); | |
201 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get(); | |
202 DCHECK(job_info); | |
203 | |
204 // Create a BackgroundFetchJobResponseData object which will aggregate | |
205 // together the response blobs. | |
206 job_info->set_job_response_data( | |
207 base::MakeUnique<BackgroundFetchJobResponseData>(job_info->num_requests(), | |
208 callback)); | |
209 BackgroundFetchJobResponseData* job_response_data = | |
210 job_info->job_response_data(); | |
211 DCHECK(job_response_data); | |
212 | |
213 // Iterate over the requests and create blobs for each response. | |
214 for (size_t request_index = 0; request_index < job_info->num_requests(); | |
215 request_index++) { | |
216 // TODO(harkness): This will need to be asynchronous. | |
217 std::unique_ptr<BackgroundFetchRequestInfo> request_info = | |
218 GetRequestInfo(job_guid, request_index); | |
219 | |
220 // TODO(harkness): Only create a blob response if the request was | |
221 // successful. Otherwise create an error response. | |
222 std::unique_ptr<BlobHandle> blob_handle = | |
223 blob_context->CreateFileBackedBlob( | |
224 request_info->file_path(), 0 /* offset */, | |
225 request_info->received_bytes(), | |
226 base::Time() /* expected_modification_time */); | |
227 | |
228 job_response_data->AddResponse(*request_info.get(), std::move(blob_handle)); | |
229 } | |
230 } | |
231 | |
232 bool BackgroundFetchDataManager::UpdateRequestState( | |
233 const std::string& job_guid, | |
234 const std::string& request_guid, | |
235 DownloadItem::DownloadState state, | |
236 DownloadInterruptReason interrupt_reason) { | |
237 // Find the request and set the state and the interrupt reason. | |
238 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get(); | |
239 DCHECK(job_info); | |
240 BackgroundFetchRequestInfo* request = | |
241 job_info->GetActiveRequest(request_guid); | |
242 DCHECK(request); | |
243 request->set_state(state); | |
244 request->set_interrupt_reason(interrupt_reason); | |
245 | |
246 // If the request is now finished, remove it from the active requests. | |
247 switch (state) { | |
248 case DownloadItem::DownloadState::COMPLETE: | |
249 case DownloadItem::DownloadState::CANCELLED: | |
250 WriteRequestToStorage(job_guid, request); | |
251 job_info->RemoveActiveRequest(request_guid); | |
252 break; | |
253 case DownloadItem::DownloadState::IN_PROGRESS: | |
254 case DownloadItem::DownloadState::INTERRUPTED: | |
255 case DownloadItem::DownloadState::MAX_DOWNLOAD_STATE: | |
256 break; | |
257 } | |
258 | |
259 // Return a boolean indicating whether there are more requests to be | |
260 // processed. | |
261 return job_info->HasRequestsRemaining(); | |
262 } | |
263 | |
264 void BackgroundFetchDataManager::UpdateRequestStorageState( | |
265 const std::string& job_guid, | |
266 const std::string& request_guid, | |
267 const base::FilePath& file_path, | |
268 int64_t received_bytes) { | |
269 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get(); | |
270 DCHECK(job_info); | |
271 BackgroundFetchRequestInfo* request = | |
272 job_info->GetActiveRequest(request_guid); | |
273 DCHECK(request); | |
274 request->set_file_path(file_path); | |
275 request->set_received_bytes(received_bytes); | |
276 } | |
277 | |
278 const BackgroundFetchRequestInfo& | |
279 BackgroundFetchDataManager::GetNextBackgroundFetchRequestInfo( | |
280 const std::string& job_guid) { | |
281 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get(); | |
282 DCHECK(job_info); | |
283 | |
284 // TODO(harkness): This needs to be async when it queries real storage. | |
285 std::unique_ptr<BackgroundFetchRequestInfo> request_info = | |
286 GetRequestInfo(job_guid, job_info->next_request_index()); | |
287 const std::string request_guid = request_info->guid(); | |
288 job_info->AddActiveRequest(std::move(request_info)); | |
289 return *job_info->GetActiveRequest(request_guid); | |
290 } | |
291 | |
292 bool BackgroundFetchDataManager::IsComplete(const std::string& job_guid) const { | |
293 auto iter = job_map_.find(job_guid); | |
294 DCHECK(iter != job_map_.end()); | |
295 return iter->second->IsComplete(); | |
296 } | |
297 | |
298 bool BackgroundFetchDataManager::HasRequestsRemaining( | |
299 const std::string& job_guid) const { | |
300 auto iter = job_map_.find(job_guid); | |
301 DCHECK(iter != job_map_.end()); | |
302 return iter->second->HasRequestsRemaining(); | |
303 } | |
304 | |
305 void BackgroundFetchDataManager::UpdateRequestDownloadGuid( | |
306 const std::string& job_guid, | |
307 const std::string& request_guid, | |
308 const std::string& download_guid) { | |
309 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get(); | |
310 DCHECK(job_info); | |
311 BackgroundFetchRequestInfo* request = | |
312 job_info->GetActiveRequest(request_guid); | |
313 DCHECK(request); | |
314 request->set_download_guid(download_guid); | |
315 } | |
316 | |
317 } // namespace content | 253 } // namespace content |
OLD | NEW |