OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "sync/internal_api/public/attachments/attachment_service_impl.h" | 5 #include "sync/internal_api/public/attachments/attachment_service_impl.h" |
6 | 6 |
| 7 #include <iterator> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
9 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
10 #include "sync/api/attachments/attachment.h" | 12 #include "sync/api/attachments/attachment.h" |
11 #include "sync/api/attachments/fake_attachment_store.h" | 13 #include "sync/api/attachments/fake_attachment_store.h" |
12 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" | 14 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" |
13 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" | 15 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" |
14 | 16 |
15 namespace syncer { | 17 namespace syncer { |
16 | 18 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 scoped_ptr<AttachmentDownloader> attachment_downloader( | 136 scoped_ptr<AttachmentDownloader> attachment_downloader( |
135 new FakeAttachmentDownloader()); | 137 new FakeAttachmentDownloader()); |
136 scoped_ptr<syncer::AttachmentService> attachment_service( | 138 scoped_ptr<syncer::AttachmentService> attachment_service( |
137 new syncer::AttachmentServiceImpl(attachment_store.Pass(), | 139 new syncer::AttachmentServiceImpl(attachment_store.Pass(), |
138 attachment_uploader.Pass(), | 140 attachment_uploader.Pass(), |
139 attachment_downloader.Pass(), | 141 attachment_downloader.Pass(), |
140 NULL)); | 142 NULL)); |
141 return attachment_service.Pass(); | 143 return attachment_service.Pass(); |
142 } | 144 } |
143 | 145 |
| 146 AttachmentStore* AttachmentServiceImpl::GetStore() { |
| 147 return attachment_store_.get(); |
| 148 } |
| 149 |
144 void AttachmentServiceImpl::GetOrDownloadAttachments( | 150 void AttachmentServiceImpl::GetOrDownloadAttachments( |
145 const AttachmentIdList& attachment_ids, | 151 const AttachmentIdList& attachment_ids, |
146 const GetOrDownloadCallback& callback) { | 152 const GetOrDownloadCallback& callback) { |
147 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
148 scoped_refptr<GetOrDownloadState> state( | 154 scoped_refptr<GetOrDownloadState> state( |
149 new GetOrDownloadState(attachment_ids, callback)); | 155 new GetOrDownloadState(attachment_ids, callback)); |
150 attachment_store_->Read(attachment_ids, | 156 attachment_store_->Read(attachment_ids, |
151 base::Bind(&AttachmentServiceImpl::ReadDone, | 157 base::Bind(&AttachmentServiceImpl::ReadDone, |
152 weak_ptr_factory_.GetWeakPtr(), | 158 weak_ptr_factory_.GetWeakPtr(), |
153 state)); | 159 state)); |
154 } | 160 } |
155 | 161 |
156 void AttachmentServiceImpl::DropAttachments( | 162 void AttachmentServiceImpl::DropAttachments( |
157 const AttachmentIdList& attachment_ids, | 163 const AttachmentIdList& attachment_ids, |
158 const DropCallback& callback) { | 164 const DropCallback& callback) { |
159 DCHECK(CalledOnValidThread()); | 165 DCHECK(CalledOnValidThread()); |
160 attachment_store_->Drop(attachment_ids, | 166 attachment_store_->Drop(attachment_ids, |
161 base::Bind(&AttachmentServiceImpl::DropDone, | 167 base::Bind(&AttachmentServiceImpl::DropDone, |
162 weak_ptr_factory_.GetWeakPtr(), | 168 weak_ptr_factory_.GetWeakPtr(), |
163 callback)); | 169 callback)); |
164 } | 170 } |
165 | 171 |
166 void AttachmentServiceImpl::StoreAttachments(const AttachmentList& attachments, | |
167 const StoreCallback& callback) { | |
168 DCHECK(CalledOnValidThread()); | |
169 attachment_store_->Write(attachments, | |
170 base::Bind(&AttachmentServiceImpl::WriteDone, | |
171 weak_ptr_factory_.GetWeakPtr(), | |
172 callback)); | |
173 if (attachment_uploader_.get()) { | |
174 for (AttachmentList::const_iterator iter = attachments.begin(); | |
175 iter != attachments.end(); | |
176 ++iter) { | |
177 attachment_uploader_->UploadAttachment( | |
178 *iter, | |
179 base::Bind(&AttachmentServiceImpl::UploadDone, | |
180 weak_ptr_factory_.GetWeakPtr())); | |
181 } | |
182 } | |
183 } | |
184 | |
185 void AttachmentServiceImpl::ReadDone( | 172 void AttachmentServiceImpl::ReadDone( |
186 const scoped_refptr<GetOrDownloadState>& state, | 173 const scoped_refptr<GetOrDownloadState>& state, |
187 const AttachmentStore::Result& result, | 174 const AttachmentStore::Result& result, |
188 scoped_ptr<AttachmentMap> attachments, | 175 scoped_ptr<AttachmentMap> attachments, |
189 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { | 176 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { |
190 // Add read attachments to result. | 177 // Add read attachments to result. |
191 for (AttachmentMap::const_iterator iter = attachments->begin(); | 178 for (AttachmentMap::const_iterator iter = attachments->begin(); |
192 iter != attachments->end(); | 179 iter != attachments->end(); |
193 ++iter) { | 180 ++iter) { |
194 state->AddAttachment(iter->second); | 181 state->AddAttachment(iter->second); |
(...skipping 24 matching lines...) Expand all Loading... |
219 AttachmentService::DropResult drop_result = | 206 AttachmentService::DropResult drop_result = |
220 AttachmentService::DROP_UNSPECIFIED_ERROR; | 207 AttachmentService::DROP_UNSPECIFIED_ERROR; |
221 if (result == AttachmentStore::SUCCESS) { | 208 if (result == AttachmentStore::SUCCESS) { |
222 drop_result = AttachmentService::DROP_SUCCESS; | 209 drop_result = AttachmentService::DROP_SUCCESS; |
223 } | 210 } |
224 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | 211 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). |
225 base::MessageLoop::current()->PostTask(FROM_HERE, | 212 base::MessageLoop::current()->PostTask(FROM_HERE, |
226 base::Bind(callback, drop_result)); | 213 base::Bind(callback, drop_result)); |
227 } | 214 } |
228 | 215 |
229 void AttachmentServiceImpl::WriteDone(const StoreCallback& callback, | |
230 const AttachmentStore::Result& result) { | |
231 AttachmentService::StoreResult store_result = | |
232 AttachmentService::STORE_UNSPECIFIED_ERROR; | |
233 if (result == AttachmentStore::SUCCESS) { | |
234 store_result = AttachmentService::STORE_SUCCESS; | |
235 } | |
236 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | |
237 base::MessageLoop::current()->PostTask(FROM_HERE, | |
238 base::Bind(callback, store_result)); | |
239 } | |
240 | |
241 void AttachmentServiceImpl::UploadDone( | 216 void AttachmentServiceImpl::UploadDone( |
242 const AttachmentUploader::UploadResult& result, | 217 const AttachmentUploader::UploadResult& result, |
243 const AttachmentId& attachment_id) { | 218 const AttachmentId& attachment_id) { |
| 219 ids_in_queue_.erase(attachment_id); |
244 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. | 220 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. |
245 if (result != AttachmentUploader::UPLOAD_SUCCESS) | 221 if (result != AttachmentUploader::UPLOAD_SUCCESS) |
246 return; | 222 return; |
247 if (delegate_) { | 223 if (delegate_) { |
248 delegate_->OnAttachmentUploaded(attachment_id); | 224 delegate_->OnAttachmentUploaded(attachment_id); |
249 } | 225 } |
250 } | 226 } |
251 | 227 |
252 void AttachmentServiceImpl::DownloadDone( | 228 void AttachmentServiceImpl::DownloadDone( |
253 const scoped_refptr<GetOrDownloadState>& state, | 229 const scoped_refptr<GetOrDownloadState>& state, |
254 const AttachmentId& attachment_id, | 230 const AttachmentId& attachment_id, |
255 const AttachmentDownloader::DownloadResult& result, | 231 const AttachmentDownloader::DownloadResult& result, |
256 scoped_ptr<Attachment> attachment) { | 232 scoped_ptr<Attachment> attachment) { |
257 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { | 233 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { |
258 state->AddAttachment(*attachment.get()); | 234 state->AddAttachment(*attachment.get()); |
259 } else { | 235 } else { |
260 state->AddUnavailableAttachmentId(attachment_id); | 236 state->AddUnavailableAttachmentId(attachment_id); |
261 } | 237 } |
262 } | 238 } |
263 | 239 |
| 240 void AttachmentServiceImpl::UploadAttachments( |
| 241 const AttachmentIdSet& attachment_ids) { |
| 242 DCHECK(CalledOnValidThread()); |
| 243 if (!attachment_uploader_.get()) { |
| 244 return; |
| 245 } |
| 246 |
| 247 // Enqueue the attachment ids that aren't already in the queue. |
| 248 AttachmentIdSet::const_iterator iter = attachment_ids.begin(); |
| 249 AttachmentIdSet::const_iterator end = attachment_ids.end(); |
| 250 for (; iter != end; ++iter) { |
| 251 if (ids_in_queue_.find(*iter) == ids_in_queue_.end()) { |
| 252 queue_.push_back(*iter); |
| 253 ids_in_queue_.insert(*iter); |
| 254 } |
| 255 } |
| 256 |
| 257 ProcessQueuedUploads(); |
| 258 } |
| 259 |
| 260 void AttachmentServiceImpl::ProcessQueuedUploads() { |
| 261 DCHECK(CalledOnValidThread()); |
| 262 // TODO(maniscalco): Don't dequeue them all. Instead, limit the number of |
| 263 // concurrent uploads and apply backoff on failure. |
| 264 while (!queue_.empty()) { |
| 265 const AttachmentId id = queue_.front(); |
| 266 queue_.pop_front(); |
| 267 AttachmentIdList attachment_ids; |
| 268 attachment_ids.push_back(id); |
| 269 attachment_store_->Read( |
| 270 attachment_ids, |
| 271 base::Bind(&AttachmentServiceImpl::ReadDoneNowUpload, |
| 272 weak_ptr_factory_.GetWeakPtr())); |
| 273 } |
| 274 } |
| 275 |
| 276 void AttachmentServiceImpl::ReadDoneNowUpload( |
| 277 const AttachmentStore::Result& result, |
| 278 scoped_ptr<AttachmentMap> attachments, |
| 279 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { |
| 280 DCHECK(CalledOnValidThread()); |
| 281 if (!unavailable_attachment_ids->empty()) { |
| 282 // TODO(maniscalco): We failed to read some attachments. What should we do |
| 283 // now? |
| 284 } |
| 285 |
| 286 AttachmentMap::const_iterator iter = attachments->begin(); |
| 287 AttachmentMap::const_iterator end = attachments->end(); |
| 288 for (; iter != end; ++iter) { |
| 289 attachment_uploader_->UploadAttachment( |
| 290 iter->second, |
| 291 base::Bind(&AttachmentServiceImpl::UploadDone, |
| 292 weak_ptr_factory_.GetWeakPtr())); |
| 293 } |
| 294 } |
| 295 |
264 } // namespace syncer | 296 } // namespace syncer |
OLD | NEW |