// Copyright 2016 The Chromium 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 "flutter/content_handler/app.h" #include #include #include "apps/icu_data/lib/icu_data.h" #include "apps/tracing/lib/trace/provider.h" #include "flutter/common/settings.h" #include "flutter/common/threads.h" #include "flutter/sky/engine/platform/fonts/fuchsia/FontCacheFuchsia.h" #include "lib/ftl/macros.h" #include "lib/ftl/tasks/task_runner.h" #include "lib/mtl/tasks/message_loop.h" namespace flutter_runner { namespace { static App* g_app = nullptr; void QuitMessageLoop() { mtl::MessageLoop::GetCurrent()->QuitNow(); } } // namespace App::App() { g_app = this; context_ = app::ApplicationContext::CreateFromStartupInfo(); tracing::InitializeTracer(context_.get(), {}); gpu_thread_ = std::make_unique(); io_thread_ = std::make_unique(); FTL_CHECK(gpu_thread_->IsValid()) << "Must be able to create the GPU thread"; FTL_CHECK(io_thread_->IsValid()) << "Must be able to create the IO thread"; auto ui_task_runner = mtl::MessageLoop::GetCurrent()->task_runner(); auto gpu_task_runner = gpu_thread_->TaskRunner(); auto io_task_runner = io_thread_->TaskRunner(); // Notice that the Platform and UI threads are actually the same. blink::Threads::Set(blink::Threads(ui_task_runner, // Platform gpu_task_runner, // GPU ui_task_runner, // UI io_task_runner // IO )); if (!icu_data::Initialize(context_.get())) { FTL_LOG(ERROR) << "Could not initialize ICU data."; } blink::Settings settings; settings.enable_observatory = true; blink::Settings::Set(settings); blink::SetFontProvider( context_->ConnectToEnvironmentService()); context_->outgoing_services()->AddService( [this](fidl::InterfaceRequest request) { runner_bindings_.AddBinding(this, std::move(request)); }); } App::~App() { icu_data::Release(); blink::Threads::Gpu()->PostTask(QuitMessageLoop); blink::Threads::IO()->PostTask(QuitMessageLoop); g_app = nullptr; } App& App::Shared() { FTL_DCHECK(g_app); return *g_app; } void App::WaitForPlatformViewIds( std::vector* platform_view_ids) { ftl::AutoResetWaitableEvent latch; blink::Threads::UI()->PostTask([this, platform_view_ids, &latch]() { WaitForPlatformViewsIdsUIThread(platform_view_ids, &latch); }); latch.Wait(); } void App::WaitForPlatformViewsIdsUIThread( std::vector* platform_view_ids, ftl::AutoResetWaitableEvent* latch) { for (auto it = controllers_.begin(); it != controllers_.end(); it++) { ApplicationControllerImpl* controller = it->first; if (!controller) { continue; } PlatformViewInfo info; // TODO(zra): We should create real IDs for these instead of relying on the // address of the controller. Maybe just use the UI Isolate main port? info.view_id = reinterpret_cast(controller); info.isolate_id = controller->GetUIIsolateMainPort(); info.isolate_name = controller->GetUIIsolateName(); platform_view_ids->push_back(info); } latch->Signal(); } void App::StartApplication( app::ApplicationPackagePtr application, app::ApplicationStartupInfoPtr startup_info, fidl::InterfaceRequest controller) { std::unique_ptr impl = std::make_unique(this, std::move(application), std::move(startup_info), std::move(controller)); ApplicationControllerImpl* key = impl.get(); controllers_.emplace(key, std::move(impl)); } void App::Destroy(ApplicationControllerImpl* controller) { auto it = controllers_.find(controller); if (it == controllers_.end()) return; controllers_.erase(it); } } // namespace flutter_runner