blob: d65a90ed36ba9c39d83d366400ef5864563bd617 [file] [log] [blame]
// Copyright 2017 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 "peridot/bin/agents/clipboard/clipboard_storage.h"
#include <lib/fsl/vmo/strings.h>
#include <lib/fxl/functional/make_copyable.h>
namespace modular {
namespace {
fidl::VectorPtr<uint8_t> ToArray(const std::string& str) {
auto array = fidl::VectorPtr<uint8_t>::New(str.size());
memcpy(array->data(), str.data(), str.size());
return array;
}
std::string ToString(fuchsia::mem::Buffer value) {
fsl::SizedVmo vmo;
std::string parsed_string;
if (!fsl::SizedVmo::FromTransport(std::move(value), &vmo)) {
FXL_LOG(ERROR) << "Could not decode clipboard value.";
return "";
}
if (!fsl::StringFromVmo(vmo, &parsed_string)) {
FXL_LOG(ERROR)
<< "fuchsia::modular::Clipboard vmo could not be decoded to string.";
return "";
}
return parsed_string;
}
// The Ledger key that is used to store the current value.
constexpr char kCurrentValueKey[] = "current_value";
} // namespace
class ClipboardStorage::PushCall : public Operation<> {
public:
PushCall(ClipboardStorage* const impl, const fidl::StringPtr& text)
: Operation("ClipboardStorage::PushCall", [] {}),
impl_(impl),
text_(text) {}
private:
void Run() override {
FlowToken flow{this};
impl_->page()->Put(ToArray(kCurrentValueKey), ToArray(text_),
[this, flow](fuchsia::ledger::Status status) {
if (status != fuchsia::ledger::Status::OK) {
FXL_LOG(ERROR) << "Failed to put text: " << text_;
}
});
}
ClipboardStorage* const impl_; // not owned
const fidl::StringPtr text_;
FXL_DISALLOW_COPY_AND_ASSIGN(PushCall);
};
class ClipboardStorage::PeekCall : public Operation<fidl::StringPtr> {
public:
PeekCall(ClipboardStorage* const impl,
std::function<void(fidl::StringPtr)> result)
: Operation("ClipboardStorage::PeekCall", std::move(result)),
impl_(impl) {
// No error checking: Absent ledger value yields "", not
// null. TODO(mesch): Once we support types, distinction of
// null may make sense.
text_.reset("");
}
private:
void Run() override {
FlowToken flow{this, &text_};
impl_->page()->GetSnapshot(
snapshot_.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
[](fuchsia::ledger::Status status) {
if (status != fuchsia::ledger::Status::OK) {
FXL_LOG(ERROR) << "Failed to get page snapshot";
}
});
snapshot_->Get(ToArray(kCurrentValueKey),
[this, flow](fuchsia::ledger::Status status,
fuchsia::mem::BufferPtr value) {
if (value) {
text_ = ToString(std::move(*value));
}
});
}
ClipboardStorage* const impl_; // not owned
fuchsia::ledger::PageSnapshotPtr snapshot_;
fidl::StringPtr text_;
FXL_DISALLOW_COPY_AND_ASSIGN(PeekCall);
};
ClipboardStorage::ClipboardStorage(LedgerClient* ledger_client,
LedgerPageId page_id)
: PageClient("ClipboardStorage", ledger_client, std::move(page_id)) {}
ClipboardStorage::~ClipboardStorage() = default;
void ClipboardStorage::Push(const fidl::StringPtr& text) {
operation_queue_.Add(new PushCall(this, text));
}
void ClipboardStorage::Peek(
const std::function<void(fidl::StringPtr)>& callback) {
operation_queue_.Add(new PeekCall(this, callback));
}
} // namespace modular