1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file. 4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "sync/internal_api/public/attachments/attachment_service_impl.h" 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <iterator> 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/bind.h" 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/message_loop/message_loop.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h" 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/api/attachments/attachment.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "sync/api/attachments/fake_attachment_store.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "sync/internal_api/public/attachments/fake_attachment_downloader.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "sync/internal_api/public/attachments/fake_attachment_uploader.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace syncer { 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// GetOrDownloadAttachments starts multiple parallel DownloadAttachment calls. 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// GetOrDownloadState tracks completion of these calls and posts callback for 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// consumer once all attachments are either retrieved or reported unavailable. 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class AttachmentServiceImpl::GetOrDownloadState 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : public base::RefCounted<GetOrDownloadState>, 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public base::NonThreadSafe { 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // GetOrDownloadState gets parameter from values passed to 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // AttachmentService::GetOrDownloadAttachments. 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // |attachment_ids| is a list of attachmens to retrieve. 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // |callback| will be posted on current thread when all attachments retrieved 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // or confirmed unavailable. 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetOrDownloadState(const AttachmentIdList& attachment_ids, 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GetOrDownloadCallback& callback); 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Attachment was just retrieved. Add it to retrieved attachments. 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void AddAttachment(const Attachment& attachment); 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Both reading from local store and downloading attachment failed. 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Add it to unavailable set. 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void AddUnavailableAttachmentId(const AttachmentId& attachment_id); 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class base::RefCounted<GetOrDownloadState>; 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~GetOrDownloadState(); 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If all attachment requests completed then post callback to consumer with 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // results. 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void PostResultIfAllRequestsCompleted(); 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetOrDownloadCallback callback_; 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Requests for these attachments are still in progress. 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AttachmentIdSet in_progress_attachments_; 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AttachmentIdSet unavailable_attachments_; 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<AttachmentMap> retrieved_attachments_; 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GetOrDownloadState); 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AttachmentServiceImpl::GetOrDownloadState::GetOrDownloadState( 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AttachmentIdList& attachment_ids, 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GetOrDownloadCallback& callback) 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : callback_(callback), retrieved_attachments_(new AttachmentMap()) { 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::copy( 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) attachment_ids.begin(), 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) attachment_ids.end(), 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::inserter(in_progress_attachments_, in_progress_attachments_.end())); 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PostResultIfAllRequestsCompleted(); 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AttachmentServiceImpl::GetOrDownloadState::~GetOrDownloadState() { 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AttachmentServiceImpl::GetOrDownloadState::AddAttachment( 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const Attachment& attachment) { 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(retrieved_attachments_->find(attachment.GetId()) == 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) retrieved_attachments_->end()); 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) retrieved_attachments_->insert( 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::make_pair(attachment.GetId(), attachment)); 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(in_progress_attachments_.find(attachment.GetId()) != 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) in_progress_attachments_.end()); 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) in_progress_attachments_.erase(attachment.GetId()); 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PostResultIfAllRequestsCompleted(); 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AttachmentServiceImpl::GetOrDownloadState::AddUnavailableAttachmentId( 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AttachmentId& attachment_id) { 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(unavailable_attachments_.find(attachment_id) == 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) unavailable_attachments_.end()); 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) unavailable_attachments_.insert(attachment_id); 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(in_progress_attachments_.find(attachment_id) != 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) in_progress_attachments_.end()); 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) in_progress_attachments_.erase(attachment_id); 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PostResultIfAllRequestsCompleted(); 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AttachmentServiceImpl::GetOrDownloadState::PostResultIfAllRequestsCompleted() { 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (in_progress_attachments_.empty()) { 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // All requests completed. Let's notify consumer. 10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetOrDownloadResult result = 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) unavailable_attachments_.empty() ? GET_SUCCESS : GET_UNSPECIFIED_ERROR; 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->PostTask( 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(callback_, result, base::Passed(&retrieved_attachments_))); 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AttachmentServiceImpl::AttachmentServiceImpl( 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<AttachmentStore> attachment_store, 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<AttachmentUploader> attachment_uploader, 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<AttachmentDownloader> attachment_downloader, 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Delegate* delegate, 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::TimeDelta& initial_backoff_delay, 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::TimeDelta& max_backoff_delay) 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : attachment_store_(attachment_store), 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) attachment_uploader_(attachment_uploader.Pass()), 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) attachment_downloader_(attachment_downloader.Pass()), 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delegate_(delegate), 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_(this) { 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(CalledOnValidThread()); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(attachment_store_.get()); 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(maniscalco): Observe network connectivity change events. When the 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // network becomes disconnected, consider suspending queue dispatch. When 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // connectivity is restored, consider clearing any dispatch backoff (bug 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 411981). 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_.reset(new TaskQueue<AttachmentId>( 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&AttachmentServiceImpl::BeginUpload, 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr()), 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci initial_backoff_delay, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_backoff_delay)); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::NetworkChangeNotifier::AddNetworkChangeObserver(this); 139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AttachmentServiceImpl::~AttachmentServiceImpl() { 142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(CalledOnValidThread()); 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Static. 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<syncer::AttachmentService> AttachmentServiceImpl::CreateForTest() { 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<syncer::AttachmentStore> attachment_store( 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new syncer::FakeAttachmentStore(base::ThreadTaskRunnerHandle::Get())); 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<AttachmentUploader> attachment_uploader( 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new FakeAttachmentUploader); 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<AttachmentDownloader> attachment_downloader( 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new FakeAttachmentDownloader()); 154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_ptr<syncer::AttachmentService> attachment_service( 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new syncer::AttachmentServiceImpl(attachment_store, 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) attachment_uploader.Pass(), 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) attachment_downloader.Pass(), 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta(), 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta())); 161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return attachment_service.Pass(); 162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAttachmentStore* AttachmentServiceImpl::GetStore() { 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return attachment_store_.get(); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AttachmentServiceImpl::GetOrDownloadAttachments( 169e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const AttachmentIdList& attachment_ids, 170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const GetOrDownloadCallback& callback) { 171e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(CalledOnValidThread()); 17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<GetOrDownloadState> state( 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new GetOrDownloadState(attachment_ids, callback)); 1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch attachment_store_->Read(attachment_ids, 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&AttachmentServiceImpl::ReadDone, 1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch weak_ptr_factory_.GetWeakPtr(), 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) state)); 178e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 179e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AttachmentServiceImpl::DropAttachments( 181e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const AttachmentIdList& attachment_ids, 182e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const DropCallback& callback) { 183e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(CalledOnValidThread()); 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch attachment_store_->Drop(attachment_ids, 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&AttachmentServiceImpl::DropDone, 1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch weak_ptr_factory_.GetWeakPtr(), 1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch callback)); 188e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 189e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AttachmentServiceImpl::ReadDone( 19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const scoped_refptr<GetOrDownloadState>& state, 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AttachmentStore::Result& result, 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<AttachmentMap> attachments, 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Add read attachments to result. 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (AttachmentMap::const_iterator iter = attachments->begin(); 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) iter != attachments->end(); 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++iter) { 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) state->AddAttachment(iter->second); 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin(); 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AttachmentIdList::const_iterator end = unavailable_attachment_ids->end(); 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (attachment_downloader_.get()) { 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Try to download locally unavailable attachments. 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (; iter != end; ++iter) { 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch attachment_downloader_->DownloadAttachment( 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *iter, 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&AttachmentServiceImpl::DownloadDone, 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch state, 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *iter)); 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // No downloader so all locally unavailable attachments are unavailable. 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (; iter != end; ++iter) { 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch state->AddUnavailableAttachmentId(*iter); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AttachmentServiceImpl::DropDone(const DropCallback& callback, 2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const AttachmentStore::Result& result) { 2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AttachmentService::DropResult drop_result = 2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AttachmentService::DROP_UNSPECIFIED_ERROR; 2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (result == AttachmentStore::SUCCESS) { 2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch drop_result = AttachmentService::DROP_SUCCESS; 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(maniscalco): Deal with case where an error occurred (bug 361251). 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::MessageLoop::current()->PostTask(FROM_HERE, 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(callback, drop_result)); 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AttachmentServiceImpl::UploadDone( 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AttachmentUploader::UploadResult& result, 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AttachmentId& attachment_id) { 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(CalledOnValidThread()); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (result) { 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case AttachmentUploader::UPLOAD_SUCCESS: 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->MarkAsSucceeded(attachment_id); 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (delegate_) { 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->OnAttachmentUploaded(attachment_id); 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case AttachmentUploader::UPLOAD_TRANSIENT_ERROR: 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->MarkAsFailed(attachment_id); 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->AddToQueue(attachment_id); 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR: 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(pavely): crbug/372622: Deal with UploadAttachment failures. 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->MarkAsFailed(attachment_id); 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AttachmentServiceImpl::DownloadDone( 25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const scoped_refptr<GetOrDownloadState>& state, 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AttachmentId& attachment_id, 25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AttachmentDownloader::DownloadResult& result, 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<Attachment> attachment) { 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (result) { 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case AttachmentDownloader::DOWNLOAD_SUCCESS: 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state->AddAttachment(*attachment.get()); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR: 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR: 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state->AddUnavailableAttachmentId(attachment_id); 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AttachmentServiceImpl::BeginUpload(const AttachmentId& attachment_id) { 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(CalledOnValidThread()); 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentIdList attachment_ids; 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci attachment_ids.push_back(attachment_id); 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci attachment_store_->Read(attachment_ids, 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&AttachmentServiceImpl::ReadDoneNowUpload, 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr())); 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AttachmentServiceImpl::UploadAttachments( 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const AttachmentIdSet& attachment_ids) { 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(CalledOnValidThread()); 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!attachment_uploader_.get()) { 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentIdSet::const_iterator iter = attachment_ids.begin(); 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentIdSet::const_iterator end = attachment_ids.end(); 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (; iter != end; ++iter) { 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->AddToQueue(*iter); 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AttachmentServiceImpl::OnNetworkChanged( 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::NetworkChangeNotifier::ConnectionType type) { 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (type != net::NetworkChangeNotifier::CONNECTION_NONE) { 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->ResetBackoff(); 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AttachmentServiceImpl::ReadDoneNowUpload( 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const AttachmentStore::Result& result, 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<AttachmentMap> attachments, 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<AttachmentIdList> unavailable_attachment_ids) { 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(CalledOnValidThread()); 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!unavailable_attachment_ids->empty()) { 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(maniscalco): We failed to read some attachments. What should we do 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // now? 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin(); 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentIdList::const_iterator end = unavailable_attachment_ids->end(); 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (; iter != end; ++iter) { 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->Cancel(*iter); 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentMap::const_iterator iter = attachments->begin(); 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AttachmentMap::const_iterator end = attachments->end(); 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (; iter != end; ++iter) { 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci attachment_uploader_->UploadAttachment( 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iter->second, 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&AttachmentServiceImpl::UploadDone, 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr())); 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AttachmentServiceImpl::SetTimerForTest(scoped_ptr<base::Timer> timer) { 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci upload_task_queue_->SetTimerForTest(timer.Pass()); 32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 330e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace syncer 331