Skip to content

Commit 0db1d90

Browse files
stuartmorgan-ggspencergoog
authored andcommitted
[linux] Allow engine flags via environment vars (flutter#21497)
Adds the ability to pass engine switches temporarily at runtime via environment variables. Uses the same approach recently added to Windows and macOS. This is enabled only for debug/profile to avoid potential issues with tampering with released applications, but if there is a need for that in the future it could be added (potentially with a whitelist, as is currently used for Dart VM flags). Fixes flutter/flutter#60393
1 parent 109c988 commit 0db1d90

File tree

6 files changed

+100
-15
lines changed

6 files changed

+100
-15
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
12791279
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h
12801280
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_test.cc
12811281
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
1282+
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_private.h
12821283
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_test.cc
12831284
FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
12841285
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h

shell/platform/linux/BUILD.gn

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,16 @@ config("relative_flutter_linux_headers") {
6969
}
7070

7171
source_set("flutter_linux_sources") {
72-
public = _public_headers
72+
public = _public_headers + [
73+
"fl_binary_messenger_private.h",
74+
"fl_dart_project_private.h",
75+
"fl_engine_private.h",
76+
"fl_method_call_private.h",
77+
"fl_method_channel_private.h",
78+
"fl_method_codec_private.h",
79+
"fl_plugin_registrar_private.h",
80+
"fl_standard_message_codec_private.h",
81+
]
7382

7483
configs += [ "//flutter/shell/platform/linux/config:gtk" ]
7584

@@ -109,6 +118,7 @@ source_set("flutter_linux_sources") {
109118

110119
deps = [
111120
"//flutter/shell/platform/common/cpp:common_cpp_input",
121+
"//flutter/shell/platform/common/cpp:common_cpp_switches",
112122
"//flutter/shell/platform/embedder:embedder_headers",
113123
"//third_party/rapidjson",
114124
]

shell/platform/linux/fl_dart_project.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
#include <gmodule.h>
88

9+
#include <string>
10+
#include <vector>
11+
12+
#include "flutter/shell/platform/common/cpp/engine_switches.h"
13+
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
14+
915
struct _FlDartProject {
1016
GObject parent_instance;
1117

@@ -91,3 +97,15 @@ G_MODULE_EXPORT const gchar* fl_dart_project_get_icu_data_path(
9197
g_return_val_if_fail(FL_IS_DART_PROJECT(self), nullptr);
9298
return self->icu_data_path;
9399
}
100+
101+
GPtrArray* fl_dart_project_get_switches(FlDartProject* self) {
102+
GPtrArray* switches = g_ptr_array_new_with_free_func(g_free);
103+
std::vector<std::string> env_switches = flutter::GetSwitchesFromEnvironment();
104+
for (const auto& env_switch : env_switches) {
105+
g_ptr_array_add(switches, g_strdup(env_switch.c_str()));
106+
}
107+
if (self->enable_mirrors) {
108+
g_ptr_array_add(switches, g_strdup("--dart-flags=--enable_mirrors=true"));
109+
}
110+
return switches;
111+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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_DART_PROJECT_PRIVATE_H_
6+
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_PRIVATE_H_
7+
8+
#include <glib-object.h>
9+
10+
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
11+
12+
G_BEGIN_DECLS
13+
14+
/**
15+
* fl_dart_project_get_switches:
16+
* @project: an #FlDartProject.
17+
*
18+
* Determines the engine switches that should be passed to the Flutter engine.
19+
*
20+
* Returns: an array of switches to pass to the Flutter engine.
21+
*/
22+
GPtrArray* fl_dart_project_get_switches(FlDartProject* project);
23+
24+
G_END_DECLS
25+
26+
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_PRIVATE_H_

shell/platform/linux/fl_dart_project_test.cc

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
// found in the LICENSE file.
44

55
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
6-
#include "gtest/gtest.h"
76

87
#include <gmodule.h>
98

9+
#include <cstdlib>
10+
11+
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
12+
#include "gtest/gtest.h"
13+
1014
TEST(FlDartProjectTest, GetPaths) {
1115
g_autoptr(FlDartProject) project = fl_dart_project_new();
1216
g_autofree gchar* exe_path = g_file_read_link("/proc/self/exe", nullptr);
@@ -33,3 +37,31 @@ TEST(FlDartProjectTest, EnableMirrors) {
3337
EXPECT_TRUE(fl_dart_project_get_enable_mirrors(project));
3438
G_GNUC_END_IGNORE_DEPRECATIONS
3539
}
40+
41+
TEST(FlDartProjectTest, SwitchesEmpty) {
42+
g_autoptr(FlDartProject) project = fl_dart_project_new();
43+
44+
// Clear the main environment variable, since test order is not guaranteed.
45+
unsetenv("FLUTTER_ENGINE_SWITCHES");
46+
47+
g_autoptr(GPtrArray) switches = fl_dart_project_get_switches(project);
48+
49+
EXPECT_EQ(switches->len, 0U);
50+
}
51+
52+
#ifndef FLUTTER_RELEASE
53+
TEST(FlDartProjectTest, Switches) {
54+
g_autoptr(FlDartProject) project = fl_dart_project_new();
55+
56+
setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
57+
setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
58+
setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);
59+
60+
g_autoptr(GPtrArray) switches = fl_dart_project_get_switches(project);
61+
EXPECT_EQ(switches->len, 2U);
62+
EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 0)),
63+
"--abc");
64+
EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 1)),
65+
"--foo=\"bar, baz\"");
66+
}
67+
#endif // !FLUTTER_RELEASE

shell/platform/linux/fl_engine.cc

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33
// found in the LICENSE file.
44

55
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
6-
#include "flutter/shell/platform/linux/fl_engine_private.h"
6+
7+
#include <gmodule.h>
8+
9+
#include <cstring>
710

811
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
12+
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
13+
#include "flutter/shell/platform/linux/fl_engine_private.h"
914
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
1015
#include "flutter/shell/platform/linux/fl_renderer.h"
1116
#include "flutter/shell/platform/linux/fl_renderer_headless.h"
1217
#include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"
1318

14-
#include <gmodule.h>
15-
#include <cstring>
16-
1719
static constexpr int kMicrosecondsPerNanosecond = 1000;
1820

1921
// Unique number associated with platform tasks.
@@ -373,15 +375,11 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
373375
custom_task_runners.platform_task_runner = &platform_task_runner;
374376

375377
g_autoptr(GPtrArray) command_line_args =
376-
g_ptr_array_new_with_free_func(g_free);
377-
g_ptr_array_add(command_line_args, g_strdup("flutter"));
378-
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
379-
gboolean enable_mirrors = fl_dart_project_get_enable_mirrors(self->project);
380-
G_GNUC_END_IGNORE_DEPRECATIONS
381-
if (enable_mirrors) {
382-
g_ptr_array_add(command_line_args,
383-
g_strdup("--dart-flags=--enable_mirrors=true"));
384-
}
378+
fl_dart_project_get_switches(self->project);
379+
// FlutterProjectArgs expects a full argv, so when processing it for flags
380+
// the first item is treated as the executable and ignored. Add a dummy value
381+
// so that all switches are used.
382+
g_ptr_array_insert(command_line_args, 0, g_strdup("flutter"));
385383

386384
FlutterProjectArgs args = {};
387385
args.struct_size = sizeof(FlutterProjectArgs);

0 commit comments

Comments
 (0)