| // 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 "garnet/lib/ui/scenic/scenic.h" |
| |
| #include <lib/async/default.h> |
| |
| #include "lib/component/cpp/startup_context.h" |
| #include "lib/fxl/logging.h" |
| |
| namespace scenic_impl { |
| |
| Scenic::Scenic(component::StartupContext* app_context, |
| fit::closure quit_callback) |
| : app_context_(app_context), quit_callback_(std::move(quit_callback)) { |
| FXL_DCHECK(app_context_); |
| |
| app_context->outgoing().AddPublicService(scenic_bindings_.GetHandler(this)); |
| |
| // Scenic relies on having a valid default dispatcher. A hard check here means |
| // we don't have to be defensive everywhere else. |
| FXL_CHECK(async_get_default_dispatcher()); |
| } |
| |
| Scenic::~Scenic() = default; |
| |
| void Scenic::OnSystemInitialized(System* system) { |
| size_t num_erased = uninitialized_systems_.erase(system); |
| FXL_CHECK(num_erased == 1); |
| |
| if (uninitialized_systems_.empty()) { |
| for (auto& closure : run_after_all_systems_initialized_) { |
| closure(); |
| } |
| run_after_all_systems_initialized_.clear(); |
| } |
| } |
| |
| void Scenic::CloseSession(Session* session) { |
| // TODO(SCN-1065): Make it so that close session removes the binding from |
| // session_bindings_, then remove num_sessions_ and return |
| // session_bindings_.size() in num_sessions() instead |
| for (auto& binding : session_bindings_.bindings()) { |
| // It's possible that this is called by BindingSet::CloseAndCheckForEmpty. |
| // In that case, binding could be empty, so check for that. |
| if (binding && binding->impl().get() == session) { |
| binding->Unbind(); |
| --num_sessions_; |
| return; |
| } |
| } |
| } |
| |
| void Scenic::CreateSession( |
| ::fidl::InterfaceRequest<fuchsia::ui::scenic::Session> session_request, |
| ::fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener) { |
| if (uninitialized_systems_.empty()) { |
| CreateSessionImmediately(std::move(session_request), std::move(listener)); |
| } else { |
| run_after_all_systems_initialized_.push_back( |
| [this, session_request = std::move(session_request), |
| listener = std::move(listener)]() mutable { |
| CreateSessionImmediately(std::move(session_request), |
| std::move(listener)); |
| }); |
| } |
| } |
| |
| void Scenic::CreateSessionImmediately( |
| ::fidl::InterfaceRequest<fuchsia::ui::scenic::Session> session_request, |
| ::fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener) { |
| auto session = |
| std::make_unique<Session>(next_session_id_++, std::move(listener)); |
| |
| // Give each installed System an opportunity to install a CommandDispatcher in |
| // the newly-created Session. |
| std::array<std::unique_ptr<CommandDispatcher>, System::TypeId::kMaxSystems> |
| dispatchers; |
| for (size_t i = 0; i < System::TypeId::kMaxSystems; ++i) { |
| if (auto& system = systems_[i]) { |
| dispatchers[i] = system->CreateCommandDispatcher( |
| CommandDispatcherContext(this, session.get())); |
| } |
| } |
| session->SetCommandDispatchers(std::move(dispatchers)); |
| |
| session_bindings_.AddBinding(std::move(session), std::move(session_request)); |
| ++num_sessions_; |
| } |
| |
| void Scenic::GetDisplayInfo( |
| fuchsia::ui::scenic::Scenic::GetDisplayInfoCallback callback) { |
| FXL_DCHECK(systems_[System::kGfx]); |
| TempSystemDelegate* delegate = |
| reinterpret_cast<TempSystemDelegate*>(systems_[System::kGfx].get()); |
| delegate->GetDisplayInfo(std::move(callback)); |
| } |
| |
| void Scenic::TakeScreenshot( |
| fuchsia::ui::scenic::Scenic::TakeScreenshotCallback callback) { |
| FXL_DCHECK(systems_[System::kGfx]); |
| TempSystemDelegate* delegate = |
| reinterpret_cast<TempSystemDelegate*>(systems_[System::kGfx].get()); |
| delegate->TakeScreenshot(std::move(callback)); |
| } |
| |
| void Scenic::GetDisplayOwnershipEvent( |
| fuchsia::ui::scenic::Scenic::GetDisplayOwnershipEventCallback callback) { |
| FXL_DCHECK(systems_[System::kGfx]); |
| TempSystemDelegate* delegate = |
| reinterpret_cast<TempSystemDelegate*>(systems_[System::kGfx].get()); |
| delegate->GetDisplayOwnershipEvent(std::move(callback)); |
| } |
| |
| } // namespace scenic_impl |