| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/ledger/bin/cloud_sync/impl/batch_download.h" |
| |
| #include <lib/callback/scoped_callback.h> |
| #include <lib/callback/waiter.h> |
| #include <lib/fit/function.h> |
| #include <trace/event.h> |
| |
| #include <utility> |
| |
| #include "src/ledger/bin/cloud_sync/impl/constants.h" |
| #include "src/lib/fxl/memory/ref_ptr.h" |
| |
| namespace cloud_sync { |
| |
| BatchDownload::BatchDownload( |
| storage::PageStorage* storage, |
| encryption::EncryptionService* encryption_service, |
| std::vector<cloud_provider::CommitPackEntry> entries, |
| std::unique_ptr<cloud_provider::Token> position_token, fit::closure on_done, |
| fit::closure on_error) |
| : storage_(storage), |
| encryption_service_(encryption_service), |
| entries_(std::move(entries)), |
| position_token_(std::move(position_token)), |
| on_done_(std::move(on_done)), |
| on_error_(std::move(on_error)), |
| weak_ptr_factory_(this) { |
| FXL_DCHECK(storage); |
| TRACE_ASYNC_BEGIN("ledger", "batch_download", |
| reinterpret_cast<uintptr_t>(this)); |
| } |
| |
| BatchDownload::~BatchDownload() { |
| TRACE_ASYNC_END("ledger", "batch_download", |
| reinterpret_cast<uintptr_t>(this)); |
| } |
| |
| void BatchDownload::Start() { |
| FXL_DCHECK(!started_); |
| started_ = true; |
| auto waiter = fxl::MakeRefCounted<callback::Waiter< |
| encryption::Status, storage::PageStorage::CommitIdAndBytes>>( |
| encryption::Status::OK); |
| for (auto& entry : entries_) { |
| encryption_service_->DecryptCommit( |
| entry.data, |
| [id = entry.id, callback = waiter->NewCallback()]( |
| encryption::Status status, std::string content) mutable { |
| callback(status, storage::PageStorage::CommitIdAndBytes( |
| std::move(id), std::move(content))); |
| }); |
| } |
| waiter->Finalize(callback::MakeScoped( |
| weak_ptr_factory_.GetWeakPtr(), |
| [this](encryption::Status status, |
| std::vector<storage::PageStorage::CommitIdAndBytes> commits) { |
| if (status != encryption::Status::OK) { |
| on_error_(); |
| return; |
| } |
| |
| storage_->AddCommitsFromSync( |
| std::move(commits), storage::ChangeSource::CLOUD, |
| callback::MakeScoped( |
| weak_ptr_factory_.GetWeakPtr(), |
| [this](storage::Status status, |
| std::vector<storage::CommitId> /*commit_ids*/) { |
| if (status != storage::Status::OK) { |
| on_error_(); |
| return; |
| } |
| |
| UpdateTimestampAndQuit(); |
| })); |
| })); |
| } |
| |
| void BatchDownload::UpdateTimestampAndQuit() { |
| if (!position_token_) { |
| // Can be deleted within. |
| on_done_(); |
| return; |
| } |
| |
| storage_->SetSyncMetadata( |
| kTimestampKey, convert::ToString(position_token_->opaque_id), |
| callback::MakeScoped(weak_ptr_factory_.GetWeakPtr(), |
| [this](storage::Status status) { |
| if (status != storage::Status::OK) { |
| on_error_(); |
| return; |
| } |
| |
| // Can be deleted within. |
| on_done_(); |
| })); |
| } |
| |
| } // namespace cloud_sync |