| 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 | |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" |
| 10 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 11 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
| 12 #include "sync/api/attachments/attachment.h" | 10 #include "sync/api/attachments/attachment.h" |
| 13 #include "sync/api/attachments/fake_attachment_store.h" | 11 #include "sync/api/attachments/fake_attachment_store.h" |
| 14 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" | 12 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h" |
| 15 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" | 13 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h" |
| 16 | 14 |
| 17 namespace syncer { | 15 namespace syncer { |
| 18 | 16 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 scoped_ptr<AttachmentDownloader> attachment_downloader( | 134 scoped_ptr<AttachmentDownloader> attachment_downloader( |
| 137 new FakeAttachmentDownloader()); | 135 new FakeAttachmentDownloader()); |
| 138 scoped_ptr<syncer::AttachmentService> attachment_service( | 136 scoped_ptr<syncer::AttachmentService> attachment_service( |
| 139 new syncer::AttachmentServiceImpl(attachment_store.Pass(), | 137 new syncer::AttachmentServiceImpl(attachment_store.Pass(), |
| 140 attachment_uploader.Pass(), | 138 attachment_uploader.Pass(), |
| 141 attachment_downloader.Pass(), | 139 attachment_downloader.Pass(), |
| 142 NULL)); | 140 NULL)); |
| 143 return attachment_service.Pass(); | 141 return attachment_service.Pass(); |
| 144 } | 142 } |
| 145 | 143 |
| 146 AttachmentStore* AttachmentServiceImpl::GetStore() { | |
| 147 return attachment_store_.get(); | |
| 148 } | |
| 149 | |
| 150 void AttachmentServiceImpl::GetOrDownloadAttachments( | 144 void AttachmentServiceImpl::GetOrDownloadAttachments( |
| 151 const AttachmentIdList& attachment_ids, | 145 const AttachmentIdList& attachment_ids, |
| 152 const GetOrDownloadCallback& callback) { | 146 const GetOrDownloadCallback& callback) { |
| 153 DCHECK(CalledOnValidThread()); | 147 DCHECK(CalledOnValidThread()); |
| 154 scoped_refptr<GetOrDownloadState> state( | 148 scoped_refptr<GetOrDownloadState> state( |
| 155 new GetOrDownloadState(attachment_ids, callback)); | 149 new GetOrDownloadState(attachment_ids, callback)); |
| 156 attachment_store_->Read(attachment_ids, | 150 attachment_store_->Read(attachment_ids, |
| 157 base::Bind(&AttachmentServiceImpl::ReadDone, | 151 base::Bind(&AttachmentServiceImpl::ReadDone, |
| 158 weak_ptr_factory_.GetWeakPtr(), | 152 weak_ptr_factory_.GetWeakPtr(), |
| 159 state)); | 153 state)); |
| 160 } | 154 } |
| 161 | 155 |
| 162 void AttachmentServiceImpl::DropAttachments( | 156 void AttachmentServiceImpl::DropAttachments( |
| 163 const AttachmentIdList& attachment_ids, | 157 const AttachmentIdList& attachment_ids, |
| 164 const DropCallback& callback) { | 158 const DropCallback& callback) { |
| 165 DCHECK(CalledOnValidThread()); | 159 DCHECK(CalledOnValidThread()); |
| 166 attachment_store_->Drop(attachment_ids, | 160 attachment_store_->Drop(attachment_ids, |
| 167 base::Bind(&AttachmentServiceImpl::DropDone, | 161 base::Bind(&AttachmentServiceImpl::DropDone, |
| 168 weak_ptr_factory_.GetWeakPtr(), | 162 weak_ptr_factory_.GetWeakPtr(), |
| 169 callback)); | 163 callback)); |
| 170 } | 164 } |
| 171 | 165 |
| 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 |
| 172 void AttachmentServiceImpl::ReadDone( | 185 void AttachmentServiceImpl::ReadDone( |
| 173 const scoped_refptr<GetOrDownloadState>& state, | 186 const scoped_refptr<GetOrDownloadState>& state, |
| 174 const AttachmentStore::Result& result, | 187 const AttachmentStore::Result& result, |
| 175 scoped_ptr<AttachmentMap> attachments, | 188 scoped_ptr<AttachmentMap> attachments, |
| 176 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { | 189 scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { |
| 177 // Add read attachments to result. | 190 // Add read attachments to result. |
| 178 for (AttachmentMap::const_iterator iter = attachments->begin(); | 191 for (AttachmentMap::const_iterator iter = attachments->begin(); |
| 179 iter != attachments->end(); | 192 iter != attachments->end(); |
| 180 ++iter) { | 193 ++iter) { |
| 181 state->AddAttachment(iter->second); | 194 state->AddAttachment(iter->second); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 206 AttachmentService::DropResult drop_result = | 219 AttachmentService::DropResult drop_result = |
| 207 AttachmentService::DROP_UNSPECIFIED_ERROR; | 220 AttachmentService::DROP_UNSPECIFIED_ERROR; |
| 208 if (result == AttachmentStore::SUCCESS) { | 221 if (result == AttachmentStore::SUCCESS) { |
| 209 drop_result = AttachmentService::DROP_SUCCESS; | 222 drop_result = AttachmentService::DROP_SUCCESS; |
| 210 } | 223 } |
| 211 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). | 224 // TODO(maniscalco): Deal with case where an error occurred (bug 361251). |
| 212 base::MessageLoop::current()->PostTask(FROM_HERE, | 225 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 213 base::Bind(callback, drop_result)); | 226 base::Bind(callback, drop_result)); |
| 214 } | 227 } |
| 215 | 228 |
| 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 |
| 216 void AttachmentServiceImpl::UploadDone( | 241 void AttachmentServiceImpl::UploadDone( |
| 217 const AttachmentUploader::UploadResult& result, | 242 const AttachmentUploader::UploadResult& result, |
| 218 const AttachmentId& attachment_id) { | 243 const AttachmentId& attachment_id) { |
| 219 ids_in_queue_.erase(attachment_id); | |
| 220 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. | 244 // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. |
| 221 if (result != AttachmentUploader::UPLOAD_SUCCESS) | 245 if (result != AttachmentUploader::UPLOAD_SUCCESS) |
| 222 return; | 246 return; |
| 223 if (delegate_) { | 247 if (delegate_) { |
| 224 delegate_->OnAttachmentUploaded(attachment_id); | 248 delegate_->OnAttachmentUploaded(attachment_id); |
| 225 } | 249 } |
| 226 } | 250 } |
| 227 | 251 |
| 228 void AttachmentServiceImpl::DownloadDone( | 252 void AttachmentServiceImpl::DownloadDone( |
| 229 const scoped_refptr<GetOrDownloadState>& state, | 253 const scoped_refptr<GetOrDownloadState>& state, |
| 230 const AttachmentId& attachment_id, | 254 const AttachmentId& attachment_id, |
| 231 const AttachmentDownloader::DownloadResult& result, | 255 const AttachmentDownloader::DownloadResult& result, |
| 232 scoped_ptr<Attachment> attachment) { | 256 scoped_ptr<Attachment> attachment) { |
| 233 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { | 257 if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) { |
| 234 state->AddAttachment(*attachment.get()); | 258 state->AddAttachment(*attachment.get()); |
| 235 } else { | 259 } else { |
| 236 state->AddUnavailableAttachmentId(attachment_id); | 260 state->AddUnavailableAttachmentId(attachment_id); |
| 237 } | 261 } |
| 238 } | 262 } |
| 239 | 263 |
| 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 | |
| 296 } // namespace syncer | 264 } // namespace syncer |
| OLD | NEW |