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

Unified Diff: sync/api/attachments/attachment_service_impl.cc

Issue 307783002: Instantiate AttachmentDownloader and use it in AttachmentServiceImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix components unittest Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: sync/api/attachments/attachment_service_impl.cc
diff --git a/sync/api/attachments/attachment_service_impl.cc b/sync/api/attachments/attachment_service_impl.cc
index af2dea7ccc60fa3d7955d21281e456760da7f11d..45134952e557db4fd5f02dfabd04f668bcadf7ca 100644
--- a/sync/api/attachments/attachment_service_impl.cc
+++ b/sync/api/attachments/attachment_service_impl.cc
@@ -7,17 +7,113 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "sync/api/attachments/attachment.h"
+#include "sync/internal_api/public/attachments/fake_attachment_downloader.h"
#include "sync/internal_api/public/attachments/fake_attachment_store.h"
#include "sync/internal_api/public/attachments/fake_attachment_uploader.h"
namespace syncer {
+// GetOrDownloadAttachments starts multiple parallel DownloadAttachment calls.
+// GetOrDownloadState tracks completion of these calls and posts callback for
+// consumer once all attachments are either retrieved or reported unavailable.
+class AttachmentServiceImpl::GetOrDownloadState
+ : public base::RefCounted<GetOrDownloadState>,
+ public base::NonThreadSafe {
+ public:
+ // GetOrDownloadState gets parameter from values passed to
+ // AttachmentService::GetOrDownloadAttachments.
+ // |attachment_ids| is a list of attachmens to retrieve.
+ // |callback| will be posted on current thread when all attachments retrieved
+ // or confirmed unavailable.
+ GetOrDownloadState(const AttachmentIdList& attachment_ids,
+ const GetOrDownloadCallback& callback);
+
+ // Attachment was just retrieved. Add it to retrieved attachments.
+ void AddAttachment(const Attachment& attachment);
+
+ // Both reading from local store and downloading attachment failed.
+ // Add it to unavailable set.
+ void AddUnavailableAttachmentId(const AttachmentId& attachment_id);
+
+ private:
+ friend class base::RefCounted<GetOrDownloadState>;
+ virtual ~GetOrDownloadState();
+
+ // If all attachment requests completed then post callback to consumer with
+ // results.
+ void PostResultIfAllRequestsCompleted();
+
+ GetOrDownloadCallback callback_;
+
+ // Requests for these attachments are still in progress.
+ AttachmentIdSet in_progress_attachments_;
+
+ AttachmentIdSet unavailable_attachments_;
+ scoped_ptr<AttachmentMap> retrieved_attachments_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetOrDownloadState);
+};
+
+AttachmentServiceImpl::GetOrDownloadState::GetOrDownloadState(
+ const AttachmentIdList& attachment_ids,
+ const GetOrDownloadCallback& callback)
+ : callback_(callback), retrieved_attachments_(new AttachmentMap()) {
+ std::copy(
+ attachment_ids.begin(),
+ attachment_ids.end(),
+ std::inserter(in_progress_attachments_, in_progress_attachments_.end()));
+ PostResultIfAllRequestsCompleted();
+}
+
+AttachmentServiceImpl::GetOrDownloadState::~GetOrDownloadState() {
+ DCHECK(CalledOnValidThread());
+}
+
+void AttachmentServiceImpl::GetOrDownloadState::AddAttachment(
+ const Attachment& attachment) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(retrieved_attachments_->find(attachment.GetId()) ==
+ retrieved_attachments_->end());
+ retrieved_attachments_->insert(
+ std::make_pair(attachment.GetId(), attachment));
+ DCHECK(in_progress_attachments_.find(attachment.GetId()) !=
+ in_progress_attachments_.end());
+ in_progress_attachments_.erase(attachment.GetId());
+ PostResultIfAllRequestsCompleted();
+}
+
+void AttachmentServiceImpl::GetOrDownloadState::AddUnavailableAttachmentId(
+ const AttachmentId& attachment_id) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(unavailable_attachments_.find(attachment_id) ==
+ unavailable_attachments_.end());
+ unavailable_attachments_.insert(attachment_id);
+ DCHECK(in_progress_attachments_.find(attachment_id) !=
+ in_progress_attachments_.end());
+ in_progress_attachments_.erase(attachment_id);
+ PostResultIfAllRequestsCompleted();
+}
+
+void
+AttachmentServiceImpl::GetOrDownloadState::PostResultIfAllRequestsCompleted() {
+ if (in_progress_attachments_.empty()) {
+ // All requests completed. Let's notify consumer.
+ GetOrDownloadResult result =
+ unavailable_attachments_.empty() ? GET_SUCCESS : GET_UNSPECIFIED_ERROR;
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(callback_, result, base::Passed(&retrieved_attachments_)));
+ }
+}
+
AttachmentServiceImpl::AttachmentServiceImpl(
scoped_ptr<AttachmentStore> attachment_store,
scoped_ptr<AttachmentUploader> attachment_uploader,
+ scoped_ptr<AttachmentDownloader> attachment_downloader,
Delegate* delegate)
: attachment_store_(attachment_store.Pass()),
attachment_uploader_(attachment_uploader.Pass()),
+ attachment_downloader_(attachment_downloader.Pass()),
delegate_(delegate),
weak_ptr_factory_(this) {
DCHECK(CalledOnValidThread());
@@ -35,9 +131,13 @@ scoped_ptr<syncer::AttachmentService> AttachmentServiceImpl::CreateForTest() {
new syncer::FakeAttachmentStore(base::MessageLoopProxy::current()));
scoped_ptr<AttachmentUploader> attachment_uploader(
new FakeAttachmentUploader);
+ scoped_ptr<AttachmentDownloader> attachment_downloader(
+ new FakeAttachmentDownloader());
scoped_ptr<syncer::AttachmentService> attachment_service(
- new syncer::AttachmentServiceImpl(
- attachment_store.Pass(), attachment_uploader.Pass(), NULL));
+ new syncer::AttachmentServiceImpl(attachment_store.Pass(),
+ attachment_uploader.Pass(),
+ attachment_downloader.Pass(),
+ NULL));
return attachment_service.Pass();
}
@@ -45,10 +145,12 @@ void AttachmentServiceImpl::GetOrDownloadAttachments(
const AttachmentIdList& attachment_ids,
const GetOrDownloadCallback& callback) {
DCHECK(CalledOnValidThread());
+ scoped_refptr<GetOrDownloadState> state(
+ new GetOrDownloadState(attachment_ids, callback));
attachment_store_->Read(attachment_ids,
base::Bind(&AttachmentServiceImpl::ReadDone,
weak_ptr_factory_.GetWeakPtr(),
- callback));
+ state));
}
void AttachmentServiceImpl::DropAttachments(
@@ -96,18 +198,29 @@ void AttachmentServiceImpl::OnSyncDataUpdate(
}
void AttachmentServiceImpl::ReadDone(
- const GetOrDownloadCallback& callback,
+ const scoped_refptr<GetOrDownloadState>& state,
const AttachmentStore::Result& result,
scoped_ptr<AttachmentMap> attachments,
scoped_ptr<AttachmentIdList> unavailable_attachment_ids) {
- AttachmentService::GetOrDownloadResult get_result =
- AttachmentService::GET_UNSPECIFIED_ERROR;
- if (result == AttachmentStore::SUCCESS) {
- get_result = AttachmentService::GET_SUCCESS;
+ // Add read attachments to result.
+ for (AttachmentMap::const_iterator iter = attachments->begin();
+ iter != attachments->end();
+ ++iter) {
+ state->AddAttachment(iter->second);
+ }
+ // Try to download locally unavailable attachments.
+ for (AttachmentIdList::const_iterator iter =
+ unavailable_attachment_ids->begin();
+ iter != unavailable_attachment_ids->end();
+ ++iter) {
+ attachment_downloader_->DownloadAttachment(
+ *iter,
+ base::Bind(&AttachmentServiceImpl::DownloadDone,
+ weak_ptr_factory_.GetWeakPtr(),
+ state,
+ *iter));
+ ;
}
- // TODO(maniscalco): Deal with case where an error occurred (bug 361251).
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(callback, get_result, base::Passed(&attachments)));
}
void AttachmentServiceImpl::DropDone(const DropCallback& callback,
@@ -145,4 +258,16 @@ void AttachmentServiceImpl::UploadDone(
}
}
+void AttachmentServiceImpl::DownloadDone(
+ const scoped_refptr<GetOrDownloadState>& state,
+ const AttachmentId& attachment_id,
+ const AttachmentDownloader::DownloadResult& result,
+ scoped_ptr<Attachment> attachment) {
+ if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) {
+ state->AddAttachment(*attachment.get());
+ } else {
+ state->AddUnavailableAttachmentId(attachment_id);
+ }
+}
+
} // namespace syncer
« no previous file with comments | « sync/api/attachments/attachment_service_impl.h ('k') | sync/api/attachments/attachment_service_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698