1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
fuchsia_web / webengine / browser / web_engine_config.cc [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fuchsia_web/webengine/browser/web_engine_config.h"
#include <string_view>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "components/embedder_support/switches.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/viz/common/features.h"
#include "components/viz/common/switches.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "fuchsia_web/webengine/switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_switches.h"
#include "media/base/media_switches.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "ui/display/display_switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/ozone/public/ozone_switches.h"
namespace {
// Returns true if protected memory is supported. Currently we assume that it is
// supported on ARM64, but not on x64.
//
// TODO(crbug.com/42050020): Detect if protected memory is supported.
bool IsProtectedMemorySupported() {
#if defined(ARCH_CPU_ARM64)
return true;
#else
return false;
#endif
}
// Appends `value` to the value of `switch_name` in the `command_line`.
// The switch is assumed to consist of comma-separated values. If `switch_name`
// is already set in `command_line` then a comma will be appended, followed by
// `value`, otherwise the switch will be set to `value`.
void AppendToSwitch(std::string_view switch_name,
std::string_view value,
base::CommandLine* command_line,
std::string_view separator = ",") {
if (!command_line->HasSwitch(switch_name)) {
command_line->AppendSwitchNative(switch_name, value);
return;
}
std::string new_value = base::StrCat(
{command_line->GetSwitchValueASCII(switch_name), separator, value});
command_line->RemoveSwitch(switch_name);
command_line->AppendSwitchNative(switch_name, new_value);
}
bool AddCommandLineArgsFromConfig(const base::Value::Dict& config,
base::CommandLine* command_line) {
const base::Value::Dict* args = config.FindDict("command-line-args");
if (!args) {
return true;
}
static const std::string_view kAllowedArgs[] = {
blink::switches::kSharedArrayBufferAllowedOrigins,
blink::switches::kGpuRasterizationMSAASampleCount,
blink::switches::kMinHeightForGpuRasterTile,
switches::kEnableClippedImageScaling,
switches::kEnableGpuBenchmarking,
embedder_support::kOriginTrialPublicKey,
embedder_support::kOriginTrialDisabledFeatures,
switches::kDisableFeatures,
switches::kDisableGpuWatchdog,
switches::kDisableQuic,
switches::kDisableMipmapGeneration,
// TODO(crbug.com/40131115): Remove this switch from the allow-list.
switches::kEnableCastStreamingReceiver,
switches::kEnableFeatures,
switches::kEnableLowEndDeviceMode,
switches::kForceDeviceScaleFactor,
switches::kForceGpuMemAvailableMb,
switches::kForceGpuMemDiscardableLimitMb,
switches::kForceMaxTextureSize,
switches::kGoogleApiKey,
switches::kInProcessGPU,
switches::kMaxDecodedImageSizeMb,
switches::kMinVideoDecoderOutputBufferSize,
switches::kOzonePlatform,
switches::kRendererProcessLimit,
switches::kUseCmdDecoder,
switches::kV,
switches::kVModule,
switches::kVulkanHeapMemoryLimitMb,
switches::kVulkanSyncCpuMemoryLimitMb,
switches::kWebglAntialiasingMode,
switches::kWebglMSAASampleCount,
};
for (const auto arg : *args) {
if (!base::Contains(kAllowedArgs, arg.first)) {
// TODO(crbug.com/40662865): Increase severity and return false
// once we have a mechanism for soft transitions of supported arguments.
LOG(WARNING) << "Unknown command-line arg: '" << arg.first
<< "'. Config file and WebEngine version may not match.";
continue;
}
if (arg.first == switches::kEnableFeatures ||
arg.first == switches::kDisableFeatures) {
if (!arg.second.is_string()) {
LOG(ERROR) << "Config command-line arg must be a string: " << arg.first;
return false;
}
// Merge the features.
AppendToSwitch(arg.first, arg.second.GetString(), command_line);
continue;
}
if (command_line->HasSwitch(arg.first)) {
// Use the existing command line value rather than override it.
continue;
}
if (arg.second.is_none()) {
command_line->AppendSwitch(arg.first);
continue;
}
if (arg.second.is_string()) {
command_line->AppendSwitchNative(arg.first, arg.second.GetString());
continue;
}
LOG(ERROR) << "Config command-line arg must be a string: " << arg.first;
return false;
}
// Disable kWebRtcHWDecoding by default until config-data are updated.
// TODO(b/326282208): Remove once config-data are updated to use the new
// feature.
AppendToSwitch(switches::kDisableFeatures, features::kWebRtcHWDecoding.name,
command_line);
return true;
}
} // namespace
bool UpdateCommandLineFromConfigFile(const base::Value::Dict& config,
base::CommandLine* command_line) {
// The FieldTrialList should be initialized only after config is loaded.
CHECK(!base::FieldTrialList::GetInstance());
if (!AddCommandLineArgsFromConfig(config, command_line)) {
return false;
}
// The following two args are set by calling component. They are used to set
// other flags below.
const bool playready_enabled =
command_line->HasSwitch(switches::kPlayreadyKeySystem);
const bool widevine_enabled =
command_line->HasSwitch(switches::kEnableWidevine);
// Ignore "force-protected-video-buffers" if protected memory is not
// supported. This is necessary to workaround https://fxbug.dev/126639.
const bool force_protected_video_buffers =
IsProtectedMemorySupported() &&
config.FindBool("force-protected-video-buffers").value_or(false);
const bool enable_protected_graphics =
playready_enabled || widevine_enabled || force_protected_video_buffers;
if (enable_protected_graphics) {
command_line->AppendSwitch(switches::kEnableVulkanProtectedMemory);
command_line->AppendSwitch(switches::kEnableProtectedVideoBuffers);
}
if (force_protected_video_buffers) {
command_line->AppendSwitch(switches::kForceProtectedVideoOutputBuffers);
}
// TODO(crbug.com/40269624): Remove this switch once fixed.
command_line->AppendSwitchASCII(switches::kEnableHardwareOverlays,
"underlay");
std::optional<int> max_old_space =
config.FindInt("js-heap-max-old-space-size");
if (max_old_space) {
AppendToSwitch(
blink::switches::kJavaScriptFlags,
"--max_old_space_size=" + base::NumberToString(max_old_space.value()),
command_line, " ");
}
std::optional<int> max_semi_space =
config.FindInt("js-heap-max-semi-space-size");
if (max_semi_space) {
AppendToSwitch(
blink::switches::kJavaScriptFlags,
"--max_semi_space_size=" + base::NumberToString(max_semi_space.value()),
command_line, " ");
}
return true;
}