blob: c8fbe387d39141da3a7bb74b02caa50326a29a28 [file] [log] [blame]
// Copyright 2020 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 "src/modular/bin/sessionmgr/element_controller_impl.h"
#include <lib/syslog/cpp/macros.h>
#include <unordered_set>
#include <utility>
#include "src/modular/bin/sessionmgr/annotations.h"
namespace modular {
ElementControllerImpl::ElementControllerImpl(std::string story_id,
SessionStorage* const session_storage)
: story_id_(std::move(story_id)), session_storage_(session_storage), weak_factory_(this) {
FX_DCHECK(session_storage_ != nullptr);
}
void ElementControllerImpl::Connect(fidl::InterfaceRequest<fuchsia::element::Controller> request) {
auto on_error = [weak_ptr = weak_factory_.GetWeakPtr()](zx_status_t status) {
if (!weak_ptr) {
return;
}
FX_PLOGS(INFO, status) << "Element proposer closed ElementController; deleting story: "
<< weak_ptr->story_id_;
weak_ptr->session_storage_->DeleteStory(weak_ptr->story_id_);
};
bindings_.AddBinding(this, std::move(request), /*dispatcher=*/nullptr, std::move(on_error));
}
void ElementControllerImpl::UpdateAnnotations(
std::vector<fuchsia::element::Annotation> annotations_to_set,
std::vector<fuchsia::element::AnnotationKey> annotations_to_delete,
UpdateAnnotationsCallback callback) {
fuchsia::element::AnnotationController_UpdateAnnotations_Result result;
// Ensure all keys, by themselves, are valid.
bool is_to_set_keys_valid = std::all_of(
annotations_to_set.begin(), annotations_to_set.end(),
[](const auto& annotation) { return element::annotations::IsValidKey(annotation.key); });
bool is_to_delete_keys_valid = std::all_of(
annotations_to_delete.begin(), annotations_to_delete.end(), element::annotations::IsValidKey);
if (!is_to_set_keys_valid || !is_to_delete_keys_valid) {
result.set_err(fuchsia::element::UpdateAnnotationsError::INVALID_ARGS);
callback(std::move(result));
return;
}
// Ensure that there are no annotations being both set and deleted, i.e. that a key
// does not exist in both |annotations_to_set| and |annotations_to_delete|.
std::unordered_set<fuchsia::element::AnnotationKey> to_set_keys;
for (const auto& annotation : annotations_to_set) {
to_set_keys.insert(fidl::Clone(annotation.key));
}
auto is_same_key_set_delete =
std::any_of(annotations_to_delete.begin(), annotations_to_delete.end(),
[&to_set_keys](const auto& key) { return to_set_keys.count(key) > 0; });
if (is_same_key_set_delete) {
result.set_err(fuchsia::element::UpdateAnnotationsError::INVALID_ARGS);
callback(std::move(result));
return;
}
auto modular_annotations = element::annotations::ToModularAnnotations(annotations_to_set);
// Add |annotations_to_delete| as Modular annotations with a null value.
// |MergeStoryAnnotations| removes annotations with a null value from the story.
for (const auto& key : annotations_to_delete) {
auto annotation = fuchsia::modular::Annotation{
.key = element::annotations::ToModularAnnotationKey(key), .value = nullptr};
modular_annotations.push_back(std::move(annotation));
}
auto merge_err =
session_storage_->MergeStoryAnnotations(story_id_, std::move(modular_annotations));
if (merge_err.has_value()) {
if (merge_err.value() == fuchsia::modular::AnnotationError::TOO_MANY_ANNOTATIONS) {
result.set_err(fuchsia::element::UpdateAnnotationsError::TOO_MANY_ANNOTATIONS);
} else {
result.set_err(fuchsia::element::UpdateAnnotationsError::INVALID_ARGS);
}
} else {
result.set_response({});
}
callback(std::move(result));
}
void ElementControllerImpl::GetAnnotations(GetAnnotationsCallback callback) {
auto story_data = session_storage_->GetStoryData(story_id_);
if (!story_data) {
fuchsia::element::AnnotationController_GetAnnotations_Result result;
result.set_response({});
callback(std::move(result));
return;
}
FX_DCHECK(story_data->has_story_info());
fuchsia::element::AnnotationController_GetAnnotations_Response response;
if (story_data->story_info().has_annotations()) {
response.annotations =
modular::annotations::ToElementAnnotations(story_data->story_info().annotations());
}
fuchsia::element::AnnotationController_GetAnnotations_Result result;
result.set_response(std::move(response));
callback(std::move(result));
}
} // namespace modular