blob: 0a38e2f319dcee8a2b039dfeb518af3b9e0c0953 [file] [log] [blame]
// Copyright 2015 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 "garnet/bin/ui/root_presenter/app.h"
#include <algorithm>
#include "garnet/bin/ui/root_presenter/presentation.h"
#include "lib/app/cpp/connect.h"
#include "lib/fxl/logging.h"
#include "lib/ui/input/cpp/formatting.h"
#include "lib/ui/views/fidl/view_provider.fidl.h"
namespace root_presenter {
App::App(const fxl::CommandLine& command_line)
: application_context_(app::ApplicationContext::CreateFromStartupInfo()),
input_reader_(this) {
FXL_DCHECK(application_context_);
input_reader_.Start();
application_context_->outgoing_services()->AddService<mozart::Presenter>(
[this](fidl::InterfaceRequest<mozart::Presenter> request) {
presenter_bindings_.AddBinding(this, std::move(request));
});
application_context_->outgoing_services()
->AddService<mozart::InputDeviceRegistry>(
[this](fidl::InterfaceRequest<mozart::InputDeviceRegistry> request) {
input_receiver_bindings_.AddBinding(this, std::move(request));
});
}
App::~App() {}
void App::Present(
fidl::InterfaceHandle<mozart::ViewOwner> view_owner_handle,
fidl::InterfaceRequest<mozart::Presentation> presentation_request) {
InitializeServices();
auto presentation =
std::make_unique<Presentation>(view_manager_.get(), scene_manager_.get());
presentation->Present(
mozart::ViewOwnerPtr::Create(std::move(view_owner_handle)),
std::move(presentation_request),
[ this, presentation = presentation.get() ] {
auto it = std::find_if(
presentations_.begin(), presentations_.end(),
[presentation](const std::unique_ptr<Presentation>& other) {
return other.get() == presentation;
});
FXL_DCHECK(it != presentations_.end());
presentations_.erase(it);
});
for (auto& it : devices_by_id_) {
presentation->OnDeviceAdded(it.second.get());
}
presentations_.push_back(std::move(presentation));
}
void App::RegisterDevice(
mozart::DeviceDescriptorPtr descriptor,
fidl::InterfaceRequest<mozart::InputDevice> input_device_request) {
uint32_t device_id = ++next_device_token_;
FXL_VLOG(1) << "RegisterDevice " << device_id << " " << *descriptor;
std::unique_ptr<mozart::InputDeviceImpl> input_device =
std::make_unique<mozart::InputDeviceImpl>(
device_id, std::move(descriptor), std::move(input_device_request),
this);
for (auto& presentation : presentations_) {
presentation->OnDeviceAdded(input_device.get());
}
devices_by_id_.emplace(device_id, std::move(input_device));
}
void App::OnDeviceDisconnected(mozart::InputDeviceImpl* input_device) {
if (devices_by_id_.count(input_device->id()) == 0)
return;
FXL_VLOG(1) << "UnregisterDevice " << input_device->id();
for (auto& presentation : presentations_) {
presentation->OnDeviceRemoved(input_device->id());
}
devices_by_id_.erase(input_device->id());
}
void App::OnReport(mozart::InputDeviceImpl* input_device,
mozart::InputReportPtr report) {
FXL_VLOG(2) << "OnReport from " << input_device->id() << " " << *report;
if (devices_by_id_.count(input_device->id()) == 0)
return;
FXL_VLOG(2) << "OnReport to " << presentations_.size();
for (auto& presentation : presentations_) {
presentation->OnReport(input_device->id(), report.Clone());
}
}
void App::InitializeServices() {
if (!view_manager_) {
application_context_->ConnectToEnvironmentService(
view_manager_.NewRequest());
view_manager_.set_connection_error_handler([this] {
FXL_LOG(ERROR) << "ViewManager died, destroying view trees.";
Reset();
});
view_manager_->GetSceneManager(scene_manager_.NewRequest());
scene_manager_.set_connection_error_handler([this] {
FXL_LOG(ERROR) << "SceneManager died, destroying view trees.";
Reset();
});
}
}
void App::Reset() {
presentations_.clear(); // must be first, holds pointers to services
view_manager_.reset();
scene_manager_.reset();
}
} // namespace root_presenter