Make timeout durations configurable (#30053)
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index c0d1efd..335a149 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -277,7 +277,7 @@
if (!await _checkForSupportedAdbVersion() || !await _checkForSupportedAndroidVersion())
return false;
- final Status status = logger.startProgress('Installing ${fs.path.relative(apk.file.path)}...', timeout: kSlowOperation);
+ final Status status = logger.startProgress('Installing ${fs.path.relative(apk.file.path)}...', timeout: timeoutConfiguration.slowOperation);
final RunResult installResult = await runAsync(adbCommandForDevice(<String>['install', '-t', '-r', apk.file.path]));
status.stop();
// Some versions of adb exit with exit code 0 even on failure :(
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index e08a3c4..6e76379 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -115,7 +115,7 @@
/// Runs `gradlew dependencies`, ensuring that dependencies are resolved and
/// potentially downloaded.
Future<void> checkGradleDependencies() async {
- final Status progress = logger.startProgress('Ensuring gradle dependencies are up to date...', timeout: kSlowOperation);
+ final Status progress = logger.startProgress('Ensuring gradle dependencies are up to date...', timeout: timeoutConfiguration.slowOperation);
final FlutterProject flutterProject = await FlutterProject.current();
final String gradle = await _ensureGradle(flutterProject);
await runCheckedAsync(
@@ -133,7 +133,7 @@
final FlutterProject flutterProject = await FlutterProject.current();
final String gradle = await _ensureGradle(flutterProject);
updateLocalProperties(project: flutterProject);
- final Status status = logger.startProgress('Resolving dependencies...', timeout: kSlowOperation);
+ final Status status = logger.startProgress('Resolving dependencies...', timeout: timeoutConfiguration.slowOperation);
GradleProject project;
try {
final RunResult propertiesRunResult = await runCheckedAsync(
@@ -211,7 +211,7 @@
// of validating the Gradle executable. This may take several seconds.
Future<String> _initializeGradle(FlutterProject project) async {
final Directory android = project.android.hostAppGradleRoot;
- final Status status = logger.startProgress('Initializing gradle...', timeout: kSlowOperation);
+ final Status status = logger.startProgress('Initializing gradle...', timeout: timeoutConfiguration.slowOperation);
String gradle = _locateGradlewExecutable(android);
if (gradle == null) {
injectGradleWrapper(android);
@@ -351,7 +351,7 @@
// Run 'gradlew build'.
final Status status = logger.startProgress(
'Running \'gradlew build\'...',
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
multilineOutput: true,
);
final int exitCode = await runCommandAndStreamOutput(
@@ -403,7 +403,7 @@
}
final Status status = logger.startProgress(
'Running Gradle task \'$assembleTask\'...',
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
multilineOutput: true,
);
final String gradlePath = fs.file(gradle).absolute.path;
diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart
index 97110d1..14c17f8 100644
--- a/packages/flutter_tools/lib/src/base/logger.dart
+++ b/packages/flutter_tools/lib/src/base/logger.dart
@@ -13,8 +13,29 @@
import 'utils.dart';
const int kDefaultStatusPadding = 59;
-const Duration kFastOperation = Duration(seconds: 2);
-const Duration kSlowOperation = Duration(minutes: 2);
+const Duration _kFastOperation = Duration(seconds: 2);
+const Duration _kSlowOperation = Duration(minutes: 2);
+
+/// The [TimeoutConfiguration] instance.
+///
+/// If not provided via injection, a default instance is provided.
+TimeoutConfiguration get timeoutConfiguration => context[TimeoutConfiguration] ?? const TimeoutConfiguration();
+
+class TimeoutConfiguration {
+ const TimeoutConfiguration();
+
+ /// The expected time that various "slow" operations take, such as running
+ /// the analyzer.
+ ///
+ /// Defaults to 2 minutes.
+ Duration get slowOperation => _kSlowOperation;
+
+ /// The expected time that various "fast" operations take, such as a hot
+ /// reload.
+ ///
+ /// Defaults to 2 seconds.
+ Duration get fastOperation => _kFastOperation;
+}
typedef VoidCallback = void Function();
@@ -375,7 +396,7 @@
timeout: timeout,
onFinish: () {
String time;
- if (timeout == null || timeout > kFastOperation) {
+ if (timeout == null || timeout > timeoutConfiguration.fastOperation) {
time = getElapsedAsSeconds(timer.elapsed);
} else {
time = getElapsedAsMilliseconds(timer.elapsed);
@@ -473,7 +494,7 @@
@protected
String get elapsedTime {
- if (timeout == null || timeout > kFastOperation)
+ if (timeout == null || timeout > timeoutConfiguration.fastOperation)
return getElapsedAsSeconds(_stopwatch.elapsed);
return getElapsedAsMilliseconds(_stopwatch.elapsed);
}
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index 4c82ae9..e0c79b4 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -366,7 +366,7 @@
Future<void> _downloadArchive(String message, Uri url, Directory location, bool verifier(File f), void extractor(File f, Directory d)) {
return _withDownloadFile('${flattenNameSubdirs(url)}', (File tempFile) async {
if (!verifier(tempFile)) {
- final Status status = logger.startProgress(message, timeout: kSlowOperation);
+ final Status status = logger.startProgress(message, timeout: timeoutConfiguration.slowOperation);
try {
await _downloadFile(url, tempFile);
status.stop();
@@ -781,7 +781,7 @@
}
Future<bool> _doesRemoteExist(String message, Uri url) async {
- final Status status = logger.startProgress(message, timeout: kSlowOperation);
+ final Status status = logger.startProgress(message, timeout: timeoutConfiguration.slowOperation);
final bool exists = await doesRemoteFileExist(url);
status.stop();
return exists;
diff --git a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
index d470d9e..a82cdd7 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
@@ -77,7 +77,7 @@
analysisStatus?.cancel();
if (!firstAnalysis)
printStatus('\n');
- analysisStatus = logger.startProgress('Analyzing $analysisTarget...', timeout: kSlowOperation);
+ analysisStatus = logger.startProgress('Analyzing $analysisTarget...', timeout: timeoutConfiguration.slowOperation);
analyzedPaths.clear();
analysisTimer = Stopwatch()..start();
} else {
diff --git a/packages/flutter_tools/lib/src/commands/analyze_once.dart b/packages/flutter_tools/lib/src/commands/analyze_once.dart
index ca21e83..9f164f0 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_once.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_once.dart
@@ -107,7 +107,7 @@
? '${directories.length} ${directories.length == 1 ? 'directory' : 'directories'}'
: fs.path.basename(directories.first);
final Status progress = argResults['preamble']
- ? logger.startProgress('Analyzing $message...', timeout: kSlowOperation)
+ ? logger.startProgress('Analyzing $message...', timeout: timeoutConfiguration.slowOperation)
: null;
await analysisCompleter.future;
diff --git a/packages/flutter_tools/lib/src/commands/build_aot.dart b/packages/flutter_tools/lib/src/commands/build_aot.dart
index d9243be..9d4362c 100644
--- a/packages/flutter_tools/lib/src/commands/build_aot.dart
+++ b/packages/flutter_tools/lib/src/commands/build_aot.dart
@@ -69,7 +69,7 @@
final String typeName = artifacts.getEngineType(platform, buildMode);
status = logger.startProgress(
'Building AOT snapshot in ${getFriendlyModeName(getBuildMode())} mode ($typeName)...',
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
);
}
final String outputPath = argResults['output-dir'] ?? getAotBuildDirectory();
diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart
index fd4f51a76..c6f8fb3 100644
--- a/packages/flutter_tools/lib/src/commands/update_packages.dart
+++ b/packages/flutter_tools/lib/src/commands/update_packages.dart
@@ -87,7 +87,7 @@
Future<void> _downloadCoverageData() async {
final Status status = logger.startProgress(
'Downloading lcov data for package:flutter...',
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
);
final String urlBase = platform.environment['FLUTTER_STORAGE_BASE_URL'] ?? 'https://storage.googleapis.com';
final List<int> data = await fetchUrl(Uri.parse('$urlBase/flutter_infra/flutter/coverage/lcov.info'));
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index c85afd0..2e253a9 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -91,6 +91,7 @@
SimControl: () => SimControl(),
SystemClock: () => const SystemClock(),
Stdio: () => const Stdio(),
+ TimeoutConfiguration: () => const TimeoutConfiguration(),
Usage: () => Usage(),
UserMessages: () => UserMessages(),
WindowsWorkflow: () => const WindowsWorkflow(),
diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart
index 3ca0c05..d347d0a 100644
--- a/packages/flutter_tools/lib/src/dart/pub.dart
+++ b/packages/flutter_tools/lib/src/dart/pub.dart
@@ -93,7 +93,7 @@
final String command = upgrade ? 'upgrade' : 'get';
final Status status = logger.startProgress(
'Running "flutter packages $command" in ${fs.path.basename(directory)}...',
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
);
final List<String> args = <String>['--verbosity=warning'];
if (FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'])
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index 0e9d793..b2d49c5 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -187,7 +187,7 @@
for (ValidatorTask validatorTask in startValidatorTasks()) {
final DoctorValidator validator = validatorTask.validator;
final Status status = Status.withSpinner(
- timeout: kFastOperation,
+ timeout: timeoutConfiguration.fastOperation,
slowWarningCallback: () => validator.slowWarning,
);
ValidationResult result;
diff --git a/packages/flutter_tools/lib/src/ios/cocoapods.dart b/packages/flutter_tools/lib/src/ios/cocoapods.dart
index 24d0430..63fe11e 100644
--- a/packages/flutter_tools/lib/src/ios/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/ios/cocoapods.dart
@@ -254,7 +254,7 @@
}
Future<void> _runPodInstall(IosProject iosProject, String engineDirectory) async {
- final Status status = logger.startProgress('Running pod install...', timeout: kSlowOperation);
+ final Status status = logger.startProgress('Running pod install...', timeout: timeoutConfiguration.slowOperation);
final ProcessResult result = await processManager.run(
<String>['pod', 'install', '--verbose'],
workingDirectory: iosProject.hostAppRoot.path,
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index efa4962..9cc4272 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -309,7 +309,7 @@
int installationResult = -1;
Uri localObservatoryUri;
- final Status installStatus = logger.startProgress('Installing and launching...', timeout: kSlowOperation);
+ final Status installStatus = logger.startProgress('Installing and launching...', timeout: timeoutConfiguration.slowOperation);
if (!debuggingOptions.debuggingEnabled) {
// If debugging is not enabled, just launch the application and continue.
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 19410ef..19ec184 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -480,7 +480,7 @@
initialBuildStatus = null;
buildSubStatus = logger.startProgress(
line,
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
progressIndicatorPadding: kDefaultStatusPadding - 7,
);
}
@@ -495,7 +495,7 @@
}
final Stopwatch buildStopwatch = Stopwatch()..start();
- initialBuildStatus = logger.startProgress('Running Xcode build...', timeout: kFastOperation);
+ initialBuildStatus = logger.startProgress('Running Xcode build...', timeout: timeoutConfiguration.fastOperation);
final RunResult buildResult = await runAsync(
buildCommands,
workingDirectory: app.project.hostAppRoot.path,
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index f38cc5b..170f563 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -447,7 +447,7 @@
}) async {
final Status devFSStatus = logger.startProgress(
'Syncing files to device ${device.name}...',
- timeout: kFastOperation,
+ timeout: timeoutConfiguration.fastOperation,
);
UpdateFSReport report;
try {
@@ -633,7 +633,7 @@
}
Future<void> _screenshot(FlutterDevice device) async {
- final Status status = logger.startProgress('Taking screenshot for ${device.device.name}...', timeout: kFastOperation);
+ final Status status = logger.startProgress('Taking screenshot for ${device.device.name}...', timeout: timeoutConfiguration.fastOperation);
final File outputFile = getUniqueFile(fs.currentDirectory, 'flutter', 'png');
try {
if (supportsServiceProtocol && isRunningDebug) {
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index 1bfe832..ee8706c 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -538,7 +538,7 @@
}
final Status status = logger.startProgress(
'Performing hot restart...',
- timeout: kFastOperation,
+ timeout: timeoutConfiguration.fastOperation,
progressId: 'hot.restart',
);
try {
@@ -557,7 +557,7 @@
final String progressPrefix = reloadOnTopOfSnapshot ? 'Initializing' : 'Performing';
Status status = logger.startProgress(
'$progressPrefix hot reload...',
- timeout: kFastOperation,
+ timeout: timeoutConfiguration.fastOperation,
progressId: 'hot.reload',
);
OperationResult result;
@@ -570,7 +570,7 @@
status?.cancel();
status = logger.startProgress(
message,
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
progressId: 'hot.reload',
);
showTime = false;
diff --git a/packages/flutter_tools/lib/src/test/coverage_collector.dart b/packages/flutter_tools/lib/src/test/coverage_collector.dart
index ff8ca0c..4220c85 100644
--- a/packages/flutter_tools/lib/src/test/coverage_collector.dart
+++ b/packages/flutter_tools/lib/src/test/coverage_collector.dart
@@ -92,7 +92,7 @@
}
Future<bool> collectCoverageData(String coveragePath, { bool mergeCoverageData = false, Directory coverageDirectory }) async {
- final Status status = logger.startProgress('Collecting coverage information...', timeout: kFastOperation);
+ final Status status = logger.startProgress('Collecting coverage information...', timeout: timeoutConfiguration.fastOperation);
final String coverageData = await finalizeCoverage(
coverageDirectory: coverageDirectory,
);
diff --git a/packages/flutter_tools/lib/src/tracing.dart b/packages/flutter_tools/lib/src/tracing.dart
index a4559f8..0a666d8 100644
--- a/packages/flutter_tools/lib/src/tracing.dart
+++ b/packages/flutter_tools/lib/src/tracing.dart
@@ -40,7 +40,7 @@
if (awaitFirstFrame) {
final Status status = logger.startProgress(
'Waiting for application to render first frame...',
- timeout: kFastOperation,
+ timeout: timeoutConfiguration.fastOperation,
);
try {
final Completer<void> whenFirstFrameRendered = Completer<void>();
diff --git a/packages/flutter_tools/test/base/logger_test.dart b/packages/flutter_tools/test/base/logger_test.dart
index 99c532f..d658955 100644
--- a/packages/flutter_tools/test/base/logger_test.dart
+++ b/packages/flutter_tools/test/base/logger_test.dart
@@ -166,7 +166,7 @@
final Status status = logger.startProgress(
'Hello',
progressId: null,
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below.
);
expect(outputStderr().length, equals(1));
@@ -357,7 +357,7 @@
called = 0;
summaryStatus = SummaryStatus(
message: 'Hello world',
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
padding: 20,
onFinish: () => called++,
);
@@ -593,7 +593,7 @@
final Status status = logger.startProgress(
'Hello',
progressId: null,
- timeout: kSlowOperation,
+ timeout: timeoutConfiguration.slowOperation,
progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below.
);
expect(outputStderr().length, equals(1));
@@ -661,8 +661,8 @@
testUsingContext('sequential startProgress calls with StdoutLogger', () async {
final Logger logger = context[Logger];
- logger.startProgress('AAA', timeout: kFastOperation)..stop();
- logger.startProgress('BBB', timeout: kFastOperation)..stop();
+ logger.startProgress('AAA', timeout: timeoutConfiguration.fastOperation)..stop();
+ logger.startProgress('BBB', timeout: timeoutConfiguration.fastOperation)..stop();
final List<String> output = outputStdout();
expect(output.length, equals(3));
// There's 61 spaces at the start: 59 (padding default) - 3 (length of AAA) + 5 (margin).
@@ -679,8 +679,8 @@
testUsingContext('sequential startProgress calls with VerboseLogger and StdoutLogger', () async {
final Logger logger = context[Logger];
- logger.startProgress('AAA', timeout: kFastOperation)..stop();
- logger.startProgress('BBB', timeout: kFastOperation)..stop();
+ logger.startProgress('AAA', timeout: timeoutConfiguration.fastOperation)..stop();
+ logger.startProgress('BBB', timeout: timeoutConfiguration.fastOperation)..stop();
expect(outputStdout(), <Matcher>[
matches(r'^\[ (?: {0,2}\+[0-9]{1,3} ms| )\] AAA$'),
matches(r'^\[ (?: {0,2}\+[0-9]{1,3} ms| )\] AAA \(completed.*\)$'),
@@ -696,8 +696,8 @@
testUsingContext('sequential startProgress calls with BufferLogger', () async {
final BufferLogger logger = context[Logger];
- logger.startProgress('AAA', timeout: kFastOperation)..stop();
- logger.startProgress('BBB', timeout: kFastOperation)..stop();
+ logger.startProgress('AAA', timeout: timeoutConfiguration.fastOperation)..stop();
+ logger.startProgress('BBB', timeout: timeoutConfiguration.fastOperation)..stop();
expect(logger.statusText, 'AAA\nBBB\n');
}, overrides: <Type, Generator>{
Logger: () => BufferLogger(),
diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart
index 9326144..d89d322 100644
--- a/packages/flutter_tools/test/src/context.dart
+++ b/packages/flutter_tools/test/src/context.dart
@@ -86,6 +86,7 @@
Usage: () => MockUsage(),
XcodeProjectInterpreter: () => MockXcodeProjectInterpreter(),
FileSystem: () => LocalFileSystemBlockingSetCurrentDirectory(),
+ TimeoutConfiguration: () => const TimeoutConfiguration(),
},
body: () {
final String flutterRoot = getFlutterRoot();