blob: fa35c4437c3ca2d5341917781bd25bd7fa11f8d0 [file] [log] [blame]
// 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/ledger_sync_impl.h"
#include <fuchsia/ledger/cloud/cpp/fidl.h>
#include <lib/fit/function.h>
#include "src/ledger/bin/cloud_sync/impl/page_sync_impl.h"
#include "src/ledger/bin/encryption/impl/encryption_service_impl.h"
#include "src/ledger/lib/convert/convert.h"
#include "src/ledger/lib/logging/logging.h"
#include "third_party/abseil-cpp/absl/strings/string_view.h"
namespace cloud_sync {
LedgerSyncImpl::LedgerSyncImpl(ledger::Environment* environment, const UserConfig* user_config,
encryption::EncryptionService* encryption_service,
absl::string_view app_id, std::unique_ptr<SyncStateWatcher> watcher)
: environment_(environment),
user_config_(user_config),
encryption_service_(encryption_service),
app_id_(convert::ToString(app_id)),
user_watcher_(std::move(watcher)) {
if (!user_config_->cloud_provider) {
LEDGER_LOG(ERROR) << "Instantiated a LedgerSyncImpl with an invalid cloud provider.";
}
aggregator_.SetBaseWatcher(user_watcher_.get());
}
LedgerSyncImpl::~LedgerSyncImpl() {
LEDGER_DCHECK(active_page_syncs_.empty());
if (on_delete_) {
on_delete_();
}
}
void LedgerSyncImpl::CreatePageSync(
storage::PageStorage* page_storage, storage::PageSyncClient* page_sync_client,
fit::function<void(storage::Status, std::unique_ptr<PageSync>)> callback) {
LEDGER_DCHECK(page_storage);
if (!user_config_->cloud_provider) {
// TODO(LE-567): handle recovery from cloud provider disconnection.
LEDGER_LOG(WARNING) << "Skipped initializing the cloud sync. "
<< "Cloud provider is disconnected.";
callback(storage::Status::INTERNAL_ERROR, nullptr);
return;
}
encryption_service_->GetPageId(
page_storage->GetId(), [this, page_storage, page_sync_client, callback = std::move(callback)](
encryption::Status status, std::string page_id) {
if (status != encryption::Status::OK) {
LEDGER_LOG(ERROR)
<< "Failed to get the encoded version of page_id from the encryption service.";
callback(storage::Status::INTERNAL_ERROR, nullptr);
return;
}
cloud_provider::PageCloudPtr page_cloud;
user_config_->cloud_provider->GetPageCloud(
convert::ToArray(app_id_), convert::ToArray(page_id), page_cloud.NewRequest(),
[](auto status) {
if (status != cloud_provider::Status::OK) {
LEDGER_LOG(ERROR) << "Failed to retrieve page cloud, status: "
<< fidl::ToUnderlying(status);
// Only log. This should be handled by page cloud
// connection error handler.
}
});
auto page_sync = std::make_unique<PageSyncImpl>(
environment_->dispatcher(), environment_->coroutine_service(), page_storage,
page_sync_client, encryption_service_, std::move(page_cloud),
environment_->MakeBackoff(), environment_->MakeBackoff(),
aggregator_.GetNewStateWatcher());
if (upload_enabled_) {
page_sync->EnableUpload();
}
active_page_syncs_.insert(page_sync.get());
page_sync->set_on_delete(
[this, page_sync = page_sync.get()]() { active_page_syncs_.erase(page_sync); });
callback(storage::Status::OK, std::move(page_sync));
});
}
void LedgerSyncImpl::EnableUpload() {
if (upload_enabled_) {
return;
}
upload_enabled_ = true;
for (auto page_sync : active_page_syncs_) {
page_sync->EnableUpload();
}
}
} // namespace cloud_sync