blob: 6976b20f6ca123a7bdd2c683ebf27e3c52b314b6 [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/acquirers/story_info/story_watcher_impl.h"
#include <lib/context/cpp/context_metadata_builder.h>
#include <lib/context/cpp/formatting.h>
#include <lib/fidl/cpp/optional.h>
#include <lib/fxl/functional/make_copyable.h>
#include "peridot/bin/acquirers/story_info/link_watcher_impl.h"
#include "peridot/bin/acquirers/story_info/story_info.h"
#include "peridot/bin/sessionmgr/storage/constants_and_utils.h" // MakeLinkKey, EncodeModulePath
namespace maxwell {
StoryWatcherImpl::StoryWatcherImpl(
StoryInfoAcquirer* const owner,
fuchsia::modular::ContextWriter* const writer,
fuchsia::modular::StoryProvider* const story_provider,
const std::string& story_id)
: owner_(owner),
writer_(writer),
story_id_(story_id),
story_watcher_binding_(this),
story_links_watcher_binding_(this) {
story_provider->GetController(story_id, story_controller_.NewRequest());
story_controller_.set_error_handler(
[this](zx_status_t status) { owner_->DropStoryWatcher(story_id_); });
story_controller_->Watch(story_watcher_binding_.NewBinding());
story_watcher_binding_.set_error_handler(
[this](zx_status_t status) { owner_->DropStoryWatcher(story_id_); });
context_metadata_ = ContextMetadataBuilder()
.SetStoryId(story_id)
.SetStoryFocused(false)
.Build();
// TODO(thatguy): Add StoryState.
// TODO(thatguy): Add visible state.
writer_->CreateValue(context_value_.NewRequest(),
fuchsia::modular::ContextValueType::STORY);
fuchsia::modular::ContextMetadata metadata;
fidl::Clone(context_metadata_, &metadata);
context_value_->Set(nullptr /* content */,
fidl::MakeOptional(std::move(metadata)));
story_controller_->GetActiveLinks(
story_links_watcher_binding_.NewBinding(),
[this](std::vector<fuchsia::modular::LinkPath> links) mutable {
for (fuchsia::modular::LinkPath& link_path : links) {
WatchLink(std::move(link_path));
}
});
}
StoryWatcherImpl::~StoryWatcherImpl() = default;
void StoryWatcherImpl::OnStateChange(fuchsia::modular::StoryState new_state) {
// TODO(thatguy): Add recording of state to fuchsia::modular::StoryMetadata.
}
void StoryWatcherImpl::OnModuleAdded(fuchsia::modular::ModuleData module_data) {
ContextModuleMetadata data;
context_value_->CreateChildValue(data.value_writer.NewRequest(),
fuchsia::modular::ContextValueType::MODULE);
auto metadata = ContextMetadataBuilder()
.SetModuleUrl(module_data.module_url)
.SetModulePath(module_data.module_path)
.Build();
fidl::Clone(metadata, &data.metadata);
data.value_writer->Set(nullptr /* content */,
fidl::MakeOptional(std::move(metadata)));
auto path = modular::EncodeModulePath(module_data.module_path);
module_values_.emplace(path, std::move(data));
}
void StoryWatcherImpl::OnModuleFocused(
std::vector<std::string> module_path) {
auto key = modular::EncodeModulePath(module_path);
auto it = module_values_.find(key);
if (it == module_values_.end()) {
return;
}
if (!last_module_focus_key_.empty()) {
auto it_last = module_values_.find(last_module_focus_key_);
if (it_last != module_values_.end()) {
UpdateModuleFocus(&it_last->second, false);
}
}
UpdateModuleFocus(&it->second, true);
last_module_focus_key_ = key;
}
void StoryWatcherImpl::OnNewLink(fuchsia::modular::LinkPath link_path) {
WatchLink(std::move(link_path));
}
void StoryWatcherImpl::WatchLink(fuchsia::modular::LinkPath link_path) {
links_.emplace(std::make_pair(
modular::MakeLinkKey(link_path),
std::make_unique<LinkWatcherImpl>(this, story_controller_.get(),
story_id_, context_value_.get(),
std::move(link_path))));
}
void StoryWatcherImpl::OnFocusChange(bool focused) {
context_metadata_ = ContextMetadataBuilder(std::move(context_metadata_))
.SetStoryFocused(focused)
.Build();
fuchsia::modular::ContextMetadata metadata;
fidl::Clone(context_metadata_, &metadata);
context_value_->Set(nullptr /* content */,
fidl::MakeOptional(std::move(metadata)));
}
void StoryWatcherImpl::OnStoryStateChange(fuchsia::modular::StoryInfo info,
fuchsia::modular::StoryState state) {
// TODO(thatguy): Record this state too.
}
void StoryWatcherImpl::DropLink(const std::string& link_key) {
links_.erase(link_key);
}
void StoryWatcherImpl::UpdateModuleFocus(ContextModuleMetadata* data,
bool focused) {
auto metadata = ContextMetadataBuilder(std::move(data->metadata))
.SetModuleFocused(focused)
.Build();
fidl::Clone(metadata, &data->metadata);
data->value_writer->Set(nullptr /* content */,
fidl::MakeOptional(std::move(metadata)));
}
} // namespace maxwell