blob: 2d50f463f1f1b78fc813dd447fc0d34c5a261bcc [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/sessionmgr/entity_provider_runner/entity_provider_controller.h"
#include <lib/fxl/logging.h>
#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
namespace modular {
class EntityProviderController::EntityImpl : fuchsia::modular::Entity {
public:
EntityImpl(EntityProviderController* const entity_provider_controller,
fuchsia::modular::EntityProvider* const entity_provider,
const std::string& cookie, const std::string& entity_reference)
: entity_provider_controller_(entity_provider_controller),
entity_provider_(entity_provider),
cookie_(cookie),
entity_reference_(entity_reference) {
entity_bindings_.set_empty_set_handler([this] {
entity_provider_controller_->OnEmptyEntityImpls(cookie_);
// |this| is no longer valid.
});
}
// Serves this |fuchsia::modular::Entity| for the cookie this |EntityImpl| was
// instantiated for.
void ProvideEntity(fidl::InterfaceRequest<fuchsia::modular::Entity> request) {
entity_bindings_.AddBinding(this, std::move(request));
}
private:
// |fuchsia::modular::Entity|
void GetTypes(GetTypesCallback callback) override {
entity_provider_->GetTypes(cookie_, callback);
}
// |fuchsia::modular::Entity|
void GetData(std::string type, GetDataCallback callback) override {
entity_provider_->GetData(cookie_, type, callback);
}
// |fuchsia::modular::Entity|
void WriteData(std::string type, fuchsia::mem::Buffer data,
WriteDataCallback callback) override {
entity_provider_->WriteData(cookie_, type, std::move(data), callback);
}
// |fuchsia::modular::Entity|
void GetReference(GetReferenceCallback callback) override {
callback(entity_reference_);
}
// |fuchsia::modular::Entity|
void Watch(
std::string type,
fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) override {
entity_provider_->Watch(cookie_, type, std::move(watcher));
}
EntityProviderController* const entity_provider_controller_;
fuchsia::modular::EntityProvider* const entity_provider_;
const std::string cookie_;
const std::string entity_reference_;
fidl::BindingSet<fuchsia::modular::Entity> entity_bindings_;
FXL_DISALLOW_COPY_AND_ASSIGN(EntityImpl);
};
EntityProviderController::EntityProviderController(
fuchsia::modular::EntityProviderPtr entity_provider,
fuchsia::modular::AgentControllerPtr agent_controller,
std::function<void()> done)
: entity_provider_(std::move(entity_provider)),
agent_controller_(std::move(agent_controller)),
done_(done) {
FXL_DLOG(INFO) << "Running fuchsia::modular::EntityProvider";
if (agent_controller_) {
agent_controller_.set_error_handler([this](zx_status_t status) {
done_();
// |this| no longer valid.
});
}
}
EntityProviderController::~EntityProviderController() = default;
void EntityProviderController::ProvideEntity(
const std::string& cookie, const std::string& entity_reference,
fidl::InterfaceRequest<fuchsia::modular::Entity> request) {
auto it = entity_impls_.find(cookie);
if (it == entity_impls_.end()) {
bool inserted;
std::tie(it, inserted) = entity_impls_.insert(std::make_pair(
cookie, std::make_unique<EntityImpl>(this, entity_provider_.get(),
cookie, entity_reference)));
FXL_DCHECK(inserted);
}
// When there are no more |fuchsia::modular::Entity|s being serviced for this
// |cookie|, |OnEmptyEntityImpl()| is triggered.
it->second->ProvideEntity(std::move(request));
}
void EntityProviderController::OnEmptyEntityImpls(const std::string cookie) {
entity_impls_.erase(cookie);
if (entity_impls_.size() == 0ul) {
// We can drop our connection to the fuchsia::modular::EntityProvider at
// this point.
done_();
// |this| no longer valid.
}
}
} // namespace modular