| 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 "components/sync/model_impl/attachments/attachment_service_impl.h" | 5 #include "components/sync/model_impl/attachments/attachment_service_impl.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "components/sync/engine/attachments/fake_attachment_downloader.h" | 16 #include "components/sync/engine/attachments/fake_attachment_downloader.h" |
| 17 #include "components/sync/engine/attachments/fake_attachment_uploader.h" | 17 #include "components/sync/engine/attachments/fake_attachment_uploader.h" |
| 18 #include "components/sync/model/attachments/attachment.h" | 18 #include "components/sync/model/attachments/attachment.h" |
| 19 | 19 |
| 20 namespace syncer { | 20 namespace syncer { |
| 21 | 21 |
| 22 // GetOrDownloadAttachments starts multiple parallel DownloadAttachment calls. | 22 // GetOrDownloadAttachments starts multiple parallel DownloadAttachment calls. |
| 23 // GetOrDownloadState tracks completion of these calls and posts callback for | 23 // GetOrDownloadState tracks completion of these calls and posts callback for |
| 24 // consumer once all attachments are either retrieved or reported unavailable. | 24 // consumer once all attachments are either retrieved or reported unavailable. |
| 25 class AttachmentServiceImpl::GetOrDownloadState | 25 class AttachmentServiceImpl::GetOrDownloadState |
| 26 : public base::RefCounted<GetOrDownloadState>, | 26 : public base::RefCounted<GetOrDownloadState> { |
| 27 public base::NonThreadSafe { | |
| 28 public: | 27 public: |
| 29 // GetOrDownloadState gets parameter from values passed to | 28 // GetOrDownloadState gets parameter from values passed to |
| 30 // AttachmentService::GetOrDownloadAttachments. | 29 // AttachmentService::GetOrDownloadAttachments. |
| 31 // |attachment_ids| is a list of attachmens to retrieve. | 30 // |attachment_ids| is a list of attachmens to retrieve. |
| 32 // |callback| will be posted on current thread when all attachments retrieved | 31 // |callback| will be posted on current thread when all attachments retrieved |
| 33 // or confirmed unavailable. | 32 // or confirmed unavailable. |
| 34 GetOrDownloadState(const AttachmentIdList& attachment_ids, | 33 GetOrDownloadState(const AttachmentIdList& attachment_ids, |
| 35 const GetOrDownloadCallback& callback); | 34 const GetOrDownloadCallback& callback); |
| 36 | 35 |
| 37 // Attachment was just retrieved. Add it to retrieved attachments. | 36 // Attachment was just retrieved. Add it to retrieved attachments. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 50 void PostResultIfAllRequestsCompleted(); | 49 void PostResultIfAllRequestsCompleted(); |
| 51 | 50 |
| 52 GetOrDownloadCallback callback_; | 51 GetOrDownloadCallback callback_; |
| 53 | 52 |
| 54 // Requests for these attachments are still in progress. | 53 // Requests for these attachments are still in progress. |
| 55 AttachmentIdSet in_progress_attachments_; | 54 AttachmentIdSet in_progress_attachments_; |
| 56 | 55 |
| 57 AttachmentIdSet unavailable_attachments_; | 56 AttachmentIdSet unavailable_attachments_; |
| 58 std::unique_ptr<AttachmentMap> retrieved_attachments_; | 57 std::unique_ptr<AttachmentMap> retrieved_attachments_; |
| 59 | 58 |
| 59 SEQUENCE_CHECKER(sequence_checker_); |
| 60 |
| 60 DISALLOW_COPY_AND_ASSIGN(GetOrDownloadState); | 61 DISALLOW_COPY_AND_ASSIGN(GetOrDownloadState); |
| 61 }; | 62 }; |
| 62 | 63 |
| 63 AttachmentServiceImpl::GetOrDownloadState::GetOrDownloadState( | 64 AttachmentServiceImpl::GetOrDownloadState::GetOrDownloadState( |
| 64 const AttachmentIdList& attachment_ids, | 65 const AttachmentIdList& attachment_ids, |
| 65 const GetOrDownloadCallback& callback) | 66 const GetOrDownloadCallback& callback) |
| 66 : callback_(callback), retrieved_attachments_(new AttachmentMap()) { | 67 : callback_(callback), retrieved_attachments_(new AttachmentMap()) { |
| 67 std::copy( | 68 std::copy( |
| 68 attachment_ids.begin(), attachment_ids.end(), | 69 attachment_ids.begin(), attachment_ids.end(), |
| 69 std::inserter(in_progress_attachments_, in_progress_attachments_.end())); | 70 std::inserter(in_progress_attachments_, in_progress_attachments_.end())); |
| 70 PostResultIfAllRequestsCompleted(); | 71 PostResultIfAllRequestsCompleted(); |
| 71 } | 72 } |
| 72 | 73 |
| 73 AttachmentServiceImpl::GetOrDownloadState::~GetOrDownloadState() { | 74 AttachmentServiceImpl::GetOrDownloadState::~GetOrDownloadState() { |
| 74 DCHECK(CalledOnValidThread()); | 75 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 75 } | 76 } |
| 76 | 77 |
| 77 void AttachmentServiceImpl::GetOrDownloadState::AddAttachment( | 78 void AttachmentServiceImpl::GetOrDownloadState::AddAttachment( |
| 78 const Attachment& attachment) { | 79 const Attachment& attachment) { |
| 79 DCHECK(CalledOnValidThread()); | 80 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 80 DCHECK(retrieved_attachments_->find(attachment.GetId()) == | 81 DCHECK(retrieved_attachments_->find(attachment.GetId()) == |
| 81 retrieved_attachments_->end()); | 82 retrieved_attachments_->end()); |
| 82 retrieved_attachments_->insert( | 83 retrieved_attachments_->insert( |
| 83 std::make_pair(attachment.GetId(), attachment)); | 84 std::make_pair(attachment.GetId(), attachment)); |
| 84 DCHECK(in_progress_attachments_.find(attachment.GetId()) != | 85 DCHECK(in_progress_attachments_.find(attachment.GetId()) != |
| 85 in_progress_attachments_.end()); | 86 in_progress_attachments_.end()); |
| 86 in_progress_attachments_.erase(attachment.GetId()); | 87 in_progress_attachments_.erase(attachment.GetId()); |
| 87 PostResultIfAllRequestsCompleted(); | 88 PostResultIfAllRequestsCompleted(); |
| 88 } | 89 } |
| 89 | 90 |
| 90 void AttachmentServiceImpl::GetOrDownloadState::AddUnavailableAttachmentId( | 91 void AttachmentServiceImpl::GetOrDownloadState::AddUnavailableAttachmentId( |
| 91 const AttachmentId& attachment_id) { | 92 const AttachmentId& attachment_id) { |
| 92 DCHECK(CalledOnValidThread()); | 93 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 93 DCHECK(unavailable_attachments_.find(attachment_id) == | 94 DCHECK(unavailable_attachments_.find(attachment_id) == |
| 94 unavailable_attachments_.end()); | 95 unavailable_attachments_.end()); |
| 95 unavailable_attachments_.insert(attachment_id); | 96 unavailable_attachments_.insert(attachment_id); |
| 96 DCHECK(in_progress_attachments_.find(attachment_id) != | 97 DCHECK(in_progress_attachments_.find(attachment_id) != |
| 97 in_progress_attachments_.end()); | 98 in_progress_attachments_.end()); |
| 98 in_progress_attachments_.erase(attachment_id); | 99 in_progress_attachments_.erase(attachment_id); |
| 99 PostResultIfAllRequestsCompleted(); | 100 PostResultIfAllRequestsCompleted(); |
| 100 } | 101 } |
| 101 | 102 |
| 102 void AttachmentServiceImpl::GetOrDownloadState:: | 103 void AttachmentServiceImpl::GetOrDownloadState:: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 116 std::unique_ptr<AttachmentUploader> attachment_uploader, | 117 std::unique_ptr<AttachmentUploader> attachment_uploader, |
| 117 std::unique_ptr<AttachmentDownloader> attachment_downloader, | 118 std::unique_ptr<AttachmentDownloader> attachment_downloader, |
| 118 Delegate* delegate, | 119 Delegate* delegate, |
| 119 const base::TimeDelta& initial_backoff_delay, | 120 const base::TimeDelta& initial_backoff_delay, |
| 120 const base::TimeDelta& max_backoff_delay) | 121 const base::TimeDelta& max_backoff_delay) |
| 121 : attachment_store_(std::move(attachment_store)), | 122 : attachment_store_(std::move(attachment_store)), |
| 122 attachment_uploader_(std::move(attachment_uploader)), | 123 attachment_uploader_(std::move(attachment_uploader)), |
| 123 attachment_downloader_(std::move(attachment_downloader)), | 124 attachment_downloader_(std::move(attachment_downloader)), |
| 124 delegate_(delegate), | 125 delegate_(delegate), |
| 125 weak_ptr_factory_(this) { | 126 weak_ptr_factory_(this) { |
| 126 DCHECK(CalledOnValidThread()); | 127 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 127 DCHECK(attachment_store_.get()); | 128 DCHECK(attachment_store_.get()); |
| 128 | 129 |
| 129 // TODO(maniscalco): Observe network connectivity change events. When the | 130 // TODO(maniscalco): Observe network connectivity change events. When the |
| 130 // network becomes disconnected, consider suspending queue dispatch. When | 131 // network becomes disconnected, consider suspending queue dispatch. When |
| 131 // connectivity is restored, consider clearing any dispatch backoff (bug | 132 // connectivity is restored, consider clearing any dispatch backoff (bug |
| 132 // 411981). | 133 // 411981). |
| 133 upload_task_queue_ = base::MakeUnique<TaskQueue<AttachmentId>>( | 134 upload_task_queue_ = base::MakeUnique<TaskQueue<AttachmentId>>( |
| 134 base::Bind(&AttachmentServiceImpl::BeginUpload, | 135 base::Bind(&AttachmentServiceImpl::BeginUpload, |
| 135 weak_ptr_factory_.GetWeakPtr()), | 136 weak_ptr_factory_.GetWeakPtr()), |
| 136 initial_backoff_delay, max_backoff_delay); | 137 initial_backoff_delay, max_backoff_delay); |
| 137 | 138 |
| 138 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); | 139 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); |
| 139 } | 140 } |
| 140 | 141 |
| 141 AttachmentServiceImpl::~AttachmentServiceImpl() { | 142 AttachmentServiceImpl::~AttachmentServiceImpl() { |
| 142 DCHECK(CalledOnValidThread()); | 143 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 143 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); | 144 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); |
| 144 } | 145 } |
| 145 | 146 |
| 146 void AttachmentServiceImpl::GetOrDownloadAttachments( | 147 void AttachmentServiceImpl::GetOrDownloadAttachments( |
| 147 const AttachmentIdList& attachment_ids, | 148 const AttachmentIdList& attachment_ids, |
| 148 const GetOrDownloadCallback& callback) { | 149 const GetOrDownloadCallback& callback) { |
| 149 DCHECK(CalledOnValidThread()); | 150 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 150 scoped_refptr<GetOrDownloadState> state( | 151 scoped_refptr<GetOrDownloadState> state( |
| 151 new GetOrDownloadState(attachment_ids, callback)); | 152 new GetOrDownloadState(attachment_ids, callback)); |
| 152 // SetModelTypeReference() makes attachments visible for model type. | 153 // SetModelTypeReference() makes attachments visible for model type. |
| 153 // Needed when attachment doesn't have model type reference, but still | 154 // Needed when attachment doesn't have model type reference, but still |
| 154 // available in local store. | 155 // available in local store. |
| 155 attachment_store_->SetModelTypeReference(attachment_ids); | 156 attachment_store_->SetModelTypeReference(attachment_ids); |
| 156 attachment_store_->Read(attachment_ids, | 157 attachment_store_->Read(attachment_ids, |
| 157 base::Bind(&AttachmentServiceImpl::ReadDone, | 158 base::Bind(&AttachmentServiceImpl::ReadDone, |
| 158 weak_ptr_factory_.GetWeakPtr(), state)); | 159 weak_ptr_factory_.GetWeakPtr(), state)); |
| 159 } | 160 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 case AttachmentStore::UNSPECIFIED_ERROR: | 199 case AttachmentStore::UNSPECIFIED_ERROR: |
| 199 case AttachmentStore::STORE_INITIALIZATION_FAILED: | 200 case AttachmentStore::STORE_INITIALIZATION_FAILED: |
| 200 state->AddUnavailableAttachmentId(attachment.GetId()); | 201 state->AddUnavailableAttachmentId(attachment.GetId()); |
| 201 break; | 202 break; |
| 202 } | 203 } |
| 203 } | 204 } |
| 204 | 205 |
| 205 void AttachmentServiceImpl::UploadDone( | 206 void AttachmentServiceImpl::UploadDone( |
| 206 const AttachmentUploader::UploadResult& result, | 207 const AttachmentUploader::UploadResult& result, |
| 207 const AttachmentId& attachment_id) { | 208 const AttachmentId& attachment_id) { |
| 208 DCHECK(CalledOnValidThread()); | 209 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 209 AttachmentIdList ids; | 210 AttachmentIdList ids; |
| 210 ids.push_back(attachment_id); | 211 ids.push_back(attachment_id); |
| 211 switch (result) { | 212 switch (result) { |
| 212 case AttachmentUploader::UPLOAD_SUCCESS: | 213 case AttachmentUploader::UPLOAD_SUCCESS: |
| 213 attachment_store_->DropSyncReference(ids); | 214 attachment_store_->DropSyncReference(ids); |
| 214 upload_task_queue_->MarkAsSucceeded(attachment_id); | 215 upload_task_queue_->MarkAsSucceeded(attachment_id); |
| 215 if (delegate_) { | 216 if (delegate_) { |
| 216 delegate_->OnAttachmentUploaded(attachment_id); | 217 delegate_->OnAttachmentUploaded(attachment_id); |
| 217 } | 218 } |
| 218 break; | 219 break; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 244 break; | 245 break; |
| 245 } | 246 } |
| 246 case AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR: | 247 case AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR: |
| 247 case AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR: | 248 case AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR: |
| 248 state->AddUnavailableAttachmentId(attachment_id); | 249 state->AddUnavailableAttachmentId(attachment_id); |
| 249 break; | 250 break; |
| 250 } | 251 } |
| 251 } | 252 } |
| 252 | 253 |
| 253 void AttachmentServiceImpl::BeginUpload(const AttachmentId& attachment_id) { | 254 void AttachmentServiceImpl::BeginUpload(const AttachmentId& attachment_id) { |
| 254 DCHECK(CalledOnValidThread()); | 255 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 255 AttachmentIdList attachment_ids; | 256 AttachmentIdList attachment_ids; |
| 256 attachment_ids.push_back(attachment_id); | 257 attachment_ids.push_back(attachment_id); |
| 257 attachment_store_->Read(attachment_ids, | 258 attachment_store_->Read(attachment_ids, |
| 258 base::Bind(&AttachmentServiceImpl::ReadDoneNowUpload, | 259 base::Bind(&AttachmentServiceImpl::ReadDoneNowUpload, |
| 259 weak_ptr_factory_.GetWeakPtr())); | 260 weak_ptr_factory_.GetWeakPtr())); |
| 260 } | 261 } |
| 261 | 262 |
| 262 void AttachmentServiceImpl::UploadAttachments( | 263 void AttachmentServiceImpl::UploadAttachments( |
| 263 const AttachmentIdList& attachment_ids) { | 264 const AttachmentIdList& attachment_ids) { |
| 264 DCHECK(CalledOnValidThread()); | 265 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 265 if (!attachment_uploader_.get()) { | 266 if (!attachment_uploader_.get()) { |
| 266 return; | 267 return; |
| 267 } | 268 } |
| 268 attachment_store_->SetSyncReference(attachment_ids); | 269 attachment_store_->SetSyncReference(attachment_ids); |
| 269 | 270 |
| 270 for (auto iter = attachment_ids.begin(); iter != attachment_ids.end(); | 271 for (auto iter = attachment_ids.begin(); iter != attachment_ids.end(); |
| 271 ++iter) { | 272 ++iter) { |
| 272 upload_task_queue_->AddToQueue(*iter); | 273 upload_task_queue_->AddToQueue(*iter); |
| 273 } | 274 } |
| 274 } | 275 } |
| 275 | 276 |
| 276 void AttachmentServiceImpl::OnNetworkChanged( | 277 void AttachmentServiceImpl::OnNetworkChanged( |
| 277 net::NetworkChangeNotifier::ConnectionType type) { | 278 net::NetworkChangeNotifier::ConnectionType type) { |
| 278 if (type != net::NetworkChangeNotifier::CONNECTION_NONE) { | 279 if (type != net::NetworkChangeNotifier::CONNECTION_NONE) { |
| 279 upload_task_queue_->ResetBackoff(); | 280 upload_task_queue_->ResetBackoff(); |
| 280 } | 281 } |
| 281 } | 282 } |
| 282 | 283 |
| 283 void AttachmentServiceImpl::ReadDoneNowUpload( | 284 void AttachmentServiceImpl::ReadDoneNowUpload( |
| 284 const AttachmentStore::Result& result, | 285 const AttachmentStore::Result& result, |
| 285 std::unique_ptr<AttachmentMap> attachments, | 286 std::unique_ptr<AttachmentMap> attachments, |
| 286 std::unique_ptr<AttachmentIdList> unavailable_attachment_ids) { | 287 std::unique_ptr<AttachmentIdList> unavailable_attachment_ids) { |
| 287 DCHECK(CalledOnValidThread()); | 288 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 288 if (!unavailable_attachment_ids->empty()) { | 289 if (!unavailable_attachment_ids->empty()) { |
| 289 // TODO(maniscalco): We failed to read some attachments. What should we do | 290 // TODO(maniscalco): We failed to read some attachments. What should we do |
| 290 // now? | 291 // now? |
| 291 AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin(); | 292 AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin(); |
| 292 AttachmentIdList::const_iterator end = unavailable_attachment_ids->end(); | 293 AttachmentIdList::const_iterator end = unavailable_attachment_ids->end(); |
| 293 for (; iter != end; ++iter) { | 294 for (; iter != end; ++iter) { |
| 294 upload_task_queue_->Cancel(*iter); | 295 upload_task_queue_->Cancel(*iter); |
| 295 } | 296 } |
| 296 attachment_store_->DropSyncReference(*unavailable_attachment_ids); | 297 attachment_store_->DropSyncReference(*unavailable_attachment_ids); |
| 297 } | 298 } |
| 298 | 299 |
| 299 AttachmentMap::const_iterator iter = attachments->begin(); | 300 AttachmentMap::const_iterator iter = attachments->begin(); |
| 300 AttachmentMap::const_iterator end = attachments->end(); | 301 AttachmentMap::const_iterator end = attachments->end(); |
| 301 for (; iter != end; ++iter) { | 302 for (; iter != end; ++iter) { |
| 302 attachment_uploader_->UploadAttachment( | 303 attachment_uploader_->UploadAttachment( |
| 303 iter->second, base::Bind(&AttachmentServiceImpl::UploadDone, | 304 iter->second, base::Bind(&AttachmentServiceImpl::UploadDone, |
| 304 weak_ptr_factory_.GetWeakPtr())); | 305 weak_ptr_factory_.GetWeakPtr())); |
| 305 } | 306 } |
| 306 } | 307 } |
| 307 | 308 |
| 308 void AttachmentServiceImpl::SetTimerForTest( | 309 void AttachmentServiceImpl::SetTimerForTest( |
| 309 std::unique_ptr<base::Timer> timer) { | 310 std::unique_ptr<base::Timer> timer) { |
| 310 upload_task_queue_->SetTimerForTest(std::move(timer)); | 311 upload_task_queue_->SetTimerForTest(std::move(timer)); |
| 311 } | 312 } |
| 312 | 313 |
| 313 } // namespace syncer | 314 } // namespace syncer |
| OLD | NEW |