From 951b2253cc0a8e33356e28b773a237d18d3694d1 Mon Sep 17 00:00:00 2001 From: Yavor Goulishev Date: Mon, 27 Jan 2025 22:11:04 +0000 Subject: [PATCH] Use the Starboard message pump. The setup is similar to ATV/iOS where the existing platform main thread is re-used and the UI message pump just attaches to it. b/392620765 b/391414243 --- base/BUILD.gn | 10 ++ base/message_loop/message_pump_for_ui.h | 4 + .../message_loop/message_pump_ui_starboard.cc | 10 ++ base/message_loop/message_pump_ui_starboard.h | 27 ++++- base/run_loop.h | 6 + base/task/current_thread.cc | 2 +- base/task/current_thread.h | 11 +- .../sequence_manager/sequence_manager_impl.cc | 8 ++ .../task/sequence_manager/thread_controller.h | 2 +- .../thread_controller_impl.cc | 4 +- .../sequence_manager/thread_controller_impl.h | 2 +- ...hread_controller_with_message_pump_impl.cc | 4 + ...thread_controller_with_message_pump_impl.h | 2 +- base/test/BUILD.gn | 6 + base/test/test_suite.cc | 7 ++ base/test/test_support_starboard.cc | 64 ++++++++++ base/test/test_support_starboard.h | 15 +++ base/threading/thread_restrictions.h | 8 +- cobalt/BUILD.gn | 5 +- cobalt/build/configs/linux-x64x11/args.gn | 12 ++ cobalt/cobalt.cc | 114 +++++++++++++++++- cobalt/cobalt_main_delegate.cc | 36 ++++++ cobalt/cobalt_main_delegate.h | 12 ++ .../platform_event_source_starboard.cc | 25 +--- .../platform_event_source_starboard.h | 16 +-- content/app/content_main.cc | 2 +- content/app/content_main_runner_impl.cc | 4 +- content/shell/app/shell_main_delegate.cc | 2 +- content/shell/browser/shell.cc | 2 + content/zygote/zygote_main_linux.cc | 3 +- device/BUILD.gn | 11 ++ ui/ozone/platform/starboard/BUILD.gn | 4 +- .../starboard/ozone_platform_starboard.cc | 7 +- 33 files changed, 385 insertions(+), 62 deletions(-) create mode 100644 base/test/test_support_starboard.cc create mode 100644 base/test/test_support_starboard.h rename {ui/ozone/platform/starboard => cobalt}/platform_event_source_starboard.cc (92%) rename {ui/ozone/platform/starboard => cobalt}/platform_event_source_starboard.h (74%) diff --git a/base/BUILD.gn b/base/BUILD.gn index 78533e218e88..46ba4a958a25 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -1005,6 +1005,12 @@ component("base") { ] } + if (is_starboard) { + sources += [ + "message_loop/message_pump_ui_starboard.cc", + "message_loop/message_pump_ui_starboard.h", + ] + } if (is_linux || is_chromeos) { sources += [ "debug/proc_maps_linux.cc", @@ -1066,6 +1072,10 @@ component("base") { deps += [ "//base/time/buildflags:buildflags" ] } + if (is_starboard) { + deps += [ "//starboard($starboard_toolchain)" ] + } + if (build_rust_json_reader) { deps += [ "//third_party/rust/serde_json_lenient/v0_1/wrapper" ] } diff --git a/base/message_loop/message_pump_for_ui.h b/base/message_loop/message_pump_for_ui.h index e0abe310cf0c..c39e3a69e06f 100644 --- a/base/message_loop/message_pump_for_ui.h +++ b/base/message_loop/message_pump_for_ui.h @@ -14,6 +14,8 @@ #include "base/message_loop/message_pump_win.h" #elif BUILDFLAG(IS_ANDROID) #include "base/message_loop/message_pump_android.h" +#elif BUILDFLAG(IS_STARBOARD) +#include "base/message_loop/message_pump_ui_starboard.h" #elif BUILDFLAG(IS_APPLE) #include "base/message_loop/message_pump.h" #elif BUILDFLAG(IS_NACL) || BUILDFLAG(IS_AIX) @@ -34,6 +36,8 @@ using MessagePumpForUI = MessagePumpForUI; #elif BUILDFLAG(IS_ANDROID) // Android defines it as-is. using MessagePumpForUI = MessagePumpForUI; +#elif BUILDFLAG(IS_STARBOARD) +using MessagePumpForUI = MessagePumpUIStarboard; #elif BUILDFLAG(IS_APPLE) // MessagePumpForUI isn't bound to a specific impl on Mac. While each impl can // be represented by a plain MessagePump: MessagePumpMac::Create() must be used diff --git a/base/message_loop/message_pump_ui_starboard.cc b/base/message_loop/message_pump_ui_starboard.cc index 142be66d5364..3f8f15e48479 100644 --- a/base/message_loop/message_pump_ui_starboard.cc +++ b/base/message_loop/message_pump_ui_starboard.cc @@ -15,6 +15,7 @@ #include "base/message_loop/message_pump_ui_starboard.h" #include "base/logging.h" +#include "base/notreached.h" #include "base/time/time.h" #include "starboard/event.h" #include "starboard/system.h" @@ -107,11 +108,20 @@ void MessagePumpUIStarboard::Attach(Delegate* delegate) { // return control back to the Looper. SetDelegate(delegate); + + run_loop_ = std::make_unique(); + // Since the RunLoop was just created above, BeforeRun should be guaranteed to + // return true (it only returns false if the RunLoop has been Quit already). + CHECK(run_loop_->BeforeRun()); } void MessagePumpUIStarboard::Quit() { delegate_ = nullptr; CancelAll(); + if (run_loop_) { + run_loop_->AfterRun(); + run_loop_ = nullptr; + } } void MessagePumpUIStarboard::ScheduleWork() { diff --git a/base/message_loop/message_pump_ui_starboard.h b/base/message_loop/message_pump_ui_starboard.h index a60b11c05477..043092fcc4ca 100644 --- a/base/message_loop/message_pump_ui_starboard.h +++ b/base/message_loop/message_pump_ui_starboard.h @@ -19,6 +19,8 @@ #include "base/base_export.h" #include "base/message_loop/message_pump.h" +#include "base/message_loop/watchable_io_message_pump_posix.h" +#include "base/run_loop.h" #include "base/synchronization/lock.h" #include "base/time/time.h" #include "starboard/event.h" @@ -37,8 +39,28 @@ namespace base { // Starboard message pump as a MessageLoop. That would typically be for the // entire lifetime of the application, and in that case, the MessageLoop would // traditionally be deleted in the kSbEventStop handler. -class BASE_EXPORT MessagePumpUIStarboard : public MessagePump { +class BASE_EXPORT MessagePumpUIStarboard : public MessagePump, public WatchableIOMessagePumpPosix { public: + + // TODO (cobalt b/393772370): Remove the stub FD support when x11/wayland are disabled. + class FdWatchController : public FdWatchControllerInterface { + public: + explicit FdWatchController(const Location& from_here): FdWatchControllerInterface(from_here) {} + + FdWatchController(const FdWatchController&) = delete; + FdWatchController& operator=(const FdWatchController&) = delete; + + ~FdWatchController() override {} + + bool StopWatchingFileDescriptor() override {} + }; + + bool WatchFileDescriptor(int fd, + bool persistent, + int mode, + FdWatchController* controller, + FdWatcher* delegate) {} + MessagePumpUIStarboard(); virtual ~MessagePumpUIStarboard() { Quit(); } @@ -83,6 +105,9 @@ class BASE_EXPORT MessagePumpUIStarboard : public MessagePump { // If the delegate has been removed, Quit() has been called. bool should_quit() const { return delegate_ == nullptr; } + // Maintain a RunLoop attached to the starboard thread. + std::unique_ptr run_loop_; + // The MessagePump::Delegate configured in Start(). Delegate* delegate_; diff --git a/base/run_loop.h b/base/run_loop.h index 3da3cc78169c..0294fccb7a86 100644 --- a/base/run_loop.h +++ b/base/run_loop.h @@ -286,6 +286,12 @@ class BASE_EXPORT RunLoop { friend class MessagePumpUIApplication; #endif +#if BUILDFLAG(IS_STARBOARD) + // Starboard doesn't support the blocking RunLoop::Run, so it calls + // BeforeRun and AfterRun directly. + friend class MessagePumpUIStarboard; +#endif // BUILDFLAG(IS_STARBOARD) + // Support for //base/test/scoped_run_loop_timeout.h. friend class test::ScopedRunLoopTimeout; friend class test::ScopedDisableRunLoopTimeout; diff --git a/base/task/current_thread.cc b/base/task/current_thread.cc index b062ee6f827b..f222b1c28651 100644 --- a/base/task/current_thread.cc +++ b/base/task/current_thread.cc @@ -149,7 +149,7 @@ MessagePumpForUI* CurrentUIThread::GetMessagePumpForUI() const { return static_cast(current_->GetMessagePump()); } -#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_STARBOARD) bool CurrentUIThread::WatchFileDescriptor( int fd, bool persistent, diff --git a/base/task/current_thread.h b/base/task/current_thread.h index c7e113456e01..27ab8f597211 100644 --- a/base/task/current_thread.h +++ b/base/task/current_thread.h @@ -213,7 +213,16 @@ class BASE_EXPORT CurrentUIThread : public CurrentThread { CurrentUIThread* operator->() { return this; } -#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) +// TODO (cobalt b/393772370): Remove when x11/wayland are disabled. +#if BUILDFLAG(IS_STARBOARD) + bool WatchFileDescriptor(int fd, + bool persistent, + MessagePumpForUI::Mode mode, + MessagePumpForUI::FdWatchController* controller, + MessagePumpForUI::FdWatcher* delegate) { return false; } +#endif + +#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_STARBOARD) static_assert( std::is_base_of::value, "CurrentThreadForUI::WatchFileDescriptor is supported only" diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index e688f876762c..ffaa5eb9a0ec 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc @@ -337,6 +337,14 @@ void SequenceManagerImpl::BindToMessagePump(std::unique_ptr pump) { controller_->AttachToMessagePump(); } #endif + + // On Starboard attach to the Starboard loop. +#if BUILDFLAG(IS_STARBOARD) + if (settings_.message_loop_type == MessagePumpType::UI) { + controller_->AttachToMessagePump(); + } +#endif // BUILDFLAG(IS_STARBOARD) + } void SequenceManagerImpl::BindToCurrentThread() { diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h index 138bdcdda77a..78ea23015ec2 100644 --- a/base/task/sequence_manager/thread_controller.h +++ b/base/task/sequence_manager/thread_controller.h @@ -132,7 +132,7 @@ class BASE_EXPORT ThreadController { // Returns true if the current run loop should quit when idle. virtual bool ShouldQuitRunLoopWhenIdle() = 0; -#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD) // On iOS, the main message loop cannot be Run(). Instead call // AttachToMessagePump(), which connects this ThreadController to the // UI thread's CFRunLoop and allows PostTask() to work. diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc index 424a7af54466..519938a64037 100644 --- a/base/task/sequence_manager/thread_controller_impl.cc +++ b/base/task/sequence_manager/thread_controller_impl.cc @@ -363,11 +363,11 @@ MessagePump* ThreadControllerImpl::GetBoundMessagePump() const { return nullptr; } -#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD) void ThreadControllerImpl::AttachToMessagePump() { NOTREACHED(); } -#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD) #if BUILDFLAG(IS_IOS) void ThreadControllerImpl::DetachFromMessagePump() { diff --git a/base/task/sequence_manager/thread_controller_impl.h b/base/task/sequence_manager/thread_controller_impl.h index f49f71b147ed..6fe501499691 100644 --- a/base/task/sequence_manager/thread_controller_impl.h +++ b/base/task/sequence_manager/thread_controller_impl.h @@ -61,7 +61,7 @@ class BASE_EXPORT ThreadControllerImpl : public ThreadController, void SetTaskExecutionAllowed(bool allowed) override; bool IsTaskExecutionAllowed() const override; MessagePump* GetBoundMessagePump() const override; -#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD) void AttachToMessagePump() override; #endif #if BUILDFLAG(IS_IOS) diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc index 7e027675a960..833ed797bad7 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc @@ -738,6 +738,10 @@ void ThreadControllerWithMessagePumpImpl::AttachToMessagePump() { main_thread_only().can_change_batch_size = false; static_cast(pump_.get())->Attach(this); } +#elif BUILDFLAG(IS_STARBOARD) +void ThreadControllerWithMessagePumpImpl::AttachToMessagePump() { + static_cast(pump_.get())->Attach(this); +} #endif bool ThreadControllerWithMessagePumpImpl::ShouldQuitRunLoopWhenIdle() { diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h index 5f5b42fbb487..c8456545862c 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h @@ -74,7 +74,7 @@ class BASE_EXPORT ThreadControllerWithMessagePumpImpl bool IsTaskExecutionAllowed() const override; MessagePump* GetBoundMessagePump() const override; void PrioritizeYieldingToNative(base::TimeTicks prioritize_until) override; -#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD) void AttachToMessagePump() override; #endif #if BUILDFLAG(IS_IOS) diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index cc75b7235f43..4d023b8b70c1 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn @@ -222,6 +222,12 @@ static_library("test_support") { ] } + if (is_starboard) { + sources += [ + "test_support_starboard.cc", + "test_support_starboard.h", + ] + } if (is_android) { sources += [ "android/java_handler_thread_helpers.cc", diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index e323e705327e..84422f3bded9 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc @@ -90,6 +90,9 @@ #include "base/allocator/partition_alloc_support.h" #endif // BUILDFLAG(USE_PARTITION_ALLOC) +#if BUILDFLAG(IS_STARBOARD) +#include "base/test/test_support_starboard.h" +#endif namespace base { namespace { @@ -624,6 +627,10 @@ void TestSuite::Initialize() { InitAndroidTestMessageLoop(); #endif // else BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_STARBOARD) + InitStarboardTestMessageLoop(); +#endif + CHECK(debug::EnableInProcessStackDumping()); #if BUILDFLAG(IS_WIN) RouteStdioToConsole(true); diff --git a/base/test/test_support_starboard.cc b/base/test/test_support_starboard.cc new file mode 100644 index 000000000000..800e8787fc0b --- /dev/null +++ b/base/test/test_support_starboard.cc @@ -0,0 +1,64 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/logging.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/singleton.h" +#include "base/message_loop/message_pump.h" +#include "base/message_loop/message_pump_default.h" +#include "base/message_loop/message_pump_for_ui.h" +#include "base/synchronization/waitable_event.h" + +namespace { + +class MessagePumpForUIStub : public base::MessagePumpUIStarboard { + public: + + MessagePumpForUIStub() : base::MessagePumpForUI(), default_pump_ (new base::MessagePumpDefault) { } + ~MessagePumpForUIStub() override {} + + // Similar to Android, in Starboad tests there isn't a native thread, + // as such RunLoop::Run() should be used to run the loop instead of attaching + // and delegating to the native loop. + // As such, this override ignores the Attach() request. + void Attach(base::MessagePump::Delegate* delegate) override {} + + // --- Delegate to the MessagePumpDefault Implementation --- + + virtual void Run(Delegate* delegate) override { + default_pump_->Run(delegate); + } + + virtual void Quit() override { + default_pump_->Quit(); + } + + virtual void ScheduleWork() override { + default_pump_->ScheduleWork(); + } + + virtual void ScheduleDelayedWork( + const Delegate::NextWorkInfo& next_work_info) override { + default_pump_->ScheduleDelayedWork(next_work_info); + } + + private: + std::unique_ptr default_pump_; +}; + +std::unique_ptr CreateMessagePumpForUIStub() { + return std::unique_ptr(new MessagePumpForUIStub()); +} + +} // namespace + +namespace base { + + +void InitStarboardTestMessageLoop() { + if (!MessagePump::IsMessagePumpForUIFactoryOveridden()) + MessagePump::OverrideMessagePumpForUIFactory(&CreateMessagePumpForUIStub); +} + +} // namespace base diff --git a/base/test/test_support_starboard.h b/base/test/test_support_starboard.h new file mode 100644 index 000000000000..22556485b62b --- /dev/null +++ b/base/test/test_support_starboard.h @@ -0,0 +1,15 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TEST_TEST_SUPPORT_STARBOARD_H_ +#define BASE_TEST_TEST_SUPPORT_STARBOARD_H_ + +namespace base { + +// Init the message loop for tests on Starboard. +void InitStarboardTestMessageLoop(); + +} // namespace base + +#endif // BASE_TEST_TEST_SUPPORT_STARBOARD_H_ diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 4c9ff4452fa1..f22c825fe4be 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h @@ -216,9 +216,9 @@ class BrowserGpuChannelHostFactory; class BrowserMainLoop; class BrowserProcessIOThread; class BrowserTestBase; -#if BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD) class ContentMainRunnerImpl; -#endif // BUILDFLAG(IS_IOS) +#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD) class DesktopCaptureDevice; class DWriteFontCollectionProxy; class DWriteFontProxyImpl; @@ -1006,9 +1006,9 @@ class BASE_EXPORT PermanentThreadAllowance { friend class base::TestCustomDisallow; friend class content::BrowserMainLoop; friend class content::BrowserTestBase; -#if BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD) friend class content::ContentMainRunnerImpl; -#endif // BUILDFLAG(IS_IOS) +#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD) friend class web::WebMainLoop; static void AllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; diff --git a/cobalt/BUILD.gn b/cobalt/BUILD.gn index 4a27954a1cc7..13c38bc6a3dd 100644 --- a/cobalt/BUILD.gn +++ b/cobalt/BUILD.gn @@ -19,7 +19,7 @@ group("gn_all") { # TODO(b/371589344): Fix android build configs. deps = [ - "//starboard($starboard_toolchain)", + "//starboard:starboard_group", "//starboard/nplb", ] if (!is_android) { @@ -38,6 +38,8 @@ if (!is_android) { "cobalt.cc", "cobalt_main_delegate.cc", "cobalt_main_delegate.h", + "platform_event_source_starboard.cc", + "platform_event_source_starboard.h", ] defines = [] @@ -50,6 +52,7 @@ if (!is_android) { "//content/shell:content_shell_lib", "//content/shell:pak", "//sandbox", + "//starboard:starboard_group", "//third_party/blink/public/common", ] diff --git a/cobalt/build/configs/linux-x64x11/args.gn b/cobalt/build/configs/linux-x64x11/args.gn index a40a0535bc6d..2b2b315595ba 100644 --- a/cobalt/build/configs/linux-x64x11/args.gn +++ b/cobalt/build/configs/linux-x64x11/args.gn @@ -18,3 +18,15 @@ enable_nacl = false # Overriding the flag from //ui/gl/features.gni use_static_angle = true + +# Disable udev +use_udev = false + +# Disable glib +use_glib = false + +# Disable PipeWire in WebRTC +rtc_use_pipewire = false + +# Disable Chrome Remote Desktop +enable_remoting = false diff --git a/cobalt/cobalt.cc b/cobalt/cobalt.cc index a40c172d0861..00be23125ddf 100644 --- a/cobalt/cobalt.cc +++ b/cobalt/cobalt.cc @@ -18,13 +18,36 @@ #include #include +#include "base/at_exit.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/no_destructor.h" #include "build/build_config.h" #include "cobalt/cobalt_main_delegate.h" +#include "cobalt/platform_event_source_starboard.h" #include "content/public/app/content_main.h" +#include "content/public/app/content_main_runner.h" +#include "content/shell/browser/shell.h" +#include "starboard/event.h" -int main(int argc, const char** argv) { - cobalt::CobaltMainDelegate delegate; - content::ContentMainParams params(&delegate); +using starboard::PlatformEventSourceStarboard; + +namespace { + +content::ContentMainRunner* GetContentMainRunner() { + static base::NoDestructor> runner{ + content::ContentMainRunner::Create()}; + return runner->get(); +} + +static base::AtExitManager* g_exit_manager = nullptr; +static cobalt::CobaltMainDelegate* g_content_main_delegate = nullptr; +static PlatformEventSourceStarboard* g_platform_event_source = nullptr; +} // namespace + +int InitCobalt(int argc, const char** argv, const char* initial_deep_link) { + // content::ContentMainParams params(g_content_main_delegate.Get().get()); + content::ContentMainParams params(g_content_main_delegate); // TODO: (cobalt b/375241103) Reimplement this in a clean way. constexpr auto cobalt_args = std::to_array( @@ -48,7 +71,7 @@ int main(int argc, const char** argv) { "--remote-allow-origins=http://localhost:9222", // This flag is added specifically for m114 and should be removed after // rebasing to m120+ - "--user-level-memory-pressure-signal-params", + "--user-level-memory-pressure-signal-params", "--no-sandbox", "https://www.youtube.com/tv"}); std::vector args(argv, argv + argc); args.insert(args.end(), cobalt_args.begin(), cobalt_args.end()); @@ -64,5 +87,86 @@ int main(int argc, const char** argv) { params.argc = args.size(); params.argv = args.data(); } - return content::ContentMain(std::move(params)); + + return RunContentProcess(std::move(params), GetContentMainRunner()); +} + +void SbEventHandle(const SbEvent* event) { + switch (event->type) { + case kSbEventTypePreload: { + SbEventStartData* data = static_cast(event->data); + g_exit_manager = new base::AtExitManager(); + g_content_main_delegate = new cobalt::CobaltMainDelegate(); + g_platform_event_source = new PlatformEventSourceStarboard(); + // TODO: (cobalt b/392613336) Initialize the musl hardware capabilities. + // init_musl_hwcap(); + InitCobalt(data->argument_count, + const_cast(data->argument_values), data->link); + + break; + } + case kSbEventTypeStart: { + SbEventStartData* data = static_cast(event->data); + + g_exit_manager = new base::AtExitManager(); + g_content_main_delegate = new cobalt::CobaltMainDelegate(); + g_platform_event_source = new PlatformEventSourceStarboard(); + // TODO: (cobalt b/392613336 Initialize the musl hardware capabilities. + // init_musl_hwcap(); + InitCobalt(data->argument_count, + const_cast(data->argument_values), data->link); + break; + } + case kSbEventTypeStop: { + content::Shell::Shutdown(); + + g_content_main_delegate->Shutdown(); + + GetContentMainRunner()->Shutdown(); + + delete g_content_main_delegate; + g_content_main_delegate = nullptr; + + delete g_platform_event_source; + g_platform_event_source = nullptr; + + delete g_exit_manager; + g_exit_manager = nullptr; + break; + } + case kSbEventTypeBlur: + case kSbEventTypeFocus: + case kSbEventTypeConceal: + case kSbEventTypeReveal: + case kSbEventTypeFreeze: + case kSbEventTypeUnfreeze: + break; + case kSbEventTypeInput: + if (g_platform_event_source) { + g_platform_event_source->HandleEvent(event); + } + break; + case kSbEventTypeUser: + case kSbEventTypeLink: + case kSbEventTypeVerticalSync: + case kSbEventTypeScheduled: + case kSbEventTypeAccessibilitySettingsChanged: + case kSbEventTypeLowMemory: + case kSbEventTypeWindowSizeChanged: + case kSbEventTypeOnScreenKeyboardShown: + case kSbEventTypeOnScreenKeyboardHidden: + case kSbEventTypeOnScreenKeyboardFocused: + case kSbEventTypeOnScreenKeyboardBlurred: + case kSbEventTypeAccessibilityCaptionSettingsChanged: + case kSbEventTypeAccessibilityTextToSpeechSettingsChanged: + case kSbEventTypeOsNetworkDisconnected: + case kSbEventTypeOsNetworkConnected: + case kSbEventDateTimeConfigurationChanged: + case kSbEventTypeReserved1: + break; + } +} + +int main(int argc, char** argv) { + return SbRunStarboardMain(argc, argv, SbEventHandle); } diff --git a/cobalt/cobalt_main_delegate.cc b/cobalt/cobalt_main_delegate.cc index b549f5ecb924..47d995ba6a81 100644 --- a/cobalt/cobalt_main_delegate.cc +++ b/cobalt/cobalt_main_delegate.cc @@ -13,8 +13,12 @@ // limitations under the License. #include "cobalt/cobalt_main_delegate.h" + +#include "base/process/current_process.h" +#include "base/trace_event/trace_log.h" #include "cobalt/browser/cobalt_content_browser_client.h" #include "cobalt/renderer/cobalt_content_renderer_client.h" +#include "content/common/content_constants_internal.h" #include "content/public/browser/render_frame_host.h" namespace cobalt { @@ -43,4 +47,36 @@ absl::optional CobaltMainDelegate::PostEarlyInitialization( return ShellMainDelegate::PostEarlyInitialization(invoked_in); } +absl::variant CobaltMainDelegate::RunProcess( + const std::string& process_type, + content::MainFunctionParams main_function_params) { + // For non-browser process, return and have the caller run the main loop. + if (!process_type.empty()) { + return std::move(main_function_params); + } + + base::CurrentProcess::GetInstance().SetProcessType( + base::CurrentProcessType::PROCESS_BROWSER); + base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex( + content::kTraceEventBrowserProcessSortIndex); + + main_runner_ = content::BrowserMainRunner::Create(); + + // In browser tests, the |main_function_params| contains a |ui_task| which + // will execute the testing. The task will be executed synchronously inside + // Initialize() so we don't depend on the BrowserMainRunner being Run(). + int initialize_exit_code = + main_runner_->Initialize(std::move(main_function_params)); + DCHECK_LT(initialize_exit_code, 0) + << "BrowserMainRunner::Initialize failed in ShellMainDelegate"; + + // Return 0 as BrowserMain() should not be called after this, bounce up to + // the system message loop for ContentShell, and we're already done thanks + // to the |ui_task| for browser tests. + return 0; +} + +void CobaltMainDelegate::Shutdown() { + main_runner_->Shutdown(); +} } // namespace cobalt diff --git a/cobalt/cobalt_main_delegate.h b/cobalt/cobalt_main_delegate.h index 146fdd9ce1a2..f1b1d8f3f4e4 100644 --- a/cobalt/cobalt_main_delegate.h +++ b/cobalt/cobalt_main_delegate.h @@ -17,6 +17,7 @@ #include "build/build_config.h" #include "cobalt/renderer/cobalt_content_renderer_client.h" +#include "content/public/browser/browser_main_runner.h" #include "content/shell/app/shell_main_delegate.h" namespace cobalt { @@ -33,9 +34,20 @@ class CobaltMainDelegate : public content::ShellMainDelegate { content::ContentRendererClient* CreateContentRendererClient() override; absl::optional PostEarlyInitialization(InvokedIn invoked_in) override; + // Override the RunProcess method to store the reference to + // BrowserMainRunner instead of leaking it. The reference would + // be used for proper shutdown and cleanup. + absl::variant RunProcess( + const std::string& process_type, + content::MainFunctionParams main_function_params) override; + + // Shutdown method that trigger the BrowserMainRunner shutdown. + void Shutdown(); + ~CobaltMainDelegate() override; private: + std::unique_ptr main_runner_; std::unique_ptr renderer_client_; }; diff --git a/ui/ozone/platform/starboard/platform_event_source_starboard.cc b/cobalt/platform_event_source_starboard.cc similarity index 92% rename from ui/ozone/platform/starboard/platform_event_source_starboard.cc rename to cobalt/platform_event_source_starboard.cc index 1caf4969f6f8..4373e2587fbc 100644 --- a/ui/ozone/platform/starboard/platform_event_source_starboard.cc +++ b/cobalt/platform_event_source_starboard.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "ui/ozone/platform/starboard/platform_event_source_starboard.h" +#include "cobalt/platform_event_source_starboard.h" #include "base/logging.h" #include "starboard/event.h" @@ -22,6 +22,7 @@ #include "ui/events/event.h" #include "base/containers/fixed_flat_map.h" +#include "base/task/single_thread_task_runner.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/dom_key.h" #include "ui/events/keycodes/keyboard_code_conversion.h" @@ -197,10 +198,6 @@ constexpr auto kSbKeyToDomCodeMap = base::MakeFixedFlatMap({ {kSbKeyTab, ui::DomCode::TAB}, {kSbKeyEscape, ui::DomCode::ESCAPE}, }); -// TODO(b/391414243): Implement this in a clean way. -#if BUILDFLAG(ENABLE_COBALT_HACKS) -static scoped_refptr g_reply_runner_; -#endif // BUILDFLAG(ENABLE_COBALT_HACKS) void DeliverEventHandler(std::unique_ptr ui_event) { CHECK(ui::PlatformEventSource::GetInstance()); @@ -209,7 +206,7 @@ void DeliverEventHandler(std::unique_ptr ui_event) { ->DeliverEvent(std::move(ui_event)); } -void PlatformEventSourceStarboard::SbEventHandle(const SbEvent* event) { +void PlatformEventSourceStarboard::HandleEvent(const SbEvent* event) { if (event->type != kSbEventTypeInput) { return; } @@ -307,22 +304,11 @@ void PlatformEventSourceStarboard::SbEventHandle(const SbEvent* event) { } else { return; } - // TODO(b/391414243): Implement this in a clean way. -#if BUILDFLAG(ENABLE_COBALT_HACKS) - g_reply_runner_->PostTask( + base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(&DeliverEventHandler, std::move(ui_event))); -#endif // BUILDFLAG(ENABLE_COBALT_HACKS) } -PlatformEventSourceStarboard::PlatformEventSourceStarboard() { - // TODO(b/391414243): Initialize Starboard correctly. -#if BUILDFLAG(ENABLE_COBALT_HACKS) - sb_main_ = std::make_unique(&SbRunStarboardMain, /*argc=*/0, - /*argv=*/nullptr, &SbEventHandle); - g_reply_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault(); - sb_main_->detach(); -#endif // BUILDFLAG(ENABLE_COBALT_HACKS) -} +PlatformEventSourceStarboard::PlatformEventSourceStarboard() {} uint32_t PlatformEventSourceStarboard::DeliverEvent( std::unique_ptr ui_event) { @@ -330,4 +316,5 @@ uint32_t PlatformEventSourceStarboard::DeliverEvent( } PlatformEventSourceStarboard::~PlatformEventSourceStarboard() {} + } // namespace starboard diff --git a/ui/ozone/platform/starboard/platform_event_source_starboard.h b/cobalt/platform_event_source_starboard.h similarity index 74% rename from ui/ozone/platform/starboard/platform_event_source_starboard.h rename to cobalt/platform_event_source_starboard.h index afe6526588d4..801d632eff0b 100644 --- a/ui/ozone/platform/starboard/platform_event_source_starboard.h +++ b/cobalt/platform_event_source_starboard.h @@ -12,16 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_ -#define UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_ +#ifndef COBALT_PLATFORM_EVENT_SOURCE_H_ +#define COBALT_PLATFORM_EVENT_SOURCE_H_ #include "ui/events/platform/platform_event_source.h" -#include "base/task/single_thread_task_runner.h" #include "starboard/event.h" -#include - namespace starboard { class PlatformEventSourceStarboard : public ui::PlatformEventSource { @@ -32,16 +29,13 @@ class PlatformEventSourceStarboard : public ui::PlatformEventSource { PlatformEventSourceStarboard& operator=(const PlatformEventSourceStarboard&) = delete; - ~PlatformEventSourceStarboard() override; + void HandleEvent(const SbEvent* event); - static void SbEventHandle(const SbEvent* event); + ~PlatformEventSourceStarboard() override; uint32_t DeliverEvent(std::unique_ptr ui_event); - - private: - std::unique_ptr sb_main_; }; } // namespace starboard -#endif // UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_ +#endif // COBALT_PLATFORM_EVENT_SOURCE_H_ diff --git a/content/app/content_main.cc b/content/app/content_main.cc index 3062f5760332..14d931ab0ac0 100644 --- a/content/app/content_main.cc +++ b/content/app/content_main.cc @@ -329,7 +329,7 @@ RunContentProcess(ContentMainParams params, autorelease_pool.reset(); #endif -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_STARBOARD) content_main_runner->Shutdown(); #endif diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 38c5f465d8e4..2139bd19e39d 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc @@ -843,7 +843,7 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) { // On Android, AtExitManager is set up when library is loaded. // A consequence of this is that you can't use the ctor/dtor-based // TRACE_EVENT methods on Linux or iOS builds till after we set this up. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_STARBOARD) if (!content_main_params_->ui_task) { // When running browser tests, don't create a second AtExitManager as that // interfers with shutdown when objects created before ContentMain is @@ -1280,7 +1280,7 @@ void ContentMainRunnerImpl::Shutdown() { DCHECK(is_initialized_); DCHECK(!is_shutdown_); -#if BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD) // This would normally be handled by BrowserMainLoop shutdown, but since iOS // (like Android) does not run this shutdown, we also need to ensure that we // permit sync primitives during shutdown. If we don't do this, eg, tearing diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc index 85f27dd847b7..da6cc4555400 100644 --- a/content/shell/app/shell_main_delegate.cc +++ b/content/shell/app/shell_main_delegate.cc @@ -248,7 +248,7 @@ absl::variant ShellMainDelegate::RunProcess( base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex( kTraceEventBrowserProcessSortIndex); -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD) // On Android and iOS, we defer to the system message loop when the stack // unwinds. So here we only create (and leak) a BrowserMainRunner. The // shutdown of BrowserMainRunner doesn't happen in Chrome Android/iOS and diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index 40835b205377..756c078a90c3 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc @@ -200,8 +200,10 @@ void Shell::Shutdown() { if (quit_loop) std::move(quit_loop).Run(); +#if !BUILDFLAG(IS_STARBOARD) // Pump the message loop to allow window teardown tasks to run. base::RunLoop().RunUntilIdle(); +#endif // !BUILDFLAG(IS_STARBOARD) } gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) { diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc index c7ee91878e6d..206e47e2e015 100644 --- a/content/zygote/zygote_main_linux.cc +++ b/content/zygote/zygote_main_linux.cc @@ -141,7 +141,8 @@ static void EnterLayerOneSandbox(sandbox::policy::SandboxLinux* linux_sandbox, // Check that the pre-sandbox initialization didn't spawn threads. // It's not just our code which may do so - some system-installed libraries // are known to be culprits, e.g. lttng. -#if !defined(THREAD_SANITIZER) +// TODO: (cobalt b/393131403) Investigate clean way to turn off Zygote support. +#if !defined(THREAD_SANITIZER) && !BUILDFLAG(IS_STARBOARD) CHECK(sandbox::ThreadHelpers::IsSingleThreaded()); #endif diff --git a/device/BUILD.gn b/device/BUILD.gn index 44d174a1fb05..a18a9f283031 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn @@ -454,6 +454,17 @@ test("device_unittests") { if (is_chromeos) { deps += [ "//chromeos/dbus/u2f" ] } + + # The following tests fail to build when udev is disabled. + if (is_cobalt && is_linux_without_udev) { + sources -= [ + "fido/ble_adapter_manager_unittest.cc", + "fido/fake_fido_discovery_unittest.cc", + "fido/fido_request_handler_unittest.cc", + "fido/get_assertion_handler_unittest.cc", + "fido/make_credential_handler_unittest.cc", + ] + } } if (is_android) { diff --git a/ui/ozone/platform/starboard/BUILD.gn b/ui/ozone/platform/starboard/BUILD.gn index 5df2c82e49f0..462b9ddb12a4 100644 --- a/ui/ozone/platform/starboard/BUILD.gn +++ b/ui/ozone/platform/starboard/BUILD.gn @@ -26,8 +26,6 @@ source_set("starboard") { "gl_ozone_egl_starboard.h", "ozone_platform_starboard.cc", "ozone_platform_starboard.h", - "platform_event_source_starboard.cc", - "platform_event_source_starboard.h", "platform_screen_starboard.cc", "platform_screen_starboard.h", "platform_window_starboard.cc", @@ -86,5 +84,5 @@ source_set("test_support") { "ozone_ui_controls_test_helper_starboard.h", ] - deps = [ "//ui/base/x" ] + deps = [ "//base:base" ] } diff --git a/ui/ozone/platform/starboard/ozone_platform_starboard.cc b/ui/ozone/platform/starboard/ozone_platform_starboard.cc index 45a2bf0bf07c..dbbd6198c1a9 100644 --- a/ui/ozone/platform/starboard/ozone_platform_starboard.cc +++ b/ui/ozone/platform/starboard/ozone_platform_starboard.cc @@ -25,7 +25,6 @@ #include "ui/gl/gl_switches.h" #include "ui/ozone/common/bitmap_cursor_factory.h" #include "ui/ozone/common/stub_overlay_manager.h" -#include "ui/ozone/platform/starboard/platform_event_source_starboard.h" #include "ui/ozone/platform/starboard/platform_screen_starboard.h" #include "ui/ozone/platform/starboard/platform_window_starboard.h" #include "ui/ozone/platform/starboard/surface_factory_starboard.h" @@ -119,9 +118,7 @@ class OzonePlatformStarboard : public OzonePlatform { if (!surface_factory_) { surface_factory_ = std::make_unique(); } - // Not thread safe. This is just for prototyping. - platform_event_source_ = - std::make_unique(); + keyboard_layout_engine_ = std::make_unique(); KeyboardLayoutEngineManager::SetKeyboardLayoutEngine( keyboard_layout_engine_.get()); @@ -165,8 +162,6 @@ class OzonePlatformStarboard : public OzonePlatform { std::unique_ptr gpu_platform_support_host_; std::unique_ptr input_controller_; std::unique_ptr overlay_manager_; - std::unique_ptr - platform_event_source_; std::unique_ptr surface_factory_; };