1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/ozone/platform/headless/ozone_platform_headless.h"
6 
7 #include <memory>
8 
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/macros.h"
12 #include "build/build_config.h"
13 #include "ui/base/cursor/cursor_factory.h"
14 #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
15 #include "ui/base/ime/input_method_minimal.h"
16 #include "ui/display/types/native_display_delegate.h"
17 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
18 #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
19 #include "ui/events/platform/platform_event_source.h"
20 #include "ui/ozone/common/stub_overlay_manager.h"
21 #include "ui/ozone/platform/headless/headless_screen.h"
22 #include "ui/ozone/platform/headless/headless_surface_factory.h"
23 #include "ui/ozone/platform/headless/headless_window.h"
24 #include "ui/ozone/platform/headless/headless_window_manager.h"
25 #include "ui/ozone/public/gpu_platform_support_host.h"
26 #include "ui/ozone/public/input_controller.h"
27 #include "ui/ozone/public/ozone_platform.h"
28 #include "ui/ozone/public/ozone_switches.h"
29 #include "ui/ozone/public/system_input_injector.h"
30 #include "ui/platform_window/platform_window_init_properties.h"
31 
32 #if defined(OS_FUCHSIA)
33 #include "ui/base/ime/fuchsia/input_method_fuchsia.h"
34 #endif
35 
36 namespace ui {
37 
38 namespace {
39 
40 // A headless implementation of PlatformEventSource that we can instantiate to
41 // make
42 // sure that the PlatformEventSource has an instance while in unit tests.
43 class HeadlessPlatformEventSource : public PlatformEventSource {
44  public:
45   HeadlessPlatformEventSource() = default;
46   ~HeadlessPlatformEventSource() override = default;
47 
48  private:
49   DISALLOW_COPY_AND_ASSIGN(HeadlessPlatformEventSource);
50 };
51 
52 // OzonePlatform for headless mode
53 class OzonePlatformHeadless : public OzonePlatform {
54  public:
OzonePlatformHeadless(const base::FilePath & dump_file)55   explicit OzonePlatformHeadless(const base::FilePath& dump_file)
56       : file_path_(dump_file) {}
57   ~OzonePlatformHeadless() override = default;
58 
59   // OzonePlatform:
GetSurfaceFactoryOzone()60   ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override {
61     return surface_factory_.get();
62   }
GetOverlayManager()63   OverlayManagerOzone* GetOverlayManager() override {
64     return overlay_manager_.get();
65   }
GetCursorFactory()66   CursorFactory* GetCursorFactory() override { return cursor_factory_.get(); }
GetInputController()67   InputController* GetInputController() override {
68     return input_controller_.get();
69   }
GetGpuPlatformSupportHost()70   GpuPlatformSupportHost* GetGpuPlatformSupportHost() override {
71     return gpu_platform_support_host_.get();
72   }
CreateSystemInputInjector()73   std::unique_ptr<SystemInputInjector> CreateSystemInputInjector() override {
74     return nullptr;  // no input injection support.
75   }
CreatePlatformWindow(PlatformWindowDelegate * delegate,PlatformWindowInitProperties properties)76   std::unique_ptr<PlatformWindow> CreatePlatformWindow(
77       PlatformWindowDelegate* delegate,
78       PlatformWindowInitProperties properties) override {
79     return std::make_unique<HeadlessWindow>(delegate, window_manager_.get(),
80                                             properties.bounds);
81   }
CreateNativeDisplayDelegate()82   std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
83       override {
84     return nullptr;
85   }
CreateScreen()86   std::unique_ptr<PlatformScreen> CreateScreen() override {
87     return std::make_unique<HeadlessScreen>();
88   }
CreateInputMethod(internal::InputMethodDelegate * delegate,gfx::AcceleratedWidget widget)89   std::unique_ptr<InputMethod> CreateInputMethod(
90       internal::InputMethodDelegate* delegate,
91       gfx::AcceleratedWidget widget) override {
92 #if defined(OS_FUCHSIA)
93     return std::make_unique<InputMethodFuchsia>(delegate, widget);
94 #else
95     return std::make_unique<InputMethodMinimal>(delegate);
96 #endif
97   }
98 
InitializeUI(const InitParams & params)99   void InitializeUI(const InitParams& params) override {
100     window_manager_ = std::make_unique<HeadlessWindowManager>();
101     surface_factory_ = std::make_unique<HeadlessSurfaceFactory>(file_path_);
102     // This unbreaks tests that create their own.
103     if (!PlatformEventSource::GetInstance())
104       platform_event_source_ = std::make_unique<HeadlessPlatformEventSource>();
105     keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
106     KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
107         keyboard_layout_engine_.get());
108 
109     overlay_manager_ = std::make_unique<StubOverlayManager>();
110     input_controller_ = CreateStubInputController();
111     cursor_factory_ = std::make_unique<BitmapCursorFactoryOzone>();
112     gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
113   }
114 
InitializeGPU(const InitParams & params)115   void InitializeGPU(const InitParams& params) override {
116     if (!surface_factory_)
117       surface_factory_ = std::make_unique<HeadlessSurfaceFactory>(file_path_);
118   }
119 
120  private:
121   std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
122   std::unique_ptr<HeadlessWindowManager> window_manager_;
123   std::unique_ptr<HeadlessSurfaceFactory> surface_factory_;
124   std::unique_ptr<PlatformEventSource> platform_event_source_;
125   std::unique_ptr<CursorFactory> cursor_factory_;
126   std::unique_ptr<InputController> input_controller_;
127   std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
128   std::unique_ptr<OverlayManagerOzone> overlay_manager_;
129   base::FilePath file_path_;
130 
131   DISALLOW_COPY_AND_ASSIGN(OzonePlatformHeadless);
132 };
133 
134 }  // namespace
135 
CreateOzonePlatformHeadless()136 OzonePlatform* CreateOzonePlatformHeadless() {
137   base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
138   base::FilePath location;
139   if (cmd->HasSwitch(switches::kOzoneDumpFile))
140     location = cmd->GetSwitchValuePath(switches::kOzoneDumpFile);
141   cmd->AppendSwitch(switches::kDisableRunningAsSystemCompositor);
142   return new OzonePlatformHeadless(location);
143 }
144 
145 }  // namespace ui
146