Skip to content

Commit 05e0ae0

Browse files
Fix Android engine flags defaulting to true for malformed values (#184631)
## Summary - `FlutterLoader` parses Android manifest metadata for engine shell flags, but `getBoolean(metadataKey, true)` defaults to `true` when the value is missing or unparseable — accidentally enabling flags that should be off - Change the default from `true` to `false`, matching the pre-#182522 per-flag behavior where flags were disabled unless explicitly enabled ## Changes - `engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java`: Changed `applicationMetaData.getBoolean(metadataKey, true)` to `getBoolean(metadataKey, false)` Fixes #184581 --------- Co-authored-by: Camille Simon <43054281+camsim99@users.noreply.github.com> Co-authored-by: Camille Simon <camillesimon@google.com>
1 parent 149fbc8 commit 05e0ae0

3 files changed

Lines changed: 40 additions & 31 deletions

File tree

docs/engine/Flutter-Android-Engine-Flags.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,10 @@ Set the `--enable-flutter-gpu` flag:
9393
/>
9494
```
9595

96-
For flags that take boolean values, if you omit a value entirely, it
97-
will be assumed to be true. For example, this is the same as the
98-
example above:
99-
100-
```xml
101-
<meta-data
102-
android:name="io.flutter.embedding.android.EnableFlutterGPU"
103-
/>
104-
```
96+
For flags that take boolean values, you must explicitly set
97+
`android:value="true"` to enable the flag. Omitting the value or
98+
providing a non-boolean value (e.g., a typo like `"Fasle"`) will
99+
default to `false` (disabled).
105100

106101
## Release-mode restrictions
107102

engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,9 @@ void ensureInitializationComplete(
396396
}
397397

398398
// Check if a boolean value is specified and if so, use it to determine if the
399-
// flags should be added. If not, assume the flag is meant to be added.
400-
if (applicationMetaData.getBoolean(metadataKey, true)) {
399+
// flags should be added. If the value is missing or unparseable, default to
400+
// false (disabled) to ensure flags are only enabled when explicitly requested.
401+
if (applicationMetaData.getBoolean(metadataKey, false)) {
401402
shellArgs.add(arg);
402403
}
403404
}

engine/src/flutter/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ public void itSetsAotSharedLibraryNameAsExpectedIfSymlinkIsNotSafe() throws IOEx
757757
public void itSetsEnableSoftwareRenderingFromMetadata() {
758758
testFlagFromMetadataPresent(
759759
"io.flutter.embedding.android.EnableSoftwareRendering",
760-
null,
760+
true,
761761
"--enable-software-rendering");
762762
}
763763

@@ -784,7 +784,7 @@ public void getSofwareRenderingEnabledViaManifest_returnsExpectedValueWhenSetVia
784784
public void itSetsSkiaDeterministicRenderingFromMetadata() {
785785
testFlagFromMetadataPresent(
786786
"io.flutter.embedding.android.SkiaDeterministicRendering",
787-
null,
787+
true,
788788
"--skia-deterministic-rendering");
789789
}
790790

@@ -914,7 +914,7 @@ public void itSetsIsolateSnapshotDataFromMetadata() {
914914
@Test
915915
public void itSetsUseTestFontsFromMetadata() {
916916
testFlagFromMetadataPresent(
917-
"io.flutter.embedding.android.UseTestFonts", null, "--use-test-fonts");
917+
"io.flutter.embedding.android.UseTestFonts", true, "--use-test-fonts");
918918
}
919919

920920
@Test
@@ -929,7 +929,7 @@ public void itSetsVmServicePortFromMetadata() {
929929
@Test
930930
public void itSetsEnableVulkanValidationFromMetadata() {
931931
testFlagFromMetadataPresent(
932-
"io.flutter.embedding.android.EnableVulkanValidation", null, "--enable-vulkan-validation");
932+
"io.flutter.embedding.android.EnableVulkanValidation", true, "--enable-vulkan-validation");
933933
}
934934

935935
@Test
@@ -944,64 +944,64 @@ public void itSetsLeakVMFromMetadata() {
944944
@Test
945945
public void itSetsTraceStartupFromMetadata() {
946946
testFlagFromMetadataPresent(
947-
"io.flutter.embedding.android.TraceStartup", null, "--trace-startup");
947+
"io.flutter.embedding.android.TraceStartup", true, "--trace-startup");
948948
}
949949

950950
@Test
951951
public void itSetsStartPausedFromMetadata() {
952-
testFlagFromMetadataPresent("io.flutter.embedding.android.StartPaused", null, "--start-paused");
952+
testFlagFromMetadataPresent("io.flutter.embedding.android.StartPaused", true, "--start-paused");
953953
}
954954

955955
@Test
956956
public void itSetsDisableServiceAuthCodesFromMetadata() {
957957
testFlagFromMetadataPresent(
958958
"io.flutter.embedding.android.DisableServiceAuthCodes",
959-
null,
959+
true,
960960
"--disable-service-auth-codes");
961961
}
962962

963963
@Test
964964
public void itSetsEndlessTraceBufferFromMetadata() {
965965
testFlagFromMetadataPresent(
966-
"io.flutter.embedding.android.EndlessTraceBuffer", null, "--endless-trace-buffer");
966+
"io.flutter.embedding.android.EndlessTraceBuffer", true, "--endless-trace-buffer");
967967
}
968968

969969
@Test
970970
public void itSetsEnableDartProfilingFromMetadata() {
971971
// Test debug mode.
972972
testFlagFromMetadataPresent(
973-
"io.flutter.embedding.android.EnableDartProfiling", null, "--enable-dart-profiling");
973+
"io.flutter.embedding.android.EnableDartProfiling", true, "--enable-dart-profiling");
974974

975975
// Test release mode.
976976
testFlagFromMetadataPresentInReleaseMode(
977-
"io.flutter.embedding.android.EnableDartProfiling", null, "--enable-dart-profiling");
977+
"io.flutter.embedding.android.EnableDartProfiling", true, "--enable-dart-profiling");
978978
}
979979

980980
@Test
981981
public void itSetsProfileStartupFromMetadata() {
982982
// Test debug mode.
983983
testFlagFromMetadataPresent(
984-
"io.flutter.embedding.android.ProfileStartup", null, "--profile-startup");
984+
"io.flutter.embedding.android.ProfileStartup", true, "--profile-startup");
985985

986986
// Test release mode.
987987
testFlagFromMetadataPresentInReleaseMode(
988-
"io.flutter.embedding.android.ProfileStartup", null, "--profile-startup");
988+
"io.flutter.embedding.android.ProfileStartup", true, "--profile-startup");
989989
}
990990

991991
@Test
992992
public void itSetsMergedPlatformUiThread() {
993993
// Test debug mode.
994994
testFlagFromMetadataPresent(
995-
"io.flutter.embedding.android.MergedPlatformUIThread", null, "--merged-platform-ui-thread");
995+
"io.flutter.embedding.android.MergedPlatformUIThread", true, "--merged-platform-ui-thread");
996996

997997
// Test release mode.
998998
testFlagFromMetadataPresentInReleaseMode(
999-
"io.flutter.embedding.android.MergedPlatformUIThread", null, "--merged-platform-ui-thread");
999+
"io.flutter.embedding.android.MergedPlatformUIThread", true, "--merged-platform-ui-thread");
10001000
}
10011001

10021002
@Test
10031003
public void itSetsTraceSkiaFromMetadata() {
1004-
testFlagFromMetadataPresent("io.flutter.embedding.android.TraceSkia", null, "--trace-skia");
1004+
testFlagFromMetadataPresent("io.flutter.embedding.android.TraceSkia", true, "--trace-skia");
10051005
}
10061006

10071007
@Test
@@ -1016,7 +1016,7 @@ public void itSetsTraceSkiaAllowlistFromMetadata() {
10161016
@Test
10171017
public void itSetsTraceSystraceFromMetadata() {
10181018
testFlagFromMetadataPresent(
1019-
"io.flutter.embedding.android.TraceSystrace", null, "--trace-systrace");
1019+
"io.flutter.embedding.android.TraceSystrace", true, "--trace-systrace");
10201020
}
10211021

10221022
@Test
@@ -1031,27 +1031,27 @@ public void itSetsTraceToFileFromMetadata() {
10311031
@Test
10321032
public void itSetsProfileMicrotasksFromMetadata() {
10331033
testFlagFromMetadataPresent(
1034-
"io.flutter.embedding.android.ProfileMicrotasks", null, "--profile-microtasks");
1034+
"io.flutter.embedding.android.ProfileMicrotasks", true, "--profile-microtasks");
10351035
}
10361036

10371037
@Test
10381038
public void itSetsDumpSkpOnShaderCompilationFromMetadata() {
10391039
testFlagFromMetadataPresent(
10401040
"io.flutter.embedding.android.DumpSkpOnShaderCompilation",
1041-
null,
1041+
true,
10421042
"--dump-skp-on-shader-compilation");
10431043
}
10441044

10451045
@Test
10461046
public void itSetsPurgePersistentCacheFromMetadata() {
10471047
testFlagFromMetadataPresent(
1048-
"io.flutter.embedding.android.PurgePersistentCache", null, "--purge-persistent-cache");
1048+
"io.flutter.embedding.android.PurgePersistentCache", true, "--purge-persistent-cache");
10491049
}
10501050

10511051
@Test
10521052
public void itSetsVerboseLoggingFromMetadata() {
10531053
testFlagFromMetadataPresent(
1054-
"io.flutter.embedding.android.VerboseLogging", null, "--verbose-logging");
1054+
"io.flutter.embedding.android.VerboseLogging", true, "--verbose-logging");
10551055
}
10561056

10571057
@Test
@@ -1112,6 +1112,19 @@ public void itSetsEnableVulkanGPUTracingFromMetadata() {
11121112
"io.flutter.embedding.android.EnableVulkanGPUTracing", true, "--enable-vulkan-gpu-tracing");
11131113
}
11141114

1115+
@Test
1116+
public void itDoesNotSetBooleanFlagWithMalformedOrMissingValue() {
1117+
// A key present with a non-boolean string value should NOT enable the flag.
1118+
testFlagFromMetadataNotPresent(
1119+
"io.flutter.embedding.android.EnableVulkanValidation",
1120+
"Fasle",
1121+
"--enable-vulkan-validation");
1122+
1123+
// A key present with a null value should NOT enable the flag.
1124+
testFlagFromMetadataNotPresent(
1125+
"io.flutter.embedding.android.EnableVulkanValidation", null, "--enable-vulkan-validation");
1126+
}
1127+
11151128
@Test
11161129
public void itDoesNotSetTestFlagFromMetadata() {
11171130
testFlagFromMetadataNotPresent("io.flutter.embedding.android.TestFlag", null, "--test-flag");

0 commit comments

Comments
 (0)