diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart index c116923739fd..7e71dcb0100f 100644 --- a/packages/flutter_tools/lib/src/android/gradle.dart +++ b/packages/flutter_tools/lib/src/android/gradle.dart @@ -7,6 +7,7 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:meta/meta.dart'; import 'package:process/process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:xml/xml.dart'; import '../artifacts.dart'; @@ -149,6 +150,7 @@ class AndroidGradleBuilder implements AndroidBuilder { required FileSystem fileSystem, required Artifacts artifacts, required Usage usage, + required Analytics analytics, required GradleUtils gradleUtils, required Platform platform, required AndroidStudio? androidStudio, @@ -157,6 +159,7 @@ class AndroidGradleBuilder implements AndroidBuilder { _fileSystem = fileSystem, _artifacts = artifacts, _usage = usage, + _analytics = analytics, _gradleUtils = gradleUtils, _androidStudio = androidStudio, _fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform), @@ -168,6 +171,7 @@ class AndroidGradleBuilder implements AndroidBuilder { final FileSystem _fileSystem; final Artifacts _artifacts; final Usage _usage; + final Analytics _analytics; final GradleUtils _gradleUtils; final FileSystemUtils _fileSystemUtils; final AndroidStudio? _androidStudio; @@ -300,7 +304,7 @@ class AndroidGradleBuilder implements AndroidBuilder { @visibleForTesting int? maxRetries, }) async { if (!project.android.isSupportedVersion) { - _exitWithUnsupportedProjectMessage(_usage, _logger.terminal); + _exitWithUnsupportedProjectMessage(_usage, _logger.terminal, analytics: _analytics); } final List migrators = [ @@ -318,8 +322,11 @@ class AndroidGradleBuilder implements AndroidBuilder { final bool usesAndroidX = isAppUsingAndroidX(project.android.hostAppGradleRoot); if (usesAndroidX) { BuildEvent('app-using-android-x', type: 'gradle', flutterUsage: _usage).send(); + _analytics.send(Event.flutterBuildInfo(label: 'app-using-android-x', buildType: 'gradle')); } else if (!usesAndroidX) { BuildEvent('app-not-using-android-x', type: 'gradle', flutterUsage: _usage).send(); + _analytics.send(Event.flutterBuildInfo(label: 'app-not-using-android-x', buildType: 'gradle')); + _logger.printStatus("${_logger.terminal.warningMark} Your app isn't using AndroidX.", emphasis: true); _logger.printStatus( 'To avoid potential build failures, you can quickly migrate your app ' @@ -488,6 +495,8 @@ class AndroidGradleBuilder implements AndroidBuilder { if (exitCode != 0) { if (detectedGradleError == null) { BuildEvent('gradle-unknown-failure', type: 'gradle', flutterUsage: _usage).send(); + _analytics.send(Event.flutterBuildInfo(label: 'gradle-unknown-failure', buildType: 'gradle')); + throwToolExit( 'Gradle task $assembleTask failed with exit code $exitCode', exitCode: exitCode, @@ -520,13 +529,19 @@ class AndroidGradleBuilder implements AndroidBuilder { configOnly: configOnly, ); final String successEventLabel = 'gradle-${detectedGradleError!.eventLabel}-success'; + BuildEvent(successEventLabel, type: 'gradle', flutterUsage: _usage).send(); + _analytics.send(Event.flutterBuildInfo(label: successEventLabel, buildType: 'gradle')); + return; case GradleBuildStatus.exit: // Continue and throw tool exit. } } - BuildEvent('gradle-${detectedGradleError?.eventLabel}-failure', type: 'gradle', flutterUsage: _usage).send(); + final String usageLabel = 'gradle-${detectedGradleError?.eventLabel}-failure'; + BuildEvent(usageLabel, type: 'gradle', flutterUsage: _usage).send(); + _analytics.send(Event.flutterBuildInfo(label: usageLabel, buildType: 'gradle')); + throwToolExit( 'Gradle task $assembleTask failed with exit code $exitCode', exitCode: exitCode, @@ -534,7 +549,7 @@ class AndroidGradleBuilder implements AndroidBuilder { } if (isBuildingBundle) { - final File bundleFile = findBundleFile(project, buildInfo, _logger, _usage); + final File bundleFile = findBundleFile(project, buildInfo, _logger, _usage, _analytics); final String appSize = (buildInfo.mode == BuildMode.debug) ? '' // Don't display the size when building a debug variant. : ' (${getSizeAsMB(bundleFile.lengthSync())})'; @@ -551,7 +566,7 @@ class AndroidGradleBuilder implements AndroidBuilder { } // Gradle produced APKs. final Iterable apkFilesPaths = project.isModule - ? findApkFilesModule(project, androidBuildInfo, _logger, _usage) + ? findApkFilesModule(project, androidBuildInfo, _logger, _usage, _analytics) : listApkPaths(androidBuildInfo); final Directory apkDirectory = getApkDirectory(project); @@ -563,6 +578,7 @@ class AndroidGradleBuilder implements AndroidBuilder { fileExtension: '.apk', logger: _logger, usage: _usage, + analytics: _analytics, ); } @@ -886,8 +902,14 @@ String _calculateSha(File file) { return _hex(sha1.convert(bytes).bytes); } -void _exitWithUnsupportedProjectMessage(Usage usage, Terminal terminal) { +void _exitWithUnsupportedProjectMessage(Usage usage, Terminal terminal, {required Analytics analytics}) { BuildEvent('unsupported-project', type: 'gradle', eventError: 'gradle-plugin', flutterUsage: usage).send(); + analytics.send(Event.flutterBuildInfo( + label: 'unsupported-project', + buildType: 'gradle', + error: 'gradle-plugin', + )); + throwToolExit( '${terminal.warningMark} Your app is using an unsupported Gradle project. ' 'To fix this problem, create a new project by running `flutter create -t app ` ' @@ -913,6 +935,7 @@ Iterable findApkFilesModule( AndroidBuildInfo androidBuildInfo, Logger logger, Usage usage, + Analytics analytics, ) { final Iterable apkFileNames = _apkFilesFor(androidBuildInfo); final Directory apkDirectory = getApkDirectory(project); @@ -948,6 +971,7 @@ Iterable findApkFilesModule( fileExtension: '.apk', logger: logger, usage: usage, + analytics: analytics, ); } return apks.map((File file) => file.path); @@ -986,7 +1010,7 @@ Iterable listApkPaths( } @visibleForTesting -File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger, Usage usage) { +File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger, Usage usage, Analytics analytics) { final List fileCandidates = [ getBundleDirectory(project) .childDirectory(camelCase(buildInfo.modeName)) @@ -1043,6 +1067,7 @@ File findBundleFile(FlutterProject project, BuildInfo buildInfo, Logger logger, fileExtension: '.aab', logger: logger, usage: usage, + analytics: analytics, ); } @@ -1052,17 +1077,25 @@ Never _exitWithExpectedFileNotFound({ required String fileExtension, required Logger logger, required Usage usage, + required Analytics analytics, }) { final String androidGradlePluginVersion = getGradleVersionForAndroidPlugin(project.android.hostAppGradleRoot, logger); + final String gradleBuildSettings = 'androidGradlePluginVersion: $androidGradlePluginVersion, ' + 'fileExtension: $fileExtension'; + BuildEvent('gradle-expected-file-not-found', type: 'gradle', - settings: - 'androidGradlePluginVersion: $androidGradlePluginVersion, ' - 'fileExtension: $fileExtension', + settings: gradleBuildSettings, flutterUsage: usage, ).send(); + analytics.send(Event.flutterBuildInfo( + label: 'gradle-expected-file-not-found', + buildType: 'gradle', + settings: gradleBuildSettings, + )); + throwToolExit( 'Gradle build failed to produce an $fileExtension file. ' "It's likely that this file was generated under ${project.android.buildDirectory.path}, " diff --git a/packages/flutter_tools/lib/src/android/gradle_utils.dart b/packages/flutter_tools/lib/src/android/gradle_utils.dart index 14a3d1462b82..78c9e16ba1cb 100644 --- a/packages/flutter_tools/lib/src/android/gradle_utils.dart +++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart @@ -4,6 +4,7 @@ import 'package:meta/meta.dart'; import 'package:process/process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../base/common.dart'; import '../base/file_system.dart'; @@ -741,6 +742,11 @@ void exitWithNoSdkMessage() { eventError: 'android-sdk-not-found', flutterUsage: globals.flutterUsage) .send(); + globals.analytics.send(Event.flutterBuildInfo( + label: 'unsupported-project', + buildType: 'gradle', + error: 'android-sdk-not-found', + )); throwToolExit('${globals.logger.terminal.warningMark} No Android SDK found. ' 'Try setting the ANDROID_HOME environment variable.'); } diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart index 1b286333e598..93c1c625e839 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -7,6 +7,7 @@ import 'dart:typed_data'; import 'package:crypto/crypto.dart'; import 'package:file/file.dart'; import 'package:meta/meta.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../base/analyze_size.dart'; import '../base/common.dart'; @@ -669,7 +670,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { xcodeBuildResult = result; if (!result.success) { - await diagnoseXcodeBuildFailure(result, globals.flutterUsage, globals.logger); + await diagnoseXcodeBuildFailure(result, globals.flutterUsage, globals.logger, globals.analytics); final String presentParticiple = xcodeBuildAction == XcodeBuildAction.build ? 'building' : 'archiving'; throwToolExit('Encountered error while $presentParticiple for $logTarget.'); } @@ -739,13 +740,19 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { final bool? impellerEnabled = globals.plistParser.getValueFromFile( plistPath, PlistParser.kFLTEnableImpellerKey, ); - BuildEvent( - impellerEnabled == false + + final String buildLabel = impellerEnabled == false ? 'plist-impeller-disabled' - : 'plist-impeller-enabled', + : 'plist-impeller-enabled'; + BuildEvent( + buildLabel, type: 'ios', flutterUsage: globals.flutterUsage, ).send(); + globals.analytics.send(Event.flutterBuildInfo( + label: buildLabel, + buildType: 'ios', + )); return FlutterCommandResult.success(); } diff --git a/packages/flutter_tools/lib/src/commands/build_web.dart b/packages/flutter_tools/lib/src/commands/build_web.dart index a0afbe2232cb..cf3f92aee45c 100644 --- a/packages/flutter_tools/lib/src/commands/build_web.dart +++ b/packages/flutter_tools/lib/src/commands/build_web.dart @@ -195,6 +195,7 @@ class BuildWebCommand extends BuildSubCommand { fileSystem: globals.fs, flutterVersion: globals.flutterVersion, usage: globals.flutterUsage, + analytics: globals.analytics, ); await webBuilder.buildWeb( flutterProject, diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index d315398b45c9..4b32aa973757 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -101,6 +101,7 @@ Future runInContext( fileSystem: globals.fs, artifacts: globals.artifacts!, usage: globals.flutterUsage, + analytics: globals.analytics, gradleUtils: globals.gradleUtils!, platform: globals.platform, androidStudio: globals.androidStudio, @@ -387,6 +388,7 @@ Future runInContext( platform: globals.platform, fileSystem: globals.fs, usage: globals.flutterUsage, + analytics: globals.analytics, ), }, ); diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index cf2f0249ccc4..52f586390a69 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart @@ -505,7 +505,7 @@ class IOSDevice extends Device { ); if (!buildResult.success) { _logger.printError('Could not build the precompiled application for the device.'); - await diagnoseXcodeBuildFailure(buildResult, globals.flutterUsage, _logger); + await diagnoseXcodeBuildFailure(buildResult, globals.flutterUsage, _logger, globals.analytics); _logger.printError(''); return LaunchResult.failed(); } diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 6865b3689f5d..406d30b76b74 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'package:meta/meta.dart'; import 'package:process/process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../artifacts.dart'; import '../base/file_system.dart'; @@ -581,17 +582,35 @@ return result.exitCode != 0 && result.stdout.contains(kConcurrentRunFailureMessage2); } -Future diagnoseXcodeBuildFailure(XcodeBuildResult result, Usage flutterUsage, Logger logger) async { +Future diagnoseXcodeBuildFailure( + XcodeBuildResult result, + Usage flutterUsage, + Logger logger, + Analytics analytics, +) async { final XcodeBuildExecution? xcodeBuildExecution = result.xcodeBuildExecution; if (xcodeBuildExecution != null && xcodeBuildExecution.environmentType == EnvironmentType.physical && (result.stdout?.toUpperCase().contains('BITCODE') ?? false)) { - BuildEvent('xcode-bitcode-failure', - type: 'ios', - command: xcodeBuildExecution.buildCommands.toString(), - settings: xcodeBuildExecution.buildSettings.toString(), + + const String label = 'xcode-bitcode-failure'; + const String buildType = 'ios'; + final String command = xcodeBuildExecution.buildCommands.toString(); + final String settings = xcodeBuildExecution.buildSettings.toString(); + + BuildEvent( + label, + type: buildType, + command: command, + settings: settings, flutterUsage: flutterUsage, ).send(); + analytics.send(Event.flutterBuildInfo( + label: label, + buildType: buildType, + command: command, + settings: settings, + )); } // Handle errors. diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 49a6bad2b462..c332964d4953 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -567,7 +567,7 @@ class IOSSimulator extends Device { deviceID: id, ); if (!buildResult.success) { - await diagnoseXcodeBuildFailure(buildResult, globals.flutterUsage, globals.logger); + await diagnoseXcodeBuildFailure(buildResult, globals.flutterUsage, globals.logger, globals.analytics); throwToolExit('Could not build the application for the simulator.'); } diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index bb8153428765..2fb276474861 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -5,6 +5,7 @@ import 'package:file/memory.dart'; import 'package:meta/meta.dart'; import 'package:process/process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../base/common.dart'; import '../base/file_system.dart'; @@ -30,6 +31,7 @@ class XcodeProjectInterpreter { required Logger logger, required FileSystem fileSystem, required Usage usage, + required Analytics analytics, }) { return XcodeProjectInterpreter._( platform: platform, @@ -37,6 +39,7 @@ class XcodeProjectInterpreter { logger: logger, fileSystem: fileSystem, usage: usage, + analytics: analytics, ); } @@ -46,6 +49,7 @@ class XcodeProjectInterpreter { required Logger logger, required FileSystem fileSystem, required Usage usage, + required Analytics analytics, Version? version, String? build, }) : _platform = platform, @@ -61,7 +65,8 @@ class XcodeProjectInterpreter { _version = version, _build = build, _versionText = version?.toString(), - _usage = usage; + _usage = usage, + _analytics = analytics; /// Create an [XcodeProjectInterpreter] for testing. /// @@ -73,6 +78,7 @@ class XcodeProjectInterpreter { required ProcessManager processManager, Version? version = const Version.withText(1000, 0, 0, '1000.0.0'), String? build = '13C100', + Analytics? analytics, }) { final Platform platform = FakePlatform( operatingSystem: 'macos', @@ -86,6 +92,7 @@ class XcodeProjectInterpreter { logger: BufferLogger.test(), version: version, build: build, + analytics: analytics ?? NoOpAnalytics(), ); } @@ -95,6 +102,7 @@ class XcodeProjectInterpreter { final OperatingSystemUtils _operatingSystemUtils; final Logger _logger; final Usage _usage; + final Analytics _analytics; static final RegExp _versionRegex = RegExp(r'Xcode ([0-9.]+).*Build version (\w+)'); void _updateVersion() { @@ -235,6 +243,11 @@ class XcodeProjectInterpreter { command: showBuildSettingsCommand.join(' '), flutterUsage: _usage, ).send(); + _analytics.send(Event.flutterBuildInfo( + label: 'xcode-show-build-settings-timeout', + buildType: 'ios', + command: showBuildSettingsCommand.join(' '), + )); } _logger.printTrace('Unexpected failure to get Xcode build settings: $error.'); return const {}; @@ -290,6 +303,11 @@ class XcodeProjectInterpreter { command: showBuildSettingsCommand.join(' '), flutterUsage: _usage, ).send(); + _analytics.send(Event.flutterBuildInfo( + label: 'xcode-show-build-settings-timeout', + buildType: 'ios', + command: showBuildSettingsCommand.join(' '), + )); } _logger.printTrace('Unexpected failure to get Pod Xcode project build settings: $error.'); return null; 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 0cfba30966cb..0cd25771b0f7 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -322,6 +322,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). fileSystem: _fileSystem, flutterVersion: globals.flutterVersion, usage: globals.flutterUsage, + analytics: globals.analytics, ); await webBuilder.buildWeb( flutterProject, @@ -400,6 +401,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). fileSystem: _fileSystem, flutterVersion: globals.flutterVersion, usage: globals.flutterUsage, + analytics: globals.analytics, ); await webBuilder.buildWeb( flutterProject, diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index befd5793e7d5..7cffc7583b6e 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:meta/meta.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'package:xml/xml.dart'; import 'package:yaml/yaml.dart'; @@ -761,8 +762,19 @@ The detected reason was: '''); if (deprecationBehavior == DeprecationBehavior.ignore) { BuildEvent('deprecated-v1-android-embedding-ignored', type: 'gradle', flutterUsage: globals.flutterUsage).send(); + globals.analytics.send( + Event.flutterBuildInfo( + label: 'deprecated-v1-android-embedding-ignored', + buildType: 'gradle', + )); + } else { // DeprecationBehavior.exit - BuildEvent('deprecated-v1-android-embedding-failed', type: 'gradle', flutterUsage: globals.flutterUsage).send(); + globals.analytics.send( + Event.flutterBuildInfo( + label: 'deprecated-v1-android-embedding-failed', + buildType: 'gradle', + )); + throwToolExit( 'Build failed due to use of deprecated Android v1 embedding.', exitCode: 1, diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart index 004ac1a50a47..29be9d4efebe 100644 --- a/packages/flutter_tools/lib/src/web/compile.dart +++ b/packages/flutter_tools/lib/src/web/compile.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:process/process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../artifacts.dart'; import '../base/common.dart'; @@ -34,12 +35,14 @@ class WebBuilder { required ProcessManager processManager, required BuildSystem buildSystem, required Usage usage, + required Analytics analytics, required FlutterVersion flutterVersion, required FileSystem fileSystem, }) : _logger = logger, _processManager = processManager, _buildSystem = buildSystem, _flutterUsage = usage, + _analytics = analytics, _flutterVersion = flutterVersion, _fileSystem = fileSystem; @@ -47,6 +50,7 @@ class WebBuilder { final ProcessManager _processManager; final BuildSystem _buildSystem; final Usage _flutterUsage; + final Analytics _analytics; final FlutterVersion _flutterVersion; final FileSystem _fileSystem; @@ -127,15 +131,23 @@ class WebBuilder { } finally { status.stop(); } + + final String buildSettingsString = _buildEventAnalyticsSettings( + config: compilerConfig, + buildInfo: buildInfo, + ); + BuildEvent( 'web-compile', type: 'web', - settings: _buildEventAnalyticsSettings( - config: compilerConfig, - buildInfo: buildInfo, - ), + settings: buildSettingsString, flutterUsage: _flutterUsage, ).send(); + _analytics.send(Event.flutterBuildInfo( + label: 'web-compile', + buildType: 'web', + settings: buildSettingsString, + )); _flutterUsage.sendTiming( 'build', diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart index d9f9f68fe3de..c7cd0f27e858 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart @@ -24,10 +24,12 @@ import 'package:flutter_tools/src/ios/xcodeproj.dart'; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../general.shard/ios/xcresult_test_data.dart'; import '../../src/common.dart'; import '../../src/context.dart'; +import '../../src/fakes.dart'; import '../../src/test_build_system.dart'; import '../../src/test_flutter_command_runner.dart'; @@ -70,6 +72,7 @@ final Platform notMacosPlatform = FakePlatform( void main() { late FileSystem fileSystem; late TestUsage usage; + late FakeAnalytics fakeAnalytics; late BufferLogger logger; late FakeProcessManager processManager; late ProcessUtils processUtils; @@ -83,6 +86,10 @@ void main() { fileSystem = MemoryFileSystem.test(); artifacts = Artifacts.test(fileSystem: fileSystem); usage = TestUsage(); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); logger = BufferLogger.test(); processManager = FakeProcessManager.empty(); processUtils = ProcessUtils( @@ -587,6 +594,13 @@ void main() { parameters:CustomDimensions(), ), )); + + expect(fakeAnalytics.sentEvents, contains( + Event.flutterBuildInfo( + label: 'plist-impeller-enabled', + buildType: 'ios', + ), + )); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => FakeProcessManager.list([ @@ -607,6 +621,7 @@ void main() { ), Usage: () => usage, XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), + Analytics: () => fakeAnalytics, }); testUsingContext('Sends an analytics event when Impeller is disabled', () async { @@ -642,6 +657,13 @@ void main() { parameters:CustomDimensions(), ), )); + + expect(fakeAnalytics.sentEvents, contains( + Event.flutterBuildInfo( + label: 'plist-impeller-disabled', + buildType: 'ios', + ), + )); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => FakeProcessManager.list([ @@ -673,6 +695,7 @@ void main() { plutilCommand, plutilCommand, plutilCommand, ]), ), + Analytics: () => fakeAnalytics, }); }); diff --git a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart index 5f5076c4fb43..35771e027c1b 100644 --- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart @@ -23,6 +23,7 @@ import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../src/common.dart'; import '../../src/context.dart'; @@ -33,6 +34,7 @@ void main() { group('gradle build', () { late BufferLogger logger; late TestUsage testUsage; + late FakeAnalytics fakeAnalytics; late FileSystem fileSystem; late FakeProcessManager processManager; @@ -42,6 +44,11 @@ void main() { testUsage = TestUsage(); fileSystem = MemoryFileSystem.test(); Cache.flutterRoot = ''; + + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); }); testUsingContext('Can immediately tool exit on recognized exit code/stderr', () async { @@ -52,6 +59,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -133,6 +141,15 @@ void main() { parameters: CustomDimensions(), ), )); + expect(testUsage.events, hasLength(2)); + + expect( + fakeAnalytics.sentEvents, + unorderedEquals([ + Event.flutterBuildInfo(label: 'app-not-using-android-x', buildType: 'gradle'), + Event.flutterBuildInfo(label: 'gradle-random-event-label-failure', buildType: 'gradle'), + ]), + ); }, overrides: { AndroidStudio: () => FakeAndroidStudio(), }); @@ -145,6 +162,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -213,6 +231,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -307,6 +326,15 @@ void main() { parameters: CustomDimensions(), ), )); + expect(testUsage.events, hasLength(4)); + + expect(fakeAnalytics.sentEvents, hasLength(4)); + expect(fakeAnalytics.sentEvents, contains( + Event.flutterBuildInfo( + label: 'gradle-random-event-label-failure', + buildType: 'gradle', + ), + )); }, overrides: { AndroidStudio: () => FakeAndroidStudio(), }); @@ -319,6 +347,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -400,6 +429,16 @@ void main() { parameters: CustomDimensions(), ), )); + expect(testUsage.events, hasLength(2)); + + expect(fakeAnalytics.sentEvents, hasLength(2)); + expect(fakeAnalytics.sentEvents, contains( + Event.flutterBuildInfo( + label: 'gradle-random-event-label-failure', + buildType: 'gradle', + ), + )); + }, overrides: { AndroidStudio: () => FakeAndroidStudio(), }); @@ -412,6 +451,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -477,6 +517,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -581,6 +622,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform( environment: { @@ -683,6 +725,7 @@ void main() { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -811,6 +854,7 @@ android { fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -846,6 +890,7 @@ BuildVariant: paidProfile fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -877,6 +922,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -904,6 +950,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -970,6 +1017,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1029,6 +1077,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1089,6 +1138,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_arm', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1169,6 +1219,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_arm64', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1249,6 +1300,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_x86', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1329,6 +1381,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_x64', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1410,6 +1463,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.test(), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1471,6 +1525,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_arm', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1560,6 +1615,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_arm64', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1649,6 +1705,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_x86', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), @@ -1738,6 +1795,7 @@ Gradle Crashed fileSystem: fileSystem, artifacts: Artifacts.testLocalEngine(localEngine: 'out/android_x64', localEngineHost: 'out/host_release'), usage: testUsage, + analytics: fakeAnalytics, gradleUtils: FakeGradleUtils(), platform: FakePlatform(), androidStudio: FakeAndroidStudio(), diff --git a/packages/flutter_tools/test/general.shard/android/gradle_find_bundle_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_find_bundle_test.dart index 9c0837735118..37c25187bb3a 100644 --- a/packages/flutter_tools/test/general.shard/android/gradle_find_bundle_test.dart +++ b/packages/flutter_tools/test/general.shard/android/gradle_find_bundle_test.dart @@ -9,14 +9,21 @@ import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../src/common.dart'; +import '../../src/fakes.dart'; void main() { late FileSystem fileSystem; + late FakeAnalytics fakeAnalytics; setUp(() { fileSystem = MemoryFileSystem.test(); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: FakeFlutterVersion(), + ); }); testWithoutContext('Finds app bundle when flavor contains multiple dimensions in release mode', () { @@ -26,6 +33,7 @@ void main() { const BuildInfo(BuildMode.release, 'fooBar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -39,6 +47,7 @@ void main() { const BuildInfo(BuildMode.release, 'foo_bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -52,6 +61,7 @@ void main() { const BuildInfo(BuildMode.release, 'foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -65,6 +75,7 @@ void main() { const BuildInfo(BuildMode.release, 'foo', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -78,6 +89,7 @@ void main() { const BuildInfo(BuildMode.release, 'fooA', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -91,6 +103,7 @@ void main() { const BuildInfo(BuildMode.release, null, treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -104,6 +117,7 @@ void main() { const BuildInfo(BuildMode.debug, 'fooBar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -117,6 +131,7 @@ void main() { const BuildInfo(BuildMode.debug, 'foo_bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -130,6 +145,7 @@ void main() { const BuildInfo(BuildMode.debug, 'foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -143,6 +159,7 @@ void main() { const BuildInfo(BuildMode.debug, 'foo', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -156,6 +173,7 @@ void main() { const BuildInfo(BuildMode.debug, 'fooA', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -169,6 +187,7 @@ void main() { BuildInfo.debug, BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -182,6 +201,7 @@ void main() { const BuildInfo(BuildMode.profile, 'fooBar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -195,6 +215,7 @@ void main() { const BuildInfo(BuildMode.profile, 'foo_bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -208,6 +229,7 @@ void main() { const BuildInfo(BuildMode.profile, 'foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -221,6 +243,7 @@ void main() { const BuildInfo(BuildMode.profile, 'foo', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -234,6 +257,7 @@ void main() { const BuildInfo(BuildMode.profile, 'fooA', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -247,6 +271,7 @@ void main() { const BuildInfo(BuildMode.profile, null, treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -260,6 +285,7 @@ void main() { const BuildInfo(BuildMode.release, null, treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -273,6 +299,7 @@ void main() { const BuildInfo(BuildMode.profile, null, treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -286,6 +313,7 @@ void main() { BuildInfo.debug, BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -299,6 +327,7 @@ void main() { const BuildInfo(BuildMode.release, 'foo_bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -312,6 +341,7 @@ void main() { const BuildInfo(BuildMode.release, 'foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -325,6 +355,7 @@ void main() { const BuildInfo(BuildMode.profile, 'foo_bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -338,6 +369,7 @@ void main() { const BuildInfo(BuildMode.debug, 'foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -352,6 +384,7 @@ void main() { const BuildInfo(BuildMode.release, 'Foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -366,6 +399,7 @@ void main() { const BuildInfo(BuildMode.debug, 'Foo_Bar', treeShakeIcons: false), BufferLogger.test(), TestUsage(), + fakeAnalytics, ); expect(bundle, isNotNull); @@ -382,6 +416,7 @@ void main() { const BuildInfo(BuildMode.debug, 'foo_bar', treeShakeIcons: false), BufferLogger.test(), testUsage, + fakeAnalytics, ); }, throwsToolExit( @@ -400,6 +435,17 @@ void main() { }), ), )); + expect(fakeAnalytics.sentEvents, hasLength(1)); + expect( + fakeAnalytics.sentEvents, + contains( + Event.flutterBuildInfo( + label: 'gradle-expected-file-not-found', + buildType: 'gradle', + settings: 'androidGradlePluginVersion: 7.5, fileExtension: .aab', + ), + ), + ); }); } diff --git a/packages/flutter_tools/test/general.shard/ios/mac_test.dart b/packages/flutter_tools/test/general.shard/ios/mac_test.dart index 303d261273ee..2ec7879caf1e 100644 --- a/packages/flutter_tools/test/general.shard/ios/mac_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/mac_test.dart @@ -17,6 +17,7 @@ import 'package:flutter_tools/src/ios/xcresult.dart'; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../src/common.dart'; import '../../src/fake_process_manager.dart'; @@ -133,12 +134,19 @@ void main() { group('Diagnose Xcode build failure', () { late Map buildSettings; late TestUsage testUsage; + late FakeAnalytics fakeAnalytics; setUp(() { buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'test.app', }; testUsage = TestUsage(); + + final MemoryFileSystem fs = MemoryFileSystem.test(); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fs, + fakeFlutterVersion: FakeFlutterVersion(), + ); }); testWithoutContext('Sends analytics when bitcode fails', () async { @@ -154,7 +162,7 @@ void main() { ), ); - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); + await diagnoseXcodeBuildFailure(buildResult, testUsage, logger, fakeAnalytics); expect(testUsage.events, contains( TestUsageEvent( 'build', @@ -166,6 +174,15 @@ void main() { ), ), )); + expect( + fakeAnalytics.sentEvents, + contains(Event.flutterBuildInfo( + label: 'xcode-bitcode-failure', + buildType: 'ios', + command: '[xcrun, cc, blah]', + settings: '{PRODUCT_BUNDLE_IDENTIFIER: test.app}' + )), + ); }); testWithoutContext('fallback to stdout: No provisioning profile shows message', () async { @@ -238,7 +255,7 @@ Error launching application on iPhone.''', ), ); - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); + await diagnoseXcodeBuildFailure(buildResult, testUsage, logger, fakeAnalytics); expect( logger.errorText, contains(noProvisioningProfileInstruction), @@ -276,7 +293,7 @@ Error launching application on iPhone.''', ), ); - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); + await diagnoseXcodeBuildFailure(buildResult, testUsage, logger, fakeAnalytics); expect( logger.errorText, contains(missingPlatformInstructions('iOS 17.0')), @@ -316,7 +333,7 @@ Could not build the precompiled application for the device.''', ), ); - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); + await diagnoseXcodeBuildFailure(buildResult, testUsage, logger, fakeAnalytics); expect( logger.errorText, contains('Building a deployable iOS app requires a selected Development Team with a \nProvisioning Profile.'), @@ -359,7 +376,7 @@ Could not build the precompiled application for the device.''', ]) ); - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); + await diagnoseXcodeBuildFailure(buildResult, testUsage, logger, fakeAnalytics); expect(logger.errorText, contains('Error (Xcode): Target aot_assembly_release failed')); expect(logger.errorText, isNot(contains('Building a deployable iOS app requires a selected Development Team'))); }); diff --git a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart index 0d5a24ea3c8e..66a732180a50 100644 --- a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart @@ -14,6 +14,7 @@ import 'package:flutter_tools/src/ios/xcode_build_settings.dart'; import 'package:flutter_tools/src/ios/xcodeproj.dart'; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../src/common.dart'; import '../../src/context.dart'; @@ -72,6 +73,7 @@ void main() { platform: platform, processManager: fakeProcessManager, usage: TestUsage(), + analytics: NoOpAnalytics(), ); }); @@ -184,6 +186,7 @@ void main() { platform: platform, processManager: fakeProcessManager, usage: TestUsage(), + analytics: NoOpAnalytics(), ); fileSystem.file(xcodebuild).deleteSync(); @@ -510,6 +513,7 @@ void main() { platform: platform, processManager: fakeProcessManager, usage: TestUsage(), + analytics: NoOpAnalytics(), ); expect(await xcodeProjectInterpreter.getInfo(workingDirectory), isNotNull); @@ -536,6 +540,7 @@ void main() { platform: platform, processManager: fakeProcessManager, usage: TestUsage(), + analytics: NoOpAnalytics(), ); expect(() => xcodeProjectInterpreter.getInfo(workingDirectory), throwsToolExit(message: stderr)); @@ -562,6 +567,7 @@ void main() { platform: platform, processManager: fakeProcessManager, usage: TestUsage(), + analytics: NoOpAnalytics(), ); expect(() => xcodeProjectInterpreter.getInfo(workingDirectory), throwsToolExit(message: stderr)); diff --git a/packages/flutter_tools/test/general.shard/web/compile_web_test.dart b/packages/flutter_tools/test/general.shard/web/compile_web_test.dart index 381c516533c4..a11a68fdb5bc 100644 --- a/packages/flutter_tools/test/general.shard/web/compile_web_test.dart +++ b/packages/flutter_tools/test/general.shard/web/compile_web_test.dart @@ -9,9 +9,9 @@ import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/targets/web.dart'; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; -import 'package:flutter_tools/src/version.dart'; import 'package:flutter_tools/src/web/compile.dart'; import 'package:flutter_tools/src/web/file_generators/flutter_service_worker_js.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../../src/common.dart'; import '../../src/context.dart'; @@ -21,8 +21,9 @@ import '../../src/test_build_system.dart'; void main() { late MemoryFileSystem fileSystem; late TestUsage testUsage; + late FakeAnalytics fakeAnalytics; late BufferLogger logger; - late FlutterVersion flutterVersion; + late FakeFlutterVersion flutterVersion; late FlutterProject flutterProject; setUp(() { @@ -30,6 +31,10 @@ void main() { testUsage = TestUsage(); logger = BufferLogger.test(); flutterVersion = FakeFlutterVersion(frameworkVersion: '1.0.0', engineRevision: '9.8.7'); + fakeAnalytics = getInitializedFakeAnalyticsInstance( + fs: fileSystem, + fakeFlutterVersion: flutterVersion, + ); flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); fileSystem.file('.packages').createSync(); @@ -65,6 +70,7 @@ void main() { usage: testUsage, flutterVersion: flutterVersion, fileSystem: fileSystem, + analytics: fakeAnalytics, ); await webBuilder.buildWeb( flutterProject, @@ -103,6 +109,17 @@ void main() { ), ); + expect( + fakeAnalytics.sentEvents, + unorderedEquals([ + Event.flutterBuildInfo( + label: 'web-compile', + buildType: 'web', + settings: 'RunWasmOpt: none; WasmOmitTypeChecks: false; wasm-compile: true; web-renderer: auto;', + ), + ]), + ); + // Sends timing event. final TestTimingEvent timingEvent = testUsage.timings.single; expect(timingEvent.category, 'build'); @@ -128,6 +145,7 @@ void main() { usage: testUsage, flutterVersion: flutterVersion, fileSystem: fileSystem, + analytics: fakeAnalytics, ); await expectLater( () async => webBuilder.buildWeb(