Unverified Commit 47f08a3f authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

[flutter_tool] Adds --enable-impeller flag to the run command (#100835)

parent 689672ff
...@@ -140,7 +140,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -140,7 +140,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
'startup. By default this is main(List<String> args). Specify ' 'startup. By default this is main(List<String> args). Specify '
'this option multiple times each with one argument to pass ' 'this option multiple times each with one argument to pass '
'multiple arguments to the Dart entrypoint. Currently this is ' 'multiple arguments to the Dart entrypoint. Currently this is '
'only supported on desktop platforms.' 'only supported on desktop platforms.',
); );
usesWebOptions(verboseHelp: verboseHelp); usesWebOptions(verboseHelp: verboseHelp);
usesTargetOption(); usesTargetOption();
...@@ -155,6 +155,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -155,6 +155,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
addDevToolsOptions(verboseHelp: verboseHelp); addDevToolsOptions(verboseHelp: verboseHelp);
addAndroidSpecificBuildOptions(hide: !verboseHelp); addAndroidSpecificBuildOptions(hide: !verboseHelp);
usesFatalWarningsOption(verboseHelp: verboseHelp); usesFatalWarningsOption(verboseHelp: verboseHelp);
addEnableImpellerFlag(verboseHelp: verboseHelp);
} }
bool get traceStartup => boolArg('trace-startup'); bool get traceStartup => boolArg('trace-startup');
...@@ -164,6 +165,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -164,6 +165,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
bool get disableServiceAuthCodes => boolArg('disable-service-auth-codes'); bool get disableServiceAuthCodes => boolArg('disable-service-auth-codes');
bool get runningWithPrebuiltApplication => argResults['use-application-binary'] != null; bool get runningWithPrebuiltApplication => argResults['use-application-binary'] != null;
bool get trackWidgetCreation => boolArg('track-widget-creation'); bool get trackWidgetCreation => boolArg('track-widget-creation');
bool get enableImpeller => boolArg('enable-impeller');
@override @override
bool get reportNullSafety => true; bool get reportNullSafety => true;
...@@ -193,6 +195,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -193,6 +195,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
webEnableExposeUrl: featureFlags.isWebEnabled && boolArg('web-allow-expose-url'), webEnableExposeUrl: featureFlags.isWebEnabled && boolArg('web-allow-expose-url'),
webRunHeadless: featureFlags.isWebEnabled && boolArg('web-run-headless'), webRunHeadless: featureFlags.isWebEnabled && boolArg('web-run-headless'),
webBrowserDebugPort: browserDebugPort, webBrowserDebugPort: browserDebugPort,
enableImpeller: enableImpeller,
); );
} else { } else {
return DebuggingOptions.enabled( return DebuggingOptions.enabled(
...@@ -235,6 +238,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -235,6 +238,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
&& !runningWithPrebuiltApplication, && !runningWithPrebuiltApplication,
nullAssertions: boolArg('null-assertions'), nullAssertions: boolArg('null-assertions'),
nativeNullAssertions: boolArg('native-null-assertions'), nativeNullAssertions: boolArg('native-null-assertions'),
enableImpeller: enableImpeller,
); );
} }
} }
...@@ -438,6 +442,7 @@ class RunCommand extends RunCommandBase { ...@@ -438,6 +442,7 @@ class RunCommand extends RunCommandBase {
commandRunProjectModule: FlutterProject.current().isModule, commandRunProjectModule: FlutterProject.current().isModule,
commandRunProjectHostLanguage: hostLanguage.join(','), commandRunProjectHostLanguage: hostLanguage.join(','),
commandRunAndroidEmbeddingVersion: androidEmbeddingVersion, commandRunAndroidEmbeddingVersion: androidEmbeddingVersion,
commandRunEnableImpeller: enableImpeller,
); );
} }
......
...@@ -790,6 +790,7 @@ class DebuggingOptions { ...@@ -790,6 +790,7 @@ class DebuggingOptions {
this.fastStart = false, this.fastStart = false,
this.nullAssertions = false, this.nullAssertions = false,
this.nativeNullAssertions = false, this.nativeNullAssertions = false,
this.enableImpeller = false,
}) : debuggingEnabled = true; }) : debuggingEnabled = true;
DebuggingOptions.disabled(this.buildInfo, { DebuggingOptions.disabled(this.buildInfo, {
...@@ -805,6 +806,7 @@ class DebuggingOptions { ...@@ -805,6 +806,7 @@ class DebuggingOptions {
this.webLaunchUrl, this.webLaunchUrl,
this.cacheSkSL = false, this.cacheSkSL = false,
this.traceAllowlist, this.traceAllowlist,
this.enableImpeller = false,
}) : debuggingEnabled = false, }) : debuggingEnabled = false,
useTestFonts = false, useTestFonts = false,
startPaused = false, startPaused = false,
...@@ -870,6 +872,7 @@ class DebuggingOptions { ...@@ -870,6 +872,7 @@ class DebuggingOptions {
required this.fastStart, required this.fastStart,
required this.nullAssertions, required this.nullAssertions,
required this.nativeNullAssertions, required this.nativeNullAssertions,
required this.enableImpeller,
}); });
final bool debuggingEnabled; final bool debuggingEnabled;
...@@ -903,6 +906,7 @@ class DebuggingOptions { ...@@ -903,6 +906,7 @@ class DebuggingOptions {
final bool webUseSseForDebugProxy; final bool webUseSseForDebugProxy;
final bool webUseSseForDebugBackend; final bool webUseSseForDebugBackend;
final bool webUseSseForInjectedClient; final bool webUseSseForInjectedClient;
final bool enableImpeller;
/// Whether to run the browser in headless mode. /// Whether to run the browser in headless mode.
/// ///
...@@ -972,6 +976,7 @@ class DebuggingOptions { ...@@ -972,6 +976,7 @@ class DebuggingOptions {
'fastStart': fastStart, 'fastStart': fastStart,
'nullAssertions': nullAssertions, 'nullAssertions': nullAssertions,
'nativeNullAssertions': nativeNullAssertions, 'nativeNullAssertions': nativeNullAssertions,
'enableImpeller': enableImpeller,
}; };
static DebuggingOptions fromJson(Map<String, Object?> json, BuildInfo buildInfo) => static DebuggingOptions fromJson(Map<String, Object?> json, BuildInfo buildInfo) =>
...@@ -1014,6 +1019,7 @@ class DebuggingOptions { ...@@ -1014,6 +1019,7 @@ class DebuggingOptions {
fastStart: (json['fastStart'] as bool?)!, fastStart: (json['fastStart'] as bool?)!,
nullAssertions: (json['nullAssertions'] as bool?)!, nullAssertions: (json['nullAssertions'] as bool?)!,
nativeNullAssertions: (json['nativeNullAssertions'] as bool?)!, nativeNullAssertions: (json['nativeNullAssertions'] as bool?)!,
enableImpeller: (json['enableImpeller'] as bool?) ?? false,
); );
} }
......
...@@ -373,6 +373,7 @@ class IOSDevice extends Device { ...@@ -373,6 +373,7 @@ class IOSDevice extends Device {
if (debuggingOptions.purgePersistentCache) '--purge-persistent-cache', if (debuggingOptions.purgePersistentCache) '--purge-persistent-cache',
if (route != null) '--route=$route', if (route != null) '--route=$route',
if (platformArgs['trace-startup'] as bool? ?? false) '--trace-startup', if (platformArgs['trace-startup'] as bool? ?? false) '--trace-startup',
if (debuggingOptions.enableImpeller) '--enable-impeller',
]; ];
final Status installStatus = _logger.startProgress( final Status installStatus = _logger.startProgress(
......
...@@ -66,6 +66,7 @@ class CustomDimensions { ...@@ -66,6 +66,7 @@ class CustomDimensions {
this.hotEventScannedSourcesCount, this.hotEventScannedSourcesCount,
this.hotEventReassembleTimeInMs, this.hotEventReassembleTimeInMs,
this.hotEventReloadVMTimeInMs, this.hotEventReloadVMTimeInMs,
this.commandRunEnableImpeller,
}); });
final String? sessionHostOsDetails; // cd1 final String? sessionHostOsDetails; // cd1
...@@ -123,6 +124,7 @@ class CustomDimensions { ...@@ -123,6 +124,7 @@ class CustomDimensions {
final int? hotEventScannedSourcesCount; // cd 53 final int? hotEventScannedSourcesCount; // cd 53
final int? hotEventReassembleTimeInMs; // cd 54 final int? hotEventReassembleTimeInMs; // cd 54
final int? hotEventReloadVMTimeInMs; // cd 55 final int? hotEventReloadVMTimeInMs; // cd 55
final bool? commandRunEnableImpeller; // cd 56
/// Convert to a map that will be used to upload to the analytics backend. /// Convert to a map that will be used to upload to the analytics backend.
Map<String, String> toMap() => <String, String>{ Map<String, String> toMap() => <String, String>{
...@@ -181,6 +183,7 @@ class CustomDimensions { ...@@ -181,6 +183,7 @@ class CustomDimensions {
if (hotEventScannedSourcesCount != null) cdKey(CustomDimensionsEnum.hotEventScannedSourcesCount): hotEventScannedSourcesCount.toString(), if (hotEventScannedSourcesCount != null) cdKey(CustomDimensionsEnum.hotEventScannedSourcesCount): hotEventScannedSourcesCount.toString(),
if (hotEventReassembleTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventReassembleTimeInMs): hotEventReassembleTimeInMs.toString(), if (hotEventReassembleTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventReassembleTimeInMs): hotEventReassembleTimeInMs.toString(),
if (hotEventReloadVMTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventReloadVMTimeInMs): hotEventReloadVMTimeInMs.toString(), if (hotEventReloadVMTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventReloadVMTimeInMs): hotEventReloadVMTimeInMs.toString(),
if (commandRunEnableImpeller != null) cdKey(CustomDimensionsEnum.commandRunEnableImpeller): commandRunEnableImpeller.toString(),
}; };
/// Merge the values of two [CustomDimensions] into one. If a value is defined /// Merge the values of two [CustomDimensions] into one. If a value is defined
...@@ -246,6 +249,7 @@ class CustomDimensions { ...@@ -246,6 +249,7 @@ class CustomDimensions {
hotEventScannedSourcesCount: other.hotEventScannedSourcesCount ?? hotEventScannedSourcesCount, hotEventScannedSourcesCount: other.hotEventScannedSourcesCount ?? hotEventScannedSourcesCount,
hotEventReassembleTimeInMs: other.hotEventReassembleTimeInMs ?? hotEventReassembleTimeInMs, hotEventReassembleTimeInMs: other.hotEventReassembleTimeInMs ?? hotEventReassembleTimeInMs,
hotEventReloadVMTimeInMs: other.hotEventReloadVMTimeInMs ?? hotEventReloadVMTimeInMs, hotEventReloadVMTimeInMs: other.hotEventReloadVMTimeInMs ?? hotEventReloadVMTimeInMs,
commandRunEnableImpeller: other.commandRunEnableImpeller ?? commandRunEnableImpeller,
); );
} }
...@@ -305,6 +309,7 @@ class CustomDimensions { ...@@ -305,6 +309,7 @@ class CustomDimensions {
hotEventScannedSourcesCount: _extractInt(map, CustomDimensionsEnum.hotEventScannedSourcesCount), hotEventScannedSourcesCount: _extractInt(map, CustomDimensionsEnum.hotEventScannedSourcesCount),
hotEventReassembleTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventReassembleTimeInMs), hotEventReassembleTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventReassembleTimeInMs),
hotEventReloadVMTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventReloadVMTimeInMs), hotEventReloadVMTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventReloadVMTimeInMs),
commandRunEnableImpeller: _extractBool(map, CustomDimensionsEnum.commandRunEnableImpeller),
); );
static bool? _extractBool(Map<String, String> map, CustomDimensionsEnum field) => static bool? _extractBool(Map<String, String> map, CustomDimensionsEnum field) =>
...@@ -390,6 +395,7 @@ enum CustomDimensionsEnum { ...@@ -390,6 +395,7 @@ enum CustomDimensionsEnum {
hotEventScannedSourcesCount, // cd53 hotEventScannedSourcesCount, // cd53
hotEventReassembleTimeInMs, // cd54 hotEventReassembleTimeInMs, // cd54
hotEventReloadVMTimeInMs, // cd55 hotEventReloadVMTimeInMs, // cd55
commandRunEnableImpeller, // cd56
} }
String cdKey(CustomDimensionsEnum cd) => 'cd${cd.index + 1}'; String cdKey(CustomDimensionsEnum cd) => 'cd${cd.index + 1}';
...@@ -948,6 +948,16 @@ abstract class FlutterCommand extends Command<void> { ...@@ -948,6 +948,16 @@ abstract class FlutterCommand extends Command<void> {
); );
} }
void addEnableImpellerFlag({required bool verboseHelp}) {
argParser.addFlag('enable-impeller',
negatable: false,
hide: !verboseHelp,
help: 'Whether to enable the experimental Impeller rendering engine. '
'Impeller is currently only supported on iOS. This flag will '
'be ignored when targeting other platforms.',
);
}
/// Compute the [BuildInfo] for the current flutter command. /// Compute the [BuildInfo] for the current flutter command.
/// Commands that build multiple build modes can pass in a [forcedBuildMode] /// Commands that build multiple build modes can pass in a [forcedBuildMode]
/// to be used instead of parsing flags. /// to be used instead of parsing flags.
......
...@@ -207,6 +207,26 @@ void main() { ...@@ -207,6 +207,26 @@ void main() {
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Pub: () => FakePub(), Pub: () => FakePub(),
}); });
testUsingContext('--enable-impeller flag propagates to debugging options', () async {
final DriveCommand command = DriveCommand(fileSystem: fileSystem, logger: logger, platform: platform);
fileSystem.file('lib/main.dart').createSync(recursive: true);
fileSystem.file('test_driver/main_test.dart').createSync(recursive: true);
fileSystem.file('pubspec.yaml').createSync();
await expectLater(() => createTestCommandRunner(command).run(<String>[
'drive',
'--enable-impeller',
]), throwsToolExit());
final DebuggingOptions options = await command.createDebuggingOptions(false);
expect(options.enableImpeller, true);
}, overrides: <Type, Generator>{
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
} }
// Unfortunately Device, despite not being immutable, has an `operator ==`. // Unfortunately Device, despite not being immutable, has an `operator ==`.
......
...@@ -394,6 +394,7 @@ void main() { ...@@ -394,6 +394,7 @@ void main() {
TestUsageCommand('run', parameters: CustomDimensions.fromMap(<String, String>{ TestUsageCommand('run', parameters: CustomDimensions.fromMap(<String, String>{
'cd3': 'false', 'cd4': 'ios', 'cd22': 'iOS 13', 'cd3': 'false', 'cd4': 'ios', 'cd22': 'iOS 13',
'cd23': 'debug', 'cd18': 'false', 'cd15': 'swift', 'cd31': 'false', 'cd23': 'debug', 'cd18': 'false', 'cd15': 'swift', 'cd31': 'false',
'cd56': 'false',
}) })
))); )));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -622,6 +623,22 @@ void main() { ...@@ -622,6 +623,22 @@ void main() {
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
testUsingContext('--enable-impeller flag propagates to debugging options', () async {
final RunCommand command = RunCommand();
await expectLater(() => createTestCommandRunner(command).run(<String>[
'run',
'--enable-impeller',
]), throwsToolExit());
final DebuggingOptions options = await command.createDebuggingOptions(false);
expect(options.enableImpeller, true);
}, overrides: <Type, Generator>{
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('fails when "--web-launch-url" is not supported', () async { testUsingContext('fails when "--web-launch-url" is not supported', () async {
final RunCommand command = RunCommand(); final RunCommand command = RunCommand();
await expectLater( await expectLater(
......
...@@ -521,6 +521,7 @@ void main() { ...@@ -521,6 +521,7 @@ void main() {
dartEntrypointArgs: <String>['a', 'b'], dartEntrypointArgs: <String>['a', 'b'],
dartFlags: 'c', dartFlags: 'c',
deviceVmServicePort: 1234, deviceVmServicePort: 1234,
enableImpeller: true,
); );
final String jsonString = json.encode(original.toJson()); final String jsonString = json.encode(original.toJson());
final Map<String, dynamic> decoded = castStringKeyedMap(json.decode(jsonString))!; final Map<String, dynamic> decoded = castStringKeyedMap(json.decode(jsonString))!;
...@@ -531,6 +532,7 @@ void main() { ...@@ -531,6 +532,7 @@ void main() {
expect(deserialized.dartEntrypointArgs, original.dartEntrypointArgs); expect(deserialized.dartEntrypointArgs, original.dartEntrypointArgs);
expect(deserialized.dartFlags, original.dartFlags); expect(deserialized.dartFlags, original.dartFlags);
expect(deserialized.deviceVmServicePort, original.deviceVmServicePort); expect(deserialized.deviceVmServicePort, original.deviceVmServicePort);
expect(deserialized.enableImpeller, original.enableImpeller);
}); });
}); });
} }
......
...@@ -285,6 +285,7 @@ void main() { ...@@ -285,6 +285,7 @@ void main() {
'--verbose-logging', '--verbose-logging',
'--cache-sksl', '--cache-sksl',
'--purge-persistent-cache', '--purge-persistent-cache',
'--enable-impeller',
].join(' '), ].join(' '),
], environment: const <String, String>{ ], environment: const <String, String>{
'PATH': '/usr/bin:null', 'PATH': '/usr/bin:null',
...@@ -332,6 +333,7 @@ void main() { ...@@ -332,6 +333,7 @@ void main() {
purgePersistentCache: true, purgePersistentCache: true,
verboseSystemLogs: true, verboseSystemLogs: true,
nullAssertions: true, nullAssertions: true,
enableImpeller: true,
), ),
platformArgs: <String, dynamic>{}, platformArgs: <String, dynamic>{},
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment