未验证 提交 042c7f04 编写于 作者: S stuartmorgan 提交者: GitHub

[linux] Allow engine flags via environment vars (#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
上级 7e6191de
......@@ -1279,6 +1279,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_private.h
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
......
......@@ -69,7 +69,16 @@ config("relative_flutter_linux_headers") {
}
source_set("flutter_linux_sources") {
public = _public_headers
public = _public_headers + [
"fl_binary_messenger_private.h",
"fl_dart_project_private.h",
"fl_engine_private.h",
"fl_method_call_private.h",
"fl_method_channel_private.h",
"fl_method_codec_private.h",
"fl_plugin_registrar_private.h",
"fl_standard_message_codec_private.h",
]
configs += [ "//flutter/shell/platform/linux/config:gtk" ]
......@@ -109,6 +118,7 @@ source_set("flutter_linux_sources") {
deps = [
"//flutter/shell/platform/common/cpp:common_cpp_input",
"//flutter/shell/platform/common/cpp:common_cpp_switches",
"//flutter/shell/platform/embedder:embedder_headers",
"//third_party/rapidjson",
]
......
......@@ -6,6 +6,12 @@
#include <gmodule.h>
#include <string>
#include <vector>
#include "flutter/shell/platform/common/cpp/engine_switches.h"
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
struct _FlDartProject {
GObject parent_instance;
......@@ -91,3 +97,15 @@ G_MODULE_EXPORT const gchar* fl_dart_project_get_icu_data_path(
g_return_val_if_fail(FL_IS_DART_PROJECT(self), nullptr);
return self->icu_data_path;
}
GPtrArray* fl_dart_project_get_switches(FlDartProject* self) {
GPtrArray* switches = g_ptr_array_new_with_free_func(g_free);
std::vector<std::string> env_switches = flutter::GetSwitchesFromEnvironment();
for (const auto& env_switch : env_switches) {
g_ptr_array_add(switches, g_strdup(env_switch.c_str()));
}
if (self->enable_mirrors) {
g_ptr_array_add(switches, g_strdup("--dart-flags=--enable_mirrors=true"));
}
return switches;
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_PRIVATE_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_PRIVATE_H_
#include <glib-object.h>
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
G_BEGIN_DECLS
/**
* fl_dart_project_get_switches:
* @project: an #FlDartProject.
*
* Determines the engine switches that should be passed to the Flutter engine.
*
* Returns: an array of switches to pass to the Flutter engine.
*/
GPtrArray* fl_dart_project_get_switches(FlDartProject* project);
G_END_DECLS
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_PRIVATE_H_
......@@ -3,10 +3,14 @@
// found in the LICENSE file.
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
#include "gtest/gtest.h"
#include <gmodule.h>
#include <cstdlib>
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
#include "gtest/gtest.h"
TEST(FlDartProjectTest, GetPaths) {
g_autoptr(FlDartProject) project = fl_dart_project_new();
g_autofree gchar* exe_path = g_file_read_link("/proc/self/exe", nullptr);
......@@ -33,3 +37,31 @@ TEST(FlDartProjectTest, EnableMirrors) {
EXPECT_TRUE(fl_dart_project_get_enable_mirrors(project));
G_GNUC_END_IGNORE_DEPRECATIONS
}
TEST(FlDartProjectTest, SwitchesEmpty) {
g_autoptr(FlDartProject) project = fl_dart_project_new();
// Clear the main environment variable, since test order is not guaranteed.
unsetenv("FLUTTER_ENGINE_SWITCHES");
g_autoptr(GPtrArray) switches = fl_dart_project_get_switches(project);
EXPECT_EQ(switches->len, 0U);
}
#ifndef FLUTTER_RELEASE
TEST(FlDartProjectTest, Switches) {
g_autoptr(FlDartProject) project = fl_dart_project_new();
setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);
g_autoptr(GPtrArray) switches = fl_dart_project_get_switches(project);
EXPECT_EQ(switches->len, 2U);
EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 0)),
"--abc");
EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 1)),
"--foo=\"bar, baz\"");
}
#endif // !FLUTTER_RELEASE
......@@ -3,17 +3,19 @@
// found in the LICENSE file.
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include <gmodule.h>
#include <cstring>
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
#include "flutter/shell/platform/linux/fl_renderer.h"
#include "flutter/shell/platform/linux/fl_renderer_headless.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"
#include <gmodule.h>
#include <cstring>
static constexpr int kMicrosecondsPerNanosecond = 1000;
// Unique number associated with platform tasks.
......@@ -373,15 +375,11 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
custom_task_runners.platform_task_runner = &platform_task_runner;
g_autoptr(GPtrArray) command_line_args =
g_ptr_array_new_with_free_func(g_free);
g_ptr_array_add(command_line_args, g_strdup("flutter"));
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gboolean enable_mirrors = fl_dart_project_get_enable_mirrors(self->project);
G_GNUC_END_IGNORE_DEPRECATIONS
if (enable_mirrors) {
g_ptr_array_add(command_line_args,
g_strdup("--dart-flags=--enable_mirrors=true"));
}
fl_dart_project_get_switches(self->project);
// FlutterProjectArgs expects a full argv, so when processing it for flags
// the first item is treated as the executable and ignored. Add a dummy value
// so that all switches are used.
g_ptr_array_insert(command_line_args, 0, g_strdup("flutter"));
FlutterProjectArgs args = {};
args.struct_size = sizeof(FlutterProjectArgs);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册