blob: 5dc13239150dda3761fa7b6907a6008b12821d3b [file] [log] [blame]
// Copyright 2018 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 <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/modular/internal/cpp/fidl.h>
#include <lib/async/cpp/future.h>
#include "peridot/bin/sessionmgr/storage/story_storage.h"
#include "peridot/lib/ledger_client/ledger_client.h"
#include "peridot/lib/ledger_client/page_client.h"
#include "peridot/lib/ledger_client/page_id.h"
namespace modular {
// This class has the following responsibilities:
// * Manage the persistence of metadata about what stories are part of a single
// session.
// * Observe the metadata and call clients back when changes initiated by other
// Ledger clients appear.
// * Manage the lifecycle of Ledger pages for storing individual story
// metadata. The contents of these pages are governed by StoryStoage.
// All calls operate directly on the Ledger itself: no local caching is
// performed.
class SessionStorage : public PageClient {
// Constructs a new SessionStorage with storage on |page_id| in the ledger
// given by |ledger_client|.
// |ledger_client| must outlive *this.
SessionStorage(LedgerClient* ledger_client, LedgerPageId page_id);
// |callback| is notified whenever a story has been deleted. This
// notification is either the result of:
// a) The story being deleted on another device.
// b) The story having been deleted locally with DeleteStory().
void set_on_story_deleted(
std::function<void(fidl::StringPtr story_id)> callback) {
on_story_deleted_ = std::move(callback);
// |callback| is notified whenever a story has been added or updated.
// Currently we do not differentiate between the two, and it is up to the
// client to make this distinction.
// The update could be the result of a local modification (ie, through
// Update*()) or a modification on another device.
void set_on_story_updated(
std::function<void(fidl::StringPtr story_id,
fuchsia::modular::internal::StoryData story_data)>
callback) {
on_story_updated_ = std::move(callback);
// Creates a new story and returns a tuple of (story id, story ledger page
// id) on completion. |story_name| and |extra_info| may be null.
// If |story_name| is not provided, a UUID will be generated as the name.
// If |extra_info| is set, populates StoryData.story_info.extra with the
// entries given.
// TODO(thatguy): Allowing for null story names is left in for backwards
// compatibility with existing code. The intention is that all clients
// outside the FW (through FIDL interfaces) use story names exclusively. It
// is unclear if internal story IDs should be an implementation detail of
// SessionStorage, or if they should be exposed to the story runtime
// architecture.
FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> CreateStory(
fidl::StringPtr story_name,
fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
fuchsia::modular::StoryOptions story_options);
// Same as above, but defaults |story_name| to nullptr.
FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> CreateStory(
fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
fuchsia::modular::StoryOptions story_options);
// Deletes the |story_id| from the list of known stories and completes the
// returned Future when done.
// Does not currently delete the story's page, so it is left dangling.
// TODO(thatguy): Deleting stories is a two-step process:
// 1) Remove the story from the list of active stories (so it doesn't show
// up on the timeline).
// 2) Delete the underlying story storage page.
// We only do (1). Find a way to split (1) and (2): either have the client
// pass in a Future that signals when it's OK to delete the story storage (ie,
// once the story has shut down cleanly) or split the function into two calls.
// MI4-1002
FuturePtr<> DeleteStory(fidl::StringPtr story_id);
// Sets the last focused timestamp for |story_id| to |ts|. Completes the
// returned Future when done.
FuturePtr<> UpdateLastFocusedTimestamp(fidl::StringPtr story_id, int64_t ts);
// Returns a Future StoryDataPtr for |story_id|. If |story_id| is not a valid
// story, the returned StoryDataPtr will be null.
FuturePtr<fuchsia::modular::internal::StoryDataPtr> GetStoryData(
fidl::StringPtr story_id);
// Returns a Future vector of StoryData for all stories in this session.
// TODO(thatguy): If the return value grows large, an dispatcher stream would
// be a more appropriate return value.
FuturePtr<> UpdateStoryOptions(fidl::StringPtr story_id,
fuchsia::modular::StoryOptions story_options);
// Gets the StoryStorage for the story with the given |story_id| to perform
// operations on the story such as adding modules, updating links, etc.
FuturePtr<std::unique_ptr<StoryStorage>> GetStoryStorage(
fidl::StringPtr story_id);
// Returns the snapshot for the story. If there is no snapshot for the story
// or the read operation failed, the return value of |fuchsia::mem::BufferPtr|
// will be nullptr.
FuturePtr<fuchsia::mem::BufferPtr> ReadSnapshot(fidl::StringPtr story_id);
// Writes the given |snapshot| to storage. The returned future will resolve
// when the |snapshot| has been written to storage or when it has failed to
// write to storage.
FuturePtr<> WriteSnapshot(fidl::StringPtr story_id,
fuchsia::mem::Buffer snapshot);
// |PageClient|
void OnPageChange(const std::string& key, const std::string& value) override;
// |PageClient|
void OnPageDelete(const std::string& key) override;
LedgerClient* const ledger_client_;
OperationQueue operation_queue_;
std::function<void(fidl::StringPtr story_id)> on_story_deleted_;
std::function<void(fidl::StringPtr story_id,
fuchsia::modular::internal::StoryData story_data)>
} // namespace modular