blob: 0fd3d38feba925e1aab8c5390eee436d47300580 [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 "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h"
#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h"
#include <lib/fsl/vmo/strings.h>
namespace modular {
namespace {
// Populates a fuchsia::modular::ModuleParameterMap struct from a
// fuchsia::modular::CreateModuleParameterMapInfo struct. May create new Links
// for any fuchsia::modular::CreateModuleParameterMapInfo.property_info if
// property_info[i].is_create_link_info().
class InitializeChainCall
: public Operation<fuchsia::modular::ExecuteResult,
fuchsia::modular::ModuleParameterMapPtr> {
public:
InitializeChainCall(StoryStorage* const story_storage,
std::vector<std::string> module_path,
fuchsia::modular::CreateModuleParameterMapInfoPtr
create_parameter_map_info,
ResultCall result_call)
: Operation("InitializeChainCall", std::move(result_call)),
story_storage_(story_storage),
module_path_(std::move(module_path)),
create_parameter_map_info_(std::move(create_parameter_map_info)) {}
private:
void Run() override {
FlowToken flow{this, &result_, &parameter_map_};
parameter_map_ = fuchsia::modular::ModuleParameterMap::New();
parameter_map_->entries.resize(0);
if (!create_parameter_map_info_) {
return;
}
// For each property in |create_parameter_map_info_|, either:
// a) Copy the |link_path| to |result_| directly or
// b) Create & populate a new Link and add the correct mapping to
// |result_|.
for (auto& entry : *create_parameter_map_info_->property_info) {
const auto& key = entry.key;
const auto& info = entry.value;
auto mapping = fuchsia::modular::ModuleParameterMapEntry::New();
mapping->name = key;
if (info.is_link_path()) {
info.link_path().Clone(&mapping->link_path);
} else { // info->is_create_link()
mapping->link_path.module_path.resize(0);
for (const auto& i : module_path_) {
mapping->link_path.module_path.push_back(i);
}
mapping->link_path.link_name = key;
// We issue N UpdateLinkValue calls and capture |flow| on each. We rely
// on the fact that once all refcounted instances of |flow| are
// destroyed, the InitializeChainCall will automatically finish.
std::string initial_json;
if (info.create_link().initial_data.size > 0) {
FXL_CHECK(fsl::StringFromVmo(info.create_link().initial_data,
&initial_json));
}
fuchsia::modular::LinkPath out_path;
mapping->link_path.Clone(&out_path);
AddSetLinkValueOperation(
&operations_, story_storage_, std::move(out_path),
[initial_json](fidl::StringPtr* value) { *value = initial_json; },
[this, flow](fuchsia::modular::ExecuteResult result) {
if (result.status != fuchsia::modular::ExecuteStatus::OK) {
result_ = std::move(result);
}
});
}
parameter_map_->entries.push_back(std::move(*mapping));
}
}
StoryStorage* const story_storage_;
const std::vector<std::string> module_path_;
const fuchsia::modular::CreateModuleParameterMapInfoPtr
create_parameter_map_info_;
fuchsia::modular::ModuleParameterMapPtr parameter_map_;
fuchsia::modular::ExecuteResult result_;
OperationCollection operations_;
FXL_DISALLOW_COPY_AND_ASSIGN(InitializeChainCall);
};
} // namespace
void AddInitializeChainOperation(
OperationContainer* const operation_container,
StoryStorage* const story_storage,
std::vector<std::string> module_path,
fuchsia::modular::CreateModuleParameterMapInfoPtr create_parameter_map_info,
std::function<void(fuchsia::modular::ExecuteResult,
fuchsia::modular::ModuleParameterMapPtr)>
result_call) {
operation_container->Add(new InitializeChainCall(
story_storage, std::move(module_path),
std::move(create_parameter_map_info), std::move(result_call)));
}
} // namespace modular