Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: content/browser/background_fetch/background_fetch_data_manager.cc

Issue 2767373002: Implement GetJobResponse and merge JobData into DataManager. (Closed)
Patch Set: cleanup Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "content/browser/background_fetch/background_fetch_context.h" 8 #include "content/browser/background_fetch/background_fetch_context.h"
9 #include "content/browser/background_fetch/background_fetch_job_response_data.h"
9 #include "content/browser/background_fetch/background_fetch_request_info.h" 10 #include "content/browser/background_fetch/background_fetch_request_info.h"
11 #include "content/public/browser/blob_handle.h"
12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/download_interrupt_reasons.h"
14 #include "content/public/browser/download_item.h"
10 15
11 namespace content { 16 namespace content {
12 17
13 BackgroundFetchDataManager::BackgroundFetchDataManager( 18 BackgroundFetchDataManager::BackgroundFetchDataManager(
14 BackgroundFetchContext* background_fetch_context) 19 BrowserContext* browser_context)
15 : background_fetch_context_(background_fetch_context) { 20 : browser_context_(browser_context), weak_ptr_factory_(this) {
16 DCHECK(background_fetch_context_); 21 DCHECK(browser_context_);
17 // TODO(harkness) Read from persistent storage and recreate requests. 22 // TODO(harkness) Read from persistent storage and recreate requests.
18 } 23 }
19 24
20 BackgroundFetchDataManager::~BackgroundFetchDataManager() = default; 25 BackgroundFetchDataManager::~BackgroundFetchDataManager() = default;
21 26
22 std::unique_ptr<BackgroundFetchJobData> 27 void BackgroundFetchDataManager::CreateRequest(
23 BackgroundFetchDataManager::CreateRequest(
24 std::unique_ptr<BackgroundFetchJobInfo> job_info, 28 std::unique_ptr<BackgroundFetchJobInfo> job_info,
25 BackgroundFetchRequestInfos request_infos) { 29 BackgroundFetchRequestInfos request_infos) {
26 JobIdentifier id(job_info->service_worker_registration_id(), job_info->tag()); 30 JobIdentifier id(job_info->service_worker_registration_id(), job_info->tag());
27 // Ensure that this is not a duplicate request. 31 // Ensure that this is not a duplicate request.
28 if (service_worker_tag_map_.find(id) != service_worker_tag_map_.end()) { 32 if (service_worker_tag_map_.find(id) != service_worker_tag_map_.end()) {
29 DVLOG(1) << "Origin " << job_info->origin() 33 DVLOG(1) << "Origin " << job_info->origin()
30 << " has already created a batch request with tag " 34 << " has already created a batch request with tag "
31 << job_info->tag(); 35 << job_info->tag();
32 // TODO(harkness) Figure out how to return errors like this. 36 // TODO(harkness) Figure out how to return errors like this.
33 return nullptr; 37 return;
34 } 38 }
35 39
36 // Add the request to our maps and return a JobData to track the individual 40 // Add the JobInfo to the in-memory map, and write the individual requests out
37 // files in the request. 41 // to storage.
42 job_info->set_num_requests(request_infos.size());
38 const std::string job_guid = job_info->guid(); 43 const std::string job_guid = job_info->guid();
39 service_worker_tag_map_[id] = job_guid; 44 service_worker_tag_map_[id] = job_guid;
40 WriteJobToStorage(std::move(job_info), std::move(request_infos)); 45 WriteJobToStorage(std::move(job_info), std::move(request_infos));
41 // TODO(harkness): Remove data when the job is complete.
42
43 return base::MakeUnique<BackgroundFetchJobData>(
44 ReadRequestsFromStorage(job_guid));
45 } 46 }
46 47
47 void BackgroundFetchDataManager::WriteJobToStorage( 48 void BackgroundFetchDataManager::WriteJobToStorage(
48 std::unique_ptr<BackgroundFetchJobInfo> job_info, 49 std::unique_ptr<BackgroundFetchJobInfo> job_info,
49 BackgroundFetchRequestInfos request_infos) { 50 BackgroundFetchRequestInfos request_infos) {
50 // TODO(harkness): Replace these maps with actually writing to storage.
51 // TODO(harkness): Check for job_guid clash. 51 // TODO(harkness): Check for job_guid clash.
52 const std::string job_guid = job_info->guid(); 52 const std::string job_guid = job_info->guid();
53 job_map_[job_guid] = std::move(job_info); 53 job_map_[job_guid] = std::move(job_info);
54 request_map_[job_guid] = std::move(request_infos); 54
55 // Make an explicit copy of the original requests
56 // TODO(harkness): Replace this with actually writing to storage.
57 std::vector<BackgroundFetchRequestInfo> requests;
58 for (const auto& request_info : request_infos) {
59 requests.emplace_back(*(request_info.get()));
60 }
61 request_map_[job_guid] = std::move(requests);
62
63 // |request_infos| will be destroyed when it leaves scope here.
55 } 64 }
56 65
57 // TODO(harkness): This should be changed to read (and cache) small numbers of 66 void BackgroundFetchDataManager::WriteRequestToStorage(
58 // the RequestInfos instead of returning all of them. 67 const std::string& job_guid,
59 BackgroundFetchRequestInfos& 68 BackgroundFetchRequestInfo* request_info) {
60 BackgroundFetchDataManager::ReadRequestsFromStorage( 69 std::vector<BackgroundFetchRequestInfo>& request_infos =
70 request_map_[job_guid];
71
72 // Copy the updated |request_info| over the in-memory version.
73 for (size_t i = 0; i < request_infos.size(); i++) {
74 if (request_infos[i].guid() == request_info->guid())
75 request_infos[i] = *request_info;
76 }
77 }
78
79 std::unique_ptr<BackgroundFetchRequestInfo>
80 BackgroundFetchDataManager::GetRequestInfo(const std::string& job_guid,
81 size_t request_index) const {
82 // Explicitly create a copy. When this is persisted to StorageWorkerStorage,
83 // the request_map_ will not exist.
84 auto iter = request_map_.find(job_guid);
85 DCHECK(iter != request_map_.end());
86 const std::vector<BackgroundFetchRequestInfo>& request_infos = iter->second;
87
88 DCHECK(request_index <= request_infos.size());
89 BackgroundFetchRequestInfo request_info =
90 *(request_infos.begin() + request_index);
Peter Beverloo 2017/03/25 03:38:50 Why wouldn't request_infos[request_index] work?
harkness 2017/03/26 16:13:18 I could do that, but then the method couldn't be c
Peter Beverloo 2017/03/26 22:32:39 This can't be const anyway - conceptually it could
harkness 2017/03/27 07:32:37 Changed.
91 return base::MakeUnique<BackgroundFetchRequestInfo>(request_info);
92 }
93
94 void BackgroundFetchDataManager::GetJobResponse(
95 const std::string& job_guid,
96 const BackgroundFetchResponseCompleteCallback& callback) {
97 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
98 DCHECK(job_info);
99
100 // Create a BackgroundFetchJobResponseData object which will aggregate
101 // together the response blobs.
102 job_info->set_job_response_data(
103 base::MakeUnique<BackgroundFetchJobResponseData>(job_info->num_requests(),
104 std::move(callback)));
Peter Beverloo 2017/03/25 03:38:50 This std::move() doesn't do anything because |call
harkness 2017/03/26 16:13:18 Done.
105
106 // Iterate over the requests and create blobs for each response.
107 for (size_t request_index = 0; request_index < job_info->num_requests();
108 request_index++) {
109 // TODO(harkness): This will need to be asynchronous.
110 std::unique_ptr<BackgroundFetchRequestInfo> request_info =
111 GetRequestInfo(job_guid, request_index);
112
113 // TODO(harkness): Only create a blob response if the request was
114 // successful. Otherwise create an error response.
115 content::BrowserContext::CreateFileBackedBlob(
Peter Beverloo 2017/03/25 03:38:50 That method only exists to bridge UI thread calls
harkness 2017/03/26 16:13:18 Won't the DataManager need access to the browser c
Peter Beverloo 2017/03/26 22:32:39 We'd give it the ServiceWorkerContextWrapper inste
harkness 2017/03/27 07:32:37 Fair enough.
116 browser_context_, request_info->file_path(), 0 /* offset */,
117 request_info->received_bytes(),
118 base::Time() /* expected_modification_time */,
119 base::Bind(&BackgroundFetchDataManager::DidGetRequestResponse,
120 weak_ptr_factory_.GetWeakPtr(), job_guid, request_index));
121 }
122 }
123
124 void BackgroundFetchDataManager::DidGetRequestResponse(
125 const std::string& job_guid,
126 int request_sequence_number,
127 std::unique_ptr<BlobHandle> blob_handle) {
128 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
129 DCHECK(job_info);
130
131 BackgroundFetchJobResponseData* job_response_data =
132 job_info->job_response_data();
133 DCHECK(job_response_data);
134
135 job_response_data->AddResponse(request_sequence_number,
136 std::move(blob_handle));
137 }
138
139 bool BackgroundFetchDataManager::UpdateRequestState(
140 const std::string& job_guid,
141 const std::string& request_guid,
142 DownloadItem::DownloadState state,
143 DownloadInterruptReason interrupt_reason) {
144 // Find the request and set the state and the interrupt reason.
145 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
146 DCHECK(job_info);
Peter Beverloo 2017/03/25 03:38:50 This is the sort of error condition that we'll hav
harkness 2017/03/26 16:13:18 The only way I could see this being hit would be i
147 BackgroundFetchRequestInfo* request =
148 job_info->GetActiveRequest(request_guid);
149 DCHECK(request);
150 request->set_state(state);
151 request->set_interrupt_reason(interrupt_reason);
152
153 // If the request is now finished, remove it from the active requests.
154 switch (state) {
155 case DownloadItem::DownloadState::COMPLETE:
156 case DownloadItem::DownloadState::CANCELLED:
157 WriteRequestToStorage(job_guid, request);
158 job_info->RemoveActiveRequest(request_guid);
159 case DownloadItem::DownloadState::IN_PROGRESS:
160 case DownloadItem::DownloadState::INTERRUPTED:
161 case DownloadItem::DownloadState::MAX_DOWNLOAD_STATE:
162 break;
163 }
164
165 // Return a boolean indicating whether there are more requests to be
166 // processed.
167 return job_info->HasRequestsRemaining();
168 }
169
170 void BackgroundFetchDataManager::UpdateRequestStorageState(
171 const std::string& job_guid,
172 const std::string& request_guid,
173 const base::FilePath& file_path,
174 int64_t received_bytes) {
175 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
176 DCHECK(job_info);
177 BackgroundFetchRequestInfo* request =
178 job_info->GetActiveRequest(request_guid);
179 DCHECK(request);
180 request->set_file_path(file_path);
181 request->set_received_bytes(received_bytes);
182 }
183
184 const BackgroundFetchRequestInfo&
185 BackgroundFetchDataManager::GetNextBackgroundFetchRequestInfo(
61 const std::string& job_guid) { 186 const std::string& job_guid) {
62 return request_map_[job_guid]; 187 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
188 DCHECK(job_info);
189
190 // TODO(harkness): This needs to be async when it queries real storage.
191 std::unique_ptr<BackgroundFetchRequestInfo> request_info =
192 GetRequestInfo(job_guid, job_info->next_request_index());
193 const std::string request_guid = request_info->guid();
194 job_info->AddActiveRequest(std::move(request_info));
195 return *job_info->GetActiveRequest(request_guid);
196 }
197
198 bool BackgroundFetchDataManager::IsComplete(const std::string& job_guid) const {
199 auto iter = job_map_.find(job_guid);
200 DCHECK(iter != job_map_.end());
201 return iter->second->IsComplete();
202 }
203
204 bool BackgroundFetchDataManager::HasRequestsRemaining(
205 const std::string& job_guid) const {
206 auto iter = job_map_.find(job_guid);
207 DCHECK(iter != job_map_.end());
208 return iter->second->HasRequestsRemaining();
209 }
210
211 void BackgroundFetchDataManager::UpdateRequestDownloadGuid(
212 const std::string& job_guid,
213 const std::string& request_guid,
214 const std::string& download_guid) {
Peter Beverloo 2017/03/25 03:38:50 I'd love to simplify the data model away from GUID
harkness 2017/03/26 16:13:18 I do hate that we have to have the download_guid a
Peter Beverloo 2017/03/26 22:32:39 Good!
harkness 2017/03/27 07:32:38 All the knowledge now on the JobInfo are things th
215 BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
216 DCHECK(job_info);
217 BackgroundFetchRequestInfo* request =
218 job_info->GetActiveRequest(request_guid);
219 DCHECK(request);
220 request->set_download_guid(download_guid);
63 } 221 }
64 222
65 } // namespace content 223 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698