| // 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/fit/function.h> |
| #include <lib/fsl/vmo/strings.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_)); |
| } |
| |
| ClipboardStorage* const impl_; // not owned |
| const fidl::StringPtr text_; |
| }; |
| |
| class ClipboardStorage::PeekCall : public Operation<fidl::StringPtr> { |
| public: |
| PeekCall(ClipboardStorage* const impl, |
| fit::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); |
| snapshot_->Get( |
| ToArray(kCurrentValueKey), |
| [this, flow](fuchsia::ledger::PageSnapshot_Get_Result result) { |
| if (result.is_response()) { |
| text_ = ToString(std::move(result.response().buffer)); |
| } |
| }); |
| } |
| |
| ClipboardStorage* const impl_; // not owned |
| fuchsia::ledger::PageSnapshotPtr snapshot_; |
| fidl::StringPtr text_; |
| }; |
| |
| 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(std::make_unique<PushCall>(this, text)); |
| } |
| |
| void ClipboardStorage::Peek(fit::function<void(fidl::StringPtr)> callback) { |
| operation_queue_.Add(std::make_unique<PeekCall>(this, std::move(callback))); |
| } |
| |
| } // namespace modular |