blob: 98b6f1d19edb33d1691b00319d1d1f6746d1d5c6 [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 "src/lib/ui/base_view/view_provider_component.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
using fuchsia::ui::views::ViewToken;
namespace scenic {
ViewProviderComponent::ViewProviderComponent(ViewFactory factory, async::Loop* loop,
sys::ComponentContext* component_context)
: component_context_(component_context
? std::unique_ptr<sys::ComponentContext>(component_context)
: sys::ComponentContext::CreateAndServeOutgoingDirectory()),
scenic_(component_context_->svc()->Connect<fuchsia::ui::scenic::Scenic>()),
service_(component_context_.get(), scenic_.get(), factory.share()) {
// Register the |View| service.
component_context_->outgoing()->AddPublicService<fuchsia::ui::views::View>(
[this, component_context = component_context_.get(), factory = std::move(factory)](
fidl::InterfaceRequest<fuchsia::ui::views::View> request) mutable {
view_impl_ = std::make_unique<ViewImpl>(factory.share(), std::move(request), scenic_.get(),
component_context);
view_impl_->SetErrorHandler([this] { view_impl_ = nullptr; });
});
if (component_context) {
// We are only responsible for cleaning up the context if we created it
// ourselves. In this case we are "borrowing" an existing context that was
// provided to us, so we shouldn't retain a unique_ptr to it.
component_context_.release();
}
scenic_.set_error_handler([loop](zx_status_t status) {
FX_LOGS(INFO) << "Lost connection to Scenic.";
loop->Quit();
});
}
ViewProviderComponent::ViewImpl::ViewImpl(ViewFactory factory,
fidl::InterfaceRequest<View> view_request,
fuchsia::ui::scenic::Scenic* scenic,
sys::ComponentContext* component_context)
: factory_(std::move(factory)),
scenic_(scenic),
component_context_(component_context),
binding_(this, std::move(view_request)) {}
void ViewProviderComponent::ViewImpl::Present(fuchsia::ui::views::ViewToken view_token) {
if (view_) {
// This should only be called once.
FX_LOGS(ERROR) << "Present() can only be called once";
OnError();
return;
}
ViewContext context = {
.session_and_listener_request = CreateScenicSessionPtrAndListenerRequest(scenic_),
.view_token = std::move(view_token),
.component_context = component_context_,
};
view_ = factory_(std::move(context));
}
void ViewProviderComponent::ViewImpl::SetErrorHandler(fit::closure error_handler) {
error_handler_ = std::move(error_handler);
}
void ViewProviderComponent::ViewImpl::OnError(zx_status_t epitaph_value) {
binding_.Close(epitaph_value);
error_handler_();
}
} // namespace scenic