Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 01e06ed

Browse files
Add support for headless mode (#19038)
1 parent d0f9ef6 commit 01e06ed

File tree

8 files changed

+117
-8
lines changed

8 files changed

+117
-8
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_plugin_registrar_private.h
12421242
FILE: ../../../flutter/shell/platform/linux/fl_plugin_registry.cc
12431243
FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc
12441244
FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
1245+
FILE: ../../../flutter/shell/platform/linux/fl_renderer_headless.cc
1246+
FILE: ../../../flutter/shell/platform/linux/fl_renderer_headless.h
12451247
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
12461248
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
12471249
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec.cc

shell/platform/linux/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ source_set("flutter_linux_sources") {
9494
"fl_plugin_registrar.cc",
9595
"fl_plugin_registry.cc",
9696
"fl_renderer.cc",
97+
"fl_renderer_headless.cc",
9798
"fl_renderer_x11.cc",
9899
"fl_standard_message_codec.cc",
99100
"fl_standard_method_codec.cc",

shell/platform/linux/fl_engine.cc

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
#include "flutter/shell/platform/linux/fl_engine_private.h"
77

88
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
9+
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
910
#include "flutter/shell/platform/linux/fl_renderer.h"
11+
#include "flutter/shell/platform/linux/fl_renderer_headless.h"
12+
#include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"
1013

1114
#include <gmodule.h>
1215

@@ -35,7 +38,15 @@ struct _FlEngine {
3538

3639
G_DEFINE_QUARK(fl_engine_error_quark, fl_engine_error)
3740

38-
G_DEFINE_TYPE(FlEngine, fl_engine, G_TYPE_OBJECT)
41+
static void fl_engine_plugin_registry_iface_init(
42+
FlPluginRegistryInterface* iface);
43+
44+
G_DEFINE_TYPE_WITH_CODE(
45+
FlEngine,
46+
fl_engine,
47+
G_TYPE_OBJECT,
48+
G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
49+
fl_engine_plugin_registry_iface_init))
3950

4051
// Subclass of GSource that integrates Flutter tasks into the GLib main loop.
4152
typedef struct {
@@ -169,6 +180,20 @@ static void fl_engine_platform_message_response_cb(const uint8_t* data,
169180
(GDestroyNotify)g_bytes_unref);
170181
}
171182

183+
// Implements FlPluginRegistry::get_registrar_for_plugin.
184+
static FlPluginRegistrar* fl_engine_get_registrar_for_plugin(
185+
FlPluginRegistry* registry,
186+
const gchar* name) {
187+
FlEngine* self = FL_ENGINE(registry);
188+
189+
return fl_plugin_registrar_new(nullptr, self->binary_messenger);
190+
}
191+
192+
static void fl_engine_plugin_registry_iface_init(
193+
FlPluginRegistryInterface* iface) {
194+
iface->get_registrar_for_plugin = fl_engine_get_registrar_for_plugin;
195+
}
196+
172197
static void fl_engine_dispose(GObject* object) {
173198
FlEngine* self = FL_ENGINE(object);
174199

@@ -210,13 +235,17 @@ FlEngine* fl_engine_new(FlDartProject* project, FlRenderer* renderer) {
210235
g_return_val_if_fail(FL_IS_DART_PROJECT(project), nullptr);
211236
g_return_val_if_fail(FL_IS_RENDERER(renderer), nullptr);
212237

213-
FlEngine* self =
214-
static_cast<FlEngine*>(g_object_new(fl_engine_get_type(), nullptr));
215-
self->project = static_cast<FlDartProject*>(g_object_ref(project));
216-
self->renderer = static_cast<FlRenderer*>(g_object_ref(renderer));
238+
FlEngine* self = FL_ENGINE(g_object_new(fl_engine_get_type(), nullptr));
239+
self->project = FL_DART_PROJECT(g_object_ref(project));
240+
self->renderer = FL_RENDERER(g_object_ref(renderer));
217241
return self;
218242
}
219243

244+
G_MODULE_EXPORT FlEngine* fl_engine_new_headless(FlDartProject* project) {
245+
g_autoptr(FlRendererHeadless) renderer = fl_renderer_headless_new();
246+
return fl_engine_new(project, FL_RENDERER(renderer));
247+
}
248+
220249
gboolean fl_engine_start(FlEngine* self, GError** error) {
221250
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
222251

shell/platform/linux/fl_plugin_registrar.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,15 @@ static void fl_plugin_registrar_init(FlPluginRegistrar* self) {}
4848

4949
FlPluginRegistrar* fl_plugin_registrar_new(FlView* view,
5050
FlBinaryMessenger* messenger) {
51-
g_return_val_if_fail(FL_IS_VIEW(view), nullptr);
51+
g_return_val_if_fail(view == nullptr || FL_IS_VIEW(view), nullptr);
5252
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
5353

5454
FlPluginRegistrar* self = FL_PLUGIN_REGISTRAR(
5555
g_object_new(fl_plugin_registrar_get_type(), nullptr));
5656

5757
self->view = view;
58-
g_object_weak_ref(G_OBJECT(view), view_weak_notify_cb, self);
58+
if (view != nullptr)
59+
g_object_weak_ref(G_OBJECT(view), view_weak_notify_cb, self);
5960
self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));
6061

6162
return self;

shell/platform/linux/fl_plugin_registrar_private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ G_BEGIN_DECLS
1212

1313
/**
1414
* fl_plugin_registrar_new:
15-
* @view: the #FlView that is being plugged into.
15+
* @view: (allow-none): the #FlView that is being plugged into or %NULL for
16+
* headless mode.
1617
* @messenger: the #FlBinaryMessenger to communicate with.
1718
*
1819
* Creates a new #FlPluginRegistrar.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2013 The Flutter 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 "fl_renderer_headless.h"
6+
7+
struct _FlRendererHeadless {
8+
FlRenderer parent_instance;
9+
};
10+
11+
G_DEFINE_TYPE(FlRendererHeadless, fl_renderer_headless, fl_renderer_get_type())
12+
13+
static EGLSurface fl_renderer_headless_create_surface(FlRenderer* renderer,
14+
EGLDisplay display,
15+
EGLConfig config) {
16+
return EGL_NO_SURFACE;
17+
}
18+
19+
static void fl_renderer_headless_class_init(FlRendererHeadlessClass* klass) {
20+
FL_RENDERER_CLASS(klass)->create_surface =
21+
fl_renderer_headless_create_surface;
22+
}
23+
24+
static void fl_renderer_headless_init(FlRendererHeadless* self) {}
25+
26+
FlRendererHeadless* fl_renderer_headless_new() {
27+
return FL_RENDERER_HEADLESS(
28+
g_object_new(fl_renderer_headless_get_type(), nullptr));
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2013 The Flutter 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+
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_HEADLESS_H_
6+
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_HEADLESS_H_
7+
8+
#include "flutter/shell/platform/linux/fl_renderer.h"
9+
10+
G_BEGIN_DECLS
11+
12+
G_DECLARE_FINAL_TYPE(FlRendererHeadless,
13+
fl_renderer_headless,
14+
FL,
15+
RENDERER_HEADLESS,
16+
FlRenderer)
17+
18+
/**
19+
* FlRendererHeadless:
20+
*
21+
* #FlRendererHeadless is an implementation of #FlRenderer that works without a
22+
* display.
23+
*/
24+
25+
/**
26+
* fl_renderer_headless_new:
27+
*
28+
* Creates an object that allows Flutter to operate without a display.
29+
*
30+
* Returns: a new #FlRendererHeadless.
31+
*/
32+
FlRendererHeadless* fl_renderer_headless_new();
33+
34+
G_END_DECLS
35+
36+
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_HEADLESS_H_

shell/platform/linux/public/flutter_linux/fl_engine.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ G_DECLARE_FINAL_TYPE(FlEngine, fl_engine, FL, ENGINE, GObject)
2424
* #FlEngine is an object that contains a running Flutter engine.
2525
*/
2626

27+
/**
28+
* fl_engine_new_headless:
29+
* @project: an #FlDartProject.
30+
*
31+
* Creates new Flutter engine running in headless mode.
32+
*
33+
* Returns: a new #FlEngine.
34+
*/
35+
FlEngine* fl_engine_new_headless(FlDartProject* project);
36+
2737
/**
2838
* fl_engine_get_binary_messenger:
2939
* @engine: an #FlEngine.

0 commit comments

Comments
 (0)