From 17e0fe1a93b6afedf0c03288af7350da4af815c4 Mon Sep 17 00:00:00 2001 From: Elias Yishak <42216813+eliasyishak@users.noreply.github.com> Date: Mon, 6 Nov 2023 16:33:11 -0500 Subject: [PATCH] Migration for `HotEvent` for Flutter hot runner (#137717) Related to tracker issue: - https://github.com/flutter/flutter/issues/128251 For this migration, the `HotEvent` was being referenced in 2 additional files outside of `lib/src/reporting/events.dart`, shown below in the screenshot image --- .../lib/src/commands/attach.dart | 4 + .../lib/src/commands/daemon.dart | 2 + .../flutter_tools/lib/src/commands/run.dart | 2 + .../lib/src/drive/web_driver_service.dart | 1 + .../lib/src/isolated/resident_web_runner.dart | 18 ++- packages/flutter_tools/lib/src/run_hot.dart | 115 ++++++++++++++++-- .../lib/src/runner/flutter_command.dart | 6 + .../flutter_tools/lib/src/web/web_runner.dart | 3 + packages/flutter_tools/pubspec.yaml | 4 +- .../commands.shard/hermetic/attach_test.dart | 2 + .../drive/web_driver_service_test.dart | 17 ++- .../test/general.shard/hot_test.dart | 80 ++++++++++++ .../general.shard/resident_runner_test.dart | 82 +++++++++++++ .../resident_web_runner_cold_test.dart | 21 ++++ .../resident_web_runner_test.dart | 52 ++++++++ .../test/general.shard/run_hot_test.dart | 2 + 16 files changed, 394 insertions(+), 17 deletions(-) diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index dfcd365d4098..615e7e392e73 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart'; import '../android/android_device.dart'; @@ -538,6 +539,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. dillOutputPath: stringArg('output-dill'), ipv6: usesIpv6, flutterProject: flutterProject, + analytics: analytics, ) : ColdRunner( flutterDevices, @@ -570,6 +572,7 @@ class HotRunnerFactory { bool stayResident = true, bool ipv6 = false, FlutterProject? flutterProject, + required Analytics analytics, }) => HotRunner( devices, target: target, @@ -581,5 +584,6 @@ class HotRunnerFactory { dillOutputPath: dillOutputPath, stayResident: stayResident, ipv6: ipv6, + analytics: analytics, ); } diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index b63a9acdbb3c..6515826981fd 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -545,6 +545,7 @@ class AppDomain extends Domain { urlTunneller: options.webEnableExposeUrl! ? daemon.daemonDomain.exposeUrl : null, machine: machine, usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, logger: globals.logger, fileSystem: globals.fs, @@ -561,6 +562,7 @@ class AppDomain extends Domain { multidexEnabled: multidexEnabled, hostIsIde: true, machine: machine, + analytics: globals.analytics, ); } else { runner = ColdRunner( diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index 39c38b8187c5..a11116851def 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -597,6 +597,7 @@ class RunCommand extends RunCommandBase { stayResident: stayResident, ipv6: ipv6 ?? false, multidexEnabled: boolArg('multidex'), + analytics: globals.analytics, ); } else if (webMode) { return webRunnerFactory!.createWebRunner( @@ -608,6 +609,7 @@ class RunCommand extends RunCommandBase { stayResident: stayResident, fileSystem: globals.fs, usage: globals.flutterUsage, + analytics: globals.analytics, logger: globals.logger, systemClock: globals.systemClock, ); diff --git a/packages/flutter_tools/lib/src/drive/web_driver_service.dart b/packages/flutter_tools/lib/src/drive/web_driver_service.dart index ffd4a990dcf3..1945c2eb7118 100644 --- a/packages/flutter_tools/lib/src/drive/web_driver_service.dart +++ b/packages/flutter_tools/lib/src/drive/web_driver_service.dart @@ -89,6 +89,7 @@ class WebDriverService extends DriverService { flutterProject: FlutterProject.current(), fileSystem: globals.fs, usage: globals.flutterUsage, + analytics: globals.analytics, logger: _logger, systemClock: globals.systemClock, ); diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart index 0cd25771b0f7..8d1fe8f92074 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -7,6 +7,7 @@ import 'dart:async'; // ignore: import_of_legacy_library_into_null_safe import 'package:dwds/dwds.dart'; import 'package:package_config/package_config.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vmservice; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' hide StackTrace; @@ -57,6 +58,7 @@ class DwdsWebRunnerFactory extends WebRunnerFactory { required FileSystem fileSystem, required SystemClock systemClock, required Usage usage, + required Analytics analytics, bool machine = false, }) { return ResidentWebRunner( @@ -69,6 +71,7 @@ class DwdsWebRunnerFactory extends WebRunnerFactory { urlTunneller: urlTunneller, machine: machine, usage: usage, + analytics: analytics, systemClock: systemClock, fileSystem: fileSystem, logger: logger, @@ -93,12 +96,14 @@ class ResidentWebRunner extends ResidentRunner { required Logger logger, required SystemClock systemClock, required Usage usage, + required Analytics analytics, UrlTunneller? urlTunneller, ResidentDevtoolsHandlerFactory devtoolsHandler = createDefaultHandler, }) : _fileSystem = fileSystem, _logger = logger, _systemClock = systemClock, _usage = usage, + _analytics = analytics, _urlTunneller = urlTunneller, super( [device], @@ -114,6 +119,7 @@ class ResidentWebRunner extends ResidentRunner { final Logger _logger; final SystemClock _systemClock; final Usage _usage; + final Analytics _analytics; final UrlTunneller? _urlTunneller; @override @@ -441,15 +447,25 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). // Don't track restart times for dart2js builds or web-server devices. if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) { _usage.sendTiming('hot', 'web-incremental-restart', elapsed); + final String sdkName = await device!.device!.sdkNameAndVersion; HotEvent( 'restart', targetPlatform: getNameForTargetPlatform(TargetPlatform.web_javascript), - sdkName: await device!.device!.sdkNameAndVersion, + sdkName: sdkName, emulator: false, fullRestart: true, reason: reason, overallTimeInMs: elapsed.inMilliseconds, ).send(); + _analytics.send(Event.hotRunnerInfo( + label: 'restart', + targetPlatform: getNameForTargetPlatform(TargetPlatform.web_javascript), + sdkName: sdkName, + emulator: false, + fullRestart: true, + reason: reason, + overallTimeInMs: elapsed.inMilliseconds + )); } return OperationResult.ok; } diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 6e829ed18c73..939f14ee2dfb 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:meta/meta.dart'; import 'package:package_config/package_config.dart'; import 'package:pool/pool.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import 'base/context.dart'; @@ -94,17 +95,20 @@ class HotRunner extends ResidentRunner { ReloadSourcesHelper reloadSourcesHelper = defaultReloadSourcesHelper, ReassembleHelper reassembleHelper = _defaultReassembleHelper, NativeAssetsBuildRunner? buildRunner, - }) : _stopwatchFactory = stopwatchFactory, - _reloadSourcesHelper = reloadSourcesHelper, - _reassembleHelper = reassembleHelper, + required Analytics analytics, + }) : _stopwatchFactory = stopwatchFactory, + _reloadSourcesHelper = reloadSourcesHelper, + _reassembleHelper = reassembleHelper, _buildRunner = buildRunner, - super( + _analytics = analytics, + super( hotMode: true, ); final StopwatchFactory _stopwatchFactory; final ReloadSourcesHelper _reloadSourcesHelper; final ReassembleHelper _reassembleHelper; + final Analytics _analytics; final bool benchmarkMode; final File? applicationBinary; @@ -429,15 +433,29 @@ class HotRunner extends ResidentRunner { })); } - unawaited(appStartedCompleter?.future.then((_) => HotEvent('reload-ready', - targetPlatform: _targetPlatform!, - sdkName: _sdkName!, - emulator: _emulator!, - fullRestart: false, - overallTimeInMs: appStartedTimer.elapsed.inMilliseconds, - compileTimeInMs: totalCompileTime.inMilliseconds, - transferTimeInMs: totalLaunchAppTime.inMilliseconds, - ).send())); + unawaited(appStartedCompleter?.future.then((_) { + HotEvent( + 'reload-ready', + targetPlatform: _targetPlatform!, + sdkName: _sdkName!, + emulator: _emulator!, + fullRestart: false, + overallTimeInMs: appStartedTimer.elapsed.inMilliseconds, + compileTimeInMs: totalCompileTime.inMilliseconds, + transferTimeInMs: totalLaunchAppTime.inMilliseconds, + ).send(); + + _analytics.send(Event.hotRunnerInfo( + label: 'reload-ready', + targetPlatform: _targetPlatform!, + sdkName: _sdkName!, + emulator: _emulator!, + fullRestart: false, + overallTimeInMs: appStartedTimer.elapsed.inMilliseconds, + compileTimeInMs: totalCompileTime.inMilliseconds, + transferTimeInMs: totalLaunchAppTime.inMilliseconds, + )); + })); try { final List results = await Future.wait(startupTasks); @@ -828,6 +846,21 @@ class HotRunner extends ResidentRunner { findInvalidatedTimeInMs: result.updateFSReport?.findInvalidatedDuration.inMilliseconds, scannedSourcesCount: result.updateFSReport?.scannedSourcesCount, ).send(); + _analytics.send(Event.hotRunnerInfo( + label: 'restart', + targetPlatform: targetPlatform, + sdkName: sdkName, + emulator: emulator, + fullRestart: true, + reason: reason, + overallTimeInMs: restartTimer.elapsed.inMilliseconds, + syncedBytes: result.updateFSReport?.syncedBytes, + invalidatedSourcesCount: result.updateFSReport?.invalidatedSourcesCount, + transferTimeInMs: result.updateFSReport?.transferDuration.inMilliseconds, + compileTimeInMs: result.updateFSReport?.compileDuration.inMilliseconds, + findInvalidatedTimeInMs: result.updateFSReport?.findInvalidatedDuration.inMilliseconds, + scannedSourcesCount: result.updateFSReport?.scannedSourcesCount, + )); } } on vm_service.SentinelException catch (err, st) { restartEvent = 'exception'; @@ -846,6 +879,14 @@ class HotRunner extends ResidentRunner { fullRestart: true, reason: reason, ).send(); + _analytics.send(Event.hotRunnerInfo( + label: restartEvent, + targetPlatform: targetPlatform, + sdkName: sdkName, + emulator: emulator, + fullRestart: true, + reason: reason, + )); } status?.cancel(); } @@ -895,6 +936,14 @@ class HotRunner extends ResidentRunner { fullRestart: false, reason: reason, ).send(); + _analytics.send(Event.hotRunnerInfo( + label: 'reload-barred', + targetPlatform: targetPlatform, + sdkName: sdkName, + emulator: emulator, + fullRestart: false, + reason: reason, + )); } else { HotEvent('exception', targetPlatform: targetPlatform!, @@ -903,6 +952,14 @@ class HotRunner extends ResidentRunner { fullRestart: false, reason: reason, ).send(); + _analytics.send(Event.hotRunnerInfo( + label: 'exception', + targetPlatform: targetPlatform, + sdkName: sdkName, + emulator: emulator, + fullRestart: false, + reason: reason, + )); } return OperationResult(errorCode, errorMessage, fatal: true); } finally { @@ -965,6 +1022,7 @@ class HotRunner extends ResidentRunner { emulator, reason, globals.flutterUsage, + globals.analytics, ); if (result.code != 0) { return result; @@ -1024,6 +1082,27 @@ class HotRunner extends ResidentRunner { reassembleTimeInMs: reassembleTimer.elapsed.inMilliseconds, reloadVMTimeInMs: reloadVMTimer.elapsed.inMilliseconds, ).send(); + _analytics.send(Event.hotRunnerInfo( + label: 'reload', + targetPlatform: targetPlatform, + sdkName: sdkName, + emulator: emulator, + fullRestart: false, + reason: reason, + overallTimeInMs: reloadInMs, + finalLibraryCount: firstReloadDetails['finalLibraryCount'] as int? ?? 0, + syncedLibraryCount: firstReloadDetails['receivedLibraryCount'] as int? ?? 0, + syncedClassesCount: firstReloadDetails['receivedClassesCount'] as int? ?? 0, + syncedProceduresCount: firstReloadDetails['receivedProceduresCount'] as int? ?? 0, + syncedBytes: updatedDevFS.syncedBytes, + invalidatedSourcesCount: updatedDevFS.invalidatedSourcesCount, + transferTimeInMs: updatedDevFS.transferDuration.inMilliseconds, + compileTimeInMs: updatedDevFS.compileDuration.inMilliseconds, + findInvalidatedTimeInMs: updatedDevFS.findInvalidatedDuration.inMilliseconds, + scannedSourcesCount: updatedDevFS.scannedSourcesCount, + reassembleTimeInMs: reassembleTimer.elapsed.inMilliseconds, + reloadVMTimeInMs: reloadVMTimer.elapsed.inMilliseconds, + )); if (shouldReportReloadTime) { globals.printTrace('Hot reload performed in ${getElapsedAsMilliseconds(reloadDuration)}.'); @@ -1186,6 +1265,7 @@ typedef ReloadSourcesHelper = Future Function( bool? emulator, String? reason, Usage usage, + Analytics analytics, ); @visibleForTesting @@ -1199,6 +1279,7 @@ Future defaultReloadSourcesHelper( bool? emulator, String? reason, Usage usage, + Analytics analytics, ) async { final Stopwatch vmReloadTimer = Stopwatch()..start(); const String entryPath = 'main.dart.incremental.dill'; @@ -1239,6 +1320,14 @@ Future defaultReloadSourcesHelper( reason: reason, usage: usage, ).send(); + analytics.send(Event.hotRunnerInfo( + label: 'reload-reject', + targetPlatform: targetPlatform, + sdkName: sdkName, + emulator: emulator, + fullRestart: false, + reason: reason, + )); // Reset devFS lastCompileTime to ensure the file will still be marked // as dirty on subsequent reloads. _resetDevFSCompileTime(flutterDevices); diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index a52083fb0da5..05f9250ddb2f 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -7,6 +7,7 @@ import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:meta/meta.dart'; import 'package:package_config/package_config_types.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../application_package.dart'; import '../base/common.dart'; @@ -223,6 +224,11 @@ abstract class FlutterCommand extends Command { bool _excludeDebug = false; bool _excludeRelease = false; + /// Grabs the [Analytics] instance from the global context. It is defined + /// at the [FlutterCommand] level to enable any classes that extend it to + /// easily reference it or overwrite as necessary. + Analytics get analytics => globals.analytics; + void requiresPubspecYaml() { _requiresPubspecYaml = true; } diff --git a/packages/flutter_tools/lib/src/web/web_runner.dart b/packages/flutter_tools/lib/src/web/web_runner.dart index 1ffe0771c639..475a3ef5fc60 100644 --- a/packages/flutter_tools/lib/src/web/web_runner.dart +++ b/packages/flutter_tools/lib/src/web/web_runner.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:unified_analytics/unified_analytics.dart'; + import '../base/context.dart'; import '../base/file_system.dart'; import '../base/logger.dart'; @@ -31,6 +33,7 @@ abstract class WebRunnerFactory { required FileSystem fileSystem, required SystemClock systemClock, required Usage usage, + required Analytics analytics, bool machine = false, }); } diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml index f24c57b08a7c..f0e6e36d6fe8 100644 --- a/packages/flutter_tools/pubspec.yaml +++ b/packages/flutter_tools/pubspec.yaml @@ -48,7 +48,7 @@ dependencies: http_multi_server: 3.2.1 convert: 3.1.1 async: 2.11.0 - unified_analytics: 5.1.0 + unified_analytics: 5.2.0 cli_config: 0.1.2 graphs: 2.3.1 @@ -114,4 +114,4 @@ dartdoc: # Exclude this package from the hosted API docs. nodoc: true -# PUBSPEC CHECKSUM: 490d +# PUBSPEC CHECKSUM: 080e diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart index d334c8aa9dd8..33301432cc1c 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart @@ -33,6 +33,7 @@ import 'package:flutter_tools/src/run_hot.dart'; import 'package:flutter_tools/src/vmservice.dart'; import 'package:multicast_dns/multicast_dns.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import '../../src/common.dart'; @@ -1199,6 +1200,7 @@ class FakeHotRunnerFactory extends Fake implements HotRunnerFactory { bool stayResident = true, bool ipv6 = false, FlutterProject? flutterProject, + Analytics? analytics, }) { if (_artifactTester != null) { for (final FlutterDevice device in devices) { diff --git a/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart b/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart index 28f66f2cc2fd..2c73630d7bb3 100644 --- a/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart +++ b/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart @@ -17,6 +17,7 @@ import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/resident_runner.dart'; import 'package:flutter_tools/src/web/web_runner.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:webdriver/sync_io.dart' as sync_io; import '../../src/common.dart'; @@ -303,7 +304,21 @@ class FakeWebRunnerFactory implements WebRunnerFactory { final bool doResolveToError; @override - ResidentRunner createWebRunner(FlutterDevice device, {String? target, bool? stayResident, FlutterProject? flutterProject, bool? ipv6, DebuggingOptions? debuggingOptions, UrlTunneller? urlTunneller, Logger? logger, FileSystem? fileSystem, SystemClock? systemClock, Usage? usage, bool machine = false}) { + ResidentRunner createWebRunner( + FlutterDevice device, { + String? target, + bool? stayResident, + FlutterProject? flutterProject, + bool? ipv6, + DebuggingOptions? debuggingOptions, + UrlTunneller? urlTunneller, + Logger? logger, + FileSystem? fileSystem, + SystemClock? systemClock, + Usage? usage, + Analytics? analytics, + bool machine = false, + }) { expect(stayResident, isTrue); return FakeResidentRunner( doResolveToError: doResolveToError, diff --git a/packages/flutter_tools/test/general.shard/hot_test.dart b/packages/flutter_tools/test/general.shard/hot_test.dart index b30361d36765..4fad1eb422ac 100644 --- a/packages/flutter_tools/test/general.shard/hot_test.dart +++ b/packages/flutter_tools/test/general.shard/hot_test.dart @@ -25,6 +25,7 @@ import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode, Target import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli; import 'package:package_config/package_config.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import '../src/common.dart'; @@ -120,10 +121,15 @@ void main() { final FakeResidentCompiler residentCompiler = FakeResidentCompiler(); late FileSystem fileSystem; late TestUsage testUsage; + late FakeAnalytics fakeAnalytics; setUp(() { fileSystem = MemoryFileSystem.test(); testUsage = TestUsage(); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); }); group('fails to setup', () { @@ -149,6 +155,8 @@ void main() { debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, + ).restart(fullRestart: true); expect(result.isOk, false); expect(result.message, 'setupHotRestart failed'); @@ -185,6 +193,7 @@ void main() { false, true, ), + analytics: fakeAnalytics, ).restart(); expect(result.isOk, false); expect(result.message, 'setupHotReload failed'); @@ -217,6 +226,7 @@ void main() { devices, debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), target: 'main.dart', + analytics: fakeAnalytics, ).cleanupAfterSignal(); expect(shutdownTestingConfig.shutdownHookCalled, true); }, overrides: { @@ -239,6 +249,7 @@ void main() { devices, debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), target: 'main.dart', + analytics: fakeAnalytics, ).preExit(); expect(shutdownTestingConfig.shutdownHookCalled, true); }, overrides: { @@ -288,6 +299,7 @@ void main() { target: 'main.dart', devtoolsHandler: createNoOpHandler, stopwatchFactory: fakeStopwatchFactory, + analytics: fakeAnalytics, ).restart(fullRestart: true); expect(result.isOk, true); @@ -306,6 +318,23 @@ void main() { hotEventScannedSourcesCount: 8, )), ]); + + expect(fakeAnalytics.sentEvents, contains( + Event.hotRunnerInfo( + label: 'restart', + targetPlatform: 'flutter-tester', + sdkName: 'Tester', + emulator: false, + fullRestart: true, + syncedBytes: 4, + invalidatedSourcesCount: 2, + transferTimeInMs: 32000, + overallTimeInMs: 64000, + compileTimeInMs: 16000, + findInvalidatedTimeInMs: 128000, + scannedSourcesCount: 8 + ) + )); expect(testingConfig.updateDevFSCompleteCalled, true); }, overrides: { HotRunnerConfig: () => testingConfig, @@ -357,6 +386,7 @@ void main() { target: 'main.dart', devtoolsHandler: createNoOpHandler, stopwatchFactory: fakeStopwatchFactory, + analytics: fakeAnalytics, reloadSourcesHelper: ( HotRunner hotRunner, List flutterDevices, @@ -367,6 +397,7 @@ void main() { bool? emulator, String? reason, Usage usage, + Analytics? analytics, ) async { firstReloadDetails['finalLibraryCount'] = 2; firstReloadDetails['receivedLibraryCount'] = 3; @@ -408,6 +439,28 @@ void main() { hotEventReloadVMTimeInMs: 512000, )), ]); + expect(fakeAnalytics.sentEvents, contains( + Event.hotRunnerInfo( + label: 'reload', + targetPlatform: 'flutter-tester', + sdkName: 'Tester', + emulator: false, + fullRestart: false, + finalLibraryCount: 2, + syncedLibraryCount: 3, + syncedClassesCount: 4, + syncedProceduresCount: 5, + syncedBytes: 8, + invalidatedSourcesCount: 6, + transferTimeInMs: 32000, + overallTimeInMs: 128000, + compileTimeInMs: 16000, + findInvalidatedTimeInMs: 64000, + scannedSourcesCount: 16, + reassembleTimeInMs: 256000, + reloadVMTimeInMs: 512000 + ), + )); expect(testingConfig.updateDevFSCompleteCalled, true); }, overrides: { HotRunnerConfig: () => testingConfig, @@ -439,6 +492,7 @@ void main() { debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await expectLater(runner.restart(fullRestart: true), throwsA(isA().having((Exception e) => e.toString(), 'message', 'Exception: updateDevFS failed'))); @@ -473,6 +527,7 @@ void main() { debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await expectLater(runner.restart(), throwsA(isA().having((Exception e) => e.toString(), 'message', 'Exception: updateDevFS failed'))); @@ -490,9 +545,14 @@ void main() { group('hot attach', () { late FileSystem fileSystem; + late FakeAnalytics fakeAnalytics; setUp(() { fileSystem = MemoryFileSystem.test(); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); }); testUsingContext('Exits with code 2 when HttpException is thrown ' @@ -515,6 +575,7 @@ void main() { final int exitCode = await HotRunner(devices, debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', + analytics: fakeAnalytics, ).attach(needsFullRestart: false); expect(exitCode, 2); }, overrides: { @@ -527,6 +588,17 @@ void main() { }); group('hot cleanupAtFinish()', () { + late FileSystem fileSystem; + late FakeAnalytics fakeAnalytics; + + setUp(() { + fileSystem = MemoryFileSystem.test(); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); + }); + testUsingContext('disposes each device', () async { final FakeDevice device1 = FakeDevice(); final FakeDevice device2 = FakeDevice(); @@ -541,6 +613,7 @@ void main() { await HotRunner(devices, debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', + analytics: fakeAnalytics, ).cleanupAtFinish(); expect(device1.disposed, true); @@ -554,12 +627,17 @@ void main() { group('native assets', () { late TestHotRunnerConfig testingConfig; late FileSystem fileSystem; + late FakeAnalytics fakeAnalytics; setUp(() { fileSystem = MemoryFileSystem.test(); testingConfig = TestHotRunnerConfig( successfulHotRestartSetup: true, ); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); }); testUsingContext('native assets restart', () async { final FakeDevice device = FakeDevice(); @@ -601,6 +679,7 @@ void main() { target: 'main.dart', devtoolsHandler: createNoOpHandler, buildRunner: buildRunner, + analytics: fakeAnalytics, ); final OperationResult result = await hotRunner.restart(fullRestart: true); expect(result.isOk, true); @@ -659,6 +738,7 @@ void main() { target: 'main.dart', devtoolsHandler: createNoOpHandler, buildRunner: buildRunner, + analytics: fakeAnalytics, ); expect( () => hotRunner.run(), diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart index 65b6e4428dfb..a0e2b90630fc 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -41,6 +41,7 @@ import 'package:native_assets_cli/native_assets_cli.dart' import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli; import 'package:package_config/package_config.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import '../src/common.dart'; @@ -170,10 +171,16 @@ void main() { late FakeDevFS devFS; late ResidentRunner residentRunner; late FakeDevice device; + late FakeAnalytics fakeAnalytics; FakeVmServiceHost? fakeVmServiceHost; setUp(() { testbed = Testbed(setup: () { + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: globals.fs, + fakeFlutterVersion: FakeFlutterVersion(), + ); + globals.fs.file('.packages') .writeAsStringSync('\n'); globals.fs.file(globals.fs.path.join('build', 'app.dill')) @@ -187,6 +194,7 @@ void main() { debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); }); device = FakeDevice(); @@ -236,6 +244,7 @@ void main() { debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); flutterDevice.generator = residentCompiler; @@ -259,6 +268,7 @@ void main() { debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); flutterDevice.generator = residentCompiler; @@ -328,6 +338,7 @@ void main() { debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); flutterDevice.generator = residentCompiler; @@ -387,6 +398,7 @@ void main() { ), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); final Completer futureConnectionInfo = Completer.sync(); final Completer futureAppStart = Completer.sync(); @@ -431,6 +443,15 @@ void main() { hotEventFullRestart: false, )), )); + expect(fakeAnalytics.sentEvents, contains( + Event.hotRunnerInfo( + label: 'exception', + targetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm), + sdkName: 'Android', + emulator: false, + fullRestart: false, + ), + )); expect(fakeVmServiceHost?.hasRemainingExpectations, false); }, overrides: { Usage: () => TestUsage(), @@ -486,6 +507,15 @@ void main() { hotEventFullRestart: false, )), )); + expect(fakeAnalytics.sentEvents, contains( + Event.hotRunnerInfo( + label: 'reload-barred', + targetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm), + sdkName: 'Android', + emulator: false, + fullRestart: false, + ) + )); expect(fakeVmServiceHost?.hasRemainingExpectations, false); }, overrides: { Usage: () => TestUsage(), @@ -509,6 +539,7 @@ void main() { ], )), devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); final Completer futureConnectionInfo = Completer.sync(); final Completer futureAppStart = Completer.sync(); @@ -532,6 +563,15 @@ void main() { hotEventFullRestart: false, )), )); + expect(fakeAnalytics.sentEvents, contains( + Event.hotRunnerInfo( + label: 'exception', + targetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm), + sdkName: 'Android', + emulator: false, + fullRestart: false, + ) + )); expect(fakeVmServiceHost?.hasRemainingExpectations, false); }, overrides: { Usage: () => TestUsage(), @@ -564,6 +604,7 @@ void main() { debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); final Completer futureConnectionInfo = Completer.sync(); final Completer futureAppStart = Completer.sync(); @@ -764,6 +805,12 @@ void main() { expect(event.category, 'hot'); expect(event.parameter, 'reload'); expect(event.parameters?.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm)); + + final Event newEvent = fakeAnalytics.sentEvents.first; + expect(newEvent.eventName.label, 'hot_runner_info'); + expect(newEvent.eventData['label'], 'reload'); + expect(newEvent.eventData['targetPlatform'], getNameForTargetPlatform(TargetPlatform.android_arm)); + }, overrides: { Usage: () => TestUsage(), })); @@ -825,6 +872,7 @@ void main() { debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); devFS.nextUpdateReport = UpdateFSReport( success: true, @@ -910,6 +958,13 @@ void main() { expect(event.parameter, 'restart'); expect(event.parameters?.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm)); expect(fakeVmServiceHost?.hasRemainingExpectations, false); + + + final Event newEvent = fakeAnalytics.sentEvents.first; + expect(newEvent.eventName.label, 'hot_runner_info'); + expect(newEvent.eventData['label'], 'restart'); + expect(newEvent.eventData['targetPlatform'], getNameForTargetPlatform(TargetPlatform.android_arm)); + }, overrides: { Usage: () => TestUsage(), })); @@ -1136,6 +1191,15 @@ void main() { hotEventFullRestart: true, )), )); + expect(fakeAnalytics.sentEvents, contains( + Event.hotRunnerInfo( + label: 'exception', + targetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm), + sdkName: 'Android', + emulator: false, + fullRestart: true, + ), + )); expect(fakeVmServiceHost?.hasRemainingExpectations, false); }, overrides: { Usage: () => TestUsage(), @@ -1154,6 +1218,7 @@ void main() { dillOutputPath: globals.fs.path.join('foobar', 'app.dill'), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); expect(otherRunner.artifactDirectory.path, contains('foobar')); })); @@ -1269,6 +1334,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'custom_main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await residentRunner.runSourceGenerators(); @@ -1328,6 +1394,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); flutterDevice.generator = residentCompiler; @@ -1597,6 +1664,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await residentRunner.run(enableDevTools: true); @@ -1625,6 +1693,7 @@ flutter: ), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); @@ -1654,6 +1723,7 @@ flutter: ), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); @@ -1684,6 +1754,7 @@ flutter: ), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); @@ -1707,6 +1778,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); @@ -1731,6 +1803,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); @@ -1758,6 +1831,7 @@ flutter: )), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); @@ -1780,6 +1854,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await residentRunner.run(); @@ -1800,6 +1875,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await residentRunner.run(enableDevTools: true); @@ -2255,6 +2331,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); await residentRunner.cleanupAtFinish(); @@ -2275,6 +2352,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); (flutterDevice.devFS! as FakeDevFS).assetPathsToEvict = {'asset'}; @@ -2299,6 +2377,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); (flutterDevice.devFS! as FakeDevFS).shaderPathsToEvict = {'foo.frag'}; @@ -2320,6 +2399,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); expect(flutterDevice.devFS!.hasSetAssetDirectory, false); @@ -2341,6 +2421,7 @@ flutter: debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', devtoolsHandler: createNoOpHandler, + analytics: fakeAnalytics, ); (flutterDevice.devFS! as FakeDevFS).assetPathsToEvict = {'asset'}; @@ -2412,6 +2493,7 @@ flutter: target: 'main.dart', devtoolsHandler: createNoOpHandler, buildRunner: buildRunner, + analytics: fakeAnalytics, ); final int? result = await residentRunner.run(); diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart index 60206c2da2a7..4c467bb82650 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart @@ -23,6 +23,7 @@ import 'package:test/fake.dart'; import '../src/common.dart'; import '../src/context.dart'; +import '../src/fakes.dart'; import '../src/test_build_system.dart'; void main() { @@ -54,6 +55,10 @@ void main() { logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), usage: TestUsage(), + analytics: getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ), ); final Completer connectionInfoCompleter = Completer(); @@ -81,6 +86,10 @@ void main() { logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), usage: TestUsage(), + analytics: getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ), ); expect(() => residentWebRunner.run(), throwsToolExit()); @@ -103,6 +112,10 @@ void main() { logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), usage: TestUsage(), + analytics: getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ), ); expect(() async => residentWebRunner.run(), throwsException); @@ -124,6 +137,10 @@ void main() { logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), usage: TestUsage(), + analytics: getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ), ); final Completer connectionInfoCompleter = Completer(); unawaited(residentWebRunner.run( @@ -150,6 +167,10 @@ void main() { logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), usage: TestUsage(), + analytics: getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ), ); final Completer connectionInfoCompleter = Completer(); unawaited(residentWebRunner.run( diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index f7b63a0f9364..7eb4a3ad1e08 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart @@ -34,6 +34,7 @@ import 'package:flutter_tools/src/web/web_device.dart'; import 'package:package_config/package_config.dart'; import 'package:package_config/package_config_types.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; @@ -41,6 +42,7 @@ import '../src/common.dart'; import '../src/context.dart'; import '../src/fake_process_manager.dart'; import '../src/fake_vm_services.dart'; +import '../src/fakes.dart' as test_fakes; const List kAttachLogExpectations = [ @@ -103,6 +105,7 @@ void main() { late FileSystem fileSystem; late ProcessManager processManager; late TestUsage testUsage; + late FakeAnalytics fakeAnalytics; setUp(() { testUsage = TestUsage(); @@ -122,6 +125,10 @@ void main() { ..device = mockDevice ..generator = residentCompiler; fileSystem.file('.packages').writeAsStringSync('\n'); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: test_fakes.FakeFlutterVersion(), + ); }); void setupMocks() { @@ -156,6 +163,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -188,6 +196,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -207,6 +216,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); fakeVmServiceHost = FakeVmServiceHost(requests: []); @@ -220,6 +230,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -353,6 +364,7 @@ void main() { fileSystem: fileSystem, logger: logger, usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -379,6 +391,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -579,6 +592,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); fakeVmServiceHost = @@ -663,11 +677,25 @@ void main() { 'cd48': 'false' })), ]); + expect( + fakeAnalytics.sentEvents, + contains( + Event.hotRunnerInfo( + label: 'restart', + targetPlatform: 'web-javascript', + sdkName: '', + emulator: false, + fullRestart: true, + overallTimeInMs: 0, + ), + ), + ); expect(testUsage.timings, const [ TestTimingEvent('hot', 'web-incremental-restart', Duration.zero), ]); }, overrides: { Usage: () => testUsage, + Analytics: () => fakeAnalytics, FileSystem: () => fileSystem, ProcessManager: () => processManager, }); @@ -735,11 +763,25 @@ void main() { 'cd48': 'false' })), ]); + expect( + fakeAnalytics.sentEvents, + contains( + Event.hotRunnerInfo( + label: 'restart', + targetPlatform: 'web-javascript', + sdkName: '', + emulator: false, + fullRestart: true, + overallTimeInMs: 0, + ), + ), + ); expect(testUsage.timings, const [ TestTimingEvent('hot', 'web-incremental-restart', Duration.zero), ]); }, overrides: { Usage: () => testUsage, + Analytics: () => fakeAnalytics, FileSystem: () => fileSystem, ProcessManager: () => processManager, }); @@ -771,9 +813,11 @@ void main() { // web-server device does not send restart analytics expect(testUsage.events, isEmpty); + expect(fakeAnalytics.sentEvents, isEmpty); expect(testUsage.timings, isEmpty); }, overrides: { Usage: () => testUsage, + Analytics: () => fakeAnalytics, FileSystem: () => fileSystem, ProcessManager: () => processManager, }); @@ -803,9 +847,11 @@ void main() { expect(await residentWebRunner.run(), 1); expect(testUsage.events, isEmpty); + expect(fakeAnalytics.sentEvents, isEmpty); expect(testUsage.timings, isEmpty); }, overrides: { Usage: () => testUsage, + Analytics: () => fakeAnalytics, FileSystem: () => fileSystem, ProcessManager: () => processManager, }); @@ -868,9 +914,11 @@ void main() { expect(result.code, 1); expect(result.message, contains('Failed to recompile application.')); expect(testUsage.events, isEmpty); + expect(fakeAnalytics.sentEvents, isEmpty); expect(testUsage.timings, isEmpty); }, overrides: { Usage: () => testUsage, + Analytics: () => fakeAnalytics, FileSystem: () => fileSystem, ProcessManager: () => processManager, }); @@ -1054,6 +1102,7 @@ void main() { fileSystem: fileSystem, logger: logger, usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -1102,6 +1151,7 @@ void main() { fileSystem: fileSystem, logger: logger, usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -1144,6 +1194,7 @@ void main() { fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: globals.systemClock, ); @@ -1344,6 +1395,7 @@ ResidentRunner setUpResidentRunner( debuggingOptions ?? DebuggingOptions.enabled(BuildInfo.debug), ipv6: true, usage: globals.flutterUsage, + analytics: globals.analytics, systemClock: systemClock ?? SystemClock.fixed(DateTime.now()), fileSystem: globals.fs, logger: logger ?? BufferLogger.test(), diff --git a/packages/flutter_tools/test/general.shard/run_hot_test.dart b/packages/flutter_tools/test/general.shard/run_hot_test.dart index df83239d8003..9c149257e10c 100644 --- a/packages/flutter_tools/test/general.shard/run_hot_test.dart +++ b/packages/flutter_tools/test/general.shard/run_hot_test.dart @@ -8,6 +8,7 @@ import 'package:flutter_tools/src/resident_runner.dart'; import 'package:flutter_tools/src/run_hot.dart'; import 'package:flutter_tools/src/vmservice.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:vm_service/vm_service.dart' as vm_service; //import '../src/context.dart'; @@ -25,6 +26,7 @@ void main() { false, 'test-reason', TestUsage(), + NoOpAnalytics(), ); }); }