Add wasm_dry_run_package event to track public package names from wasm dry run findings. (#2279)

Co-authored-by: Nate Biggs <natebiggs@google.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
diff --git a/pkgs/unified_analytics/CHANGELOG.md b/pkgs/unified_analytics/CHANGELOG.md
index a540234..43f679c 100644
--- a/pkgs/unified_analytics/CHANGELOG.md
+++ b/pkgs/unified_analytics/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 8.0.10
+- Added `Event.flutterWasmDryRunPackage` to track dart2wasm dry run metrics from Flutter
+  including public package information.
+
 ## 8.0.9
 - Added `libraryDiagnosticsBundleFailures` to `Event.analysisStatistics`.
 
@@ -6,9 +10,9 @@
 
 ## 8.0.7
 - Added optional fields `contextWorkspaceType` and `numberOfPackagesInWorkspace`
-  to `Event.contextStructure` for workspace and packages distribution from the 
+  to `Event.contextStructure` for workspace and packages distribution from the
   Dart Analysis Server.
-- Removed `Event.contextStructure` optional fields `contextsFromBothFiles`, 
+- Removed `Event.contextStructure` optional fields `contextsFromBothFiles`,
   `contextsFromOptionsFiles`,`contextsFromPackagesFiles`,`contextsWithoutFiles`.
 
 ## 8.0.6
diff --git a/pkgs/unified_analytics/lib/src/constants.dart b/pkgs/unified_analytics/lib/src/constants.dart
index 17d857e..aec77b9 100644
--- a/pkgs/unified_analytics/lib/src/constants.dart
+++ b/pkgs/unified_analytics/lib/src/constants.dart
@@ -87,7 +87,7 @@
 const String kLogFileName = 'dart-flutter-telemetry.log';
 
 /// The current version of the package, should be in line with pubspec version.
-const String kPackageVersion = '8.0.9';
+const String kPackageVersion = '8.0.10';
 
 /// The minimum length for a session.
 const int kSessionDurationMinutes = 30;
diff --git a/pkgs/unified_analytics/lib/src/enums.dart b/pkgs/unified_analytics/lib/src/enums.dart
index b3fb969..5ee215a 100644
--- a/pkgs/unified_analytics/lib/src/enums.dart
+++ b/pkgs/unified_analytics/lib/src/enums.dart
@@ -108,6 +108,13 @@
     description: 'Information for a dart2wasm dry run invoked from Flutter',
     toolOwner: DashTool.flutterTool,
   ),
+  flutterWasmDryRunPackage(
+    label: 'wasm_dry_run_package',
+    description:
+        'Information for a dart2wasm dry run invoked from Flutter with package '
+        'info',
+    toolOwner: DashTool.flutterTool,
+  ),
   flutterInjectDarwinPlugins(
     label: 'flutter_inject_darwin_plugins',
     description: 'Information on plugins injected into an iOS/macOS project',
diff --git a/pkgs/unified_analytics/lib/src/event.dart b/pkgs/unified_analytics/lib/src/event.dart
index 9f8c273..3694722 100644
--- a/pkgs/unified_analytics/lib/src/event.dart
+++ b/pkgs/unified_analytics/lib/src/event.dart
@@ -673,6 +673,29 @@
           },
         );
 
+  /// Provides information about the results of a wasm dry run including public
+  /// package names and versions.
+  ///
+  /// [result] - dry run result summary
+  ///
+  /// [exitCode] - the exit code of the dry run.
+  ///
+  /// [findingsInfo] - findings for the dry run, keyed by finding index.
+  ///   The value is a comma-separated string containing flags and package
+  ///   information in `name:version` format, e.g., `'-ph,pkg1:1.2.3'`.
+  Event.flutterWasmDryRunPackage({
+    required String result,
+    required int exitCode,
+    required Map<String, String> findingsInfo,
+  }) : this._(
+          eventName: DashEvent.flutterWasmDryRunPackage,
+          eventData: {
+            'result': result,
+            'exitCode': exitCode,
+            ...findingsInfo,
+          },
+        );
+
   /// Provides information about the plugins injected into an iOS or macOS
   /// project.
   ///
diff --git a/pkgs/unified_analytics/pubspec.yaml b/pkgs/unified_analytics/pubspec.yaml
index 40335dc..e6523e0 100644
--- a/pkgs/unified_analytics/pubspec.yaml
+++ b/pkgs/unified_analytics/pubspec.yaml
@@ -5,7 +5,7 @@
 # LINT.IfChange
 # When updating this, keep the version consistent with the changelog and the
 # value in lib/src/constants.dart.
-version: 8.0.9
+version: 8.0.10
 # LINT.ThenChange(lib/src/constants.dart)
 repository: https://github.com/dart-lang/tools/tree/main/pkgs/unified_analytics
 issue_tracker: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics
diff --git a/pkgs/unified_analytics/test/event_test.dart b/pkgs/unified_analytics/test/event_test.dart
index 8de296e..6ca38e1 100644
--- a/pkgs/unified_analytics/test/event_test.dart
+++ b/pkgs/unified_analytics/test/event_test.dart
@@ -455,7 +455,7 @@
     expect(constructedEvent.eventData.length, 4);
   });
 
-  test('Event.flutterWasmDryRun constructed', () {
+  test('Event.flutterWasmDryRun constructed no findings', () {
     Event generateEventNoFindings() => Event.flutterWasmDryRun(
           result: 'success',
           exitCode: 123,
@@ -469,7 +469,7 @@
     expect(constructedEvent1.eventData['exitCode'], 123);
     expect(constructedEvent1.eventData.length, 2);
   });
-  test('Event.flutterWasmDryRun constructed', () {
+  test('Event.flutterWasmDryRun constructed with findings', () {
     Event generateEventNoFindings() => Event.flutterWasmDryRun(
           result: 'success',
           exitCode: 123,
@@ -496,6 +496,26 @@
     expect(constructedEvent2.eventData.length, 3);
   });
 
+  test('Event.flutterWasmDryRunPackage constructed', () {
+    Event generateEvent() => Event.flutterWasmDryRunPackage(
+            result: 'success',
+            exitCode: 123,
+            findingsInfo: {
+              '0': '-ph,pkg1:1.2.3,pkg2:5.4.3',
+              '1': '-p,pkg3:9.2.44,pkg4:6.4.3',
+            });
+
+    final constructedEvent1 = generateEvent();
+
+    expect(generateEvent, returnsNormally);
+    expect(constructedEvent1.eventName, DashEvent.flutterWasmDryRunPackage);
+    expect(constructedEvent1.eventData['result'], 'success');
+    expect(constructedEvent1.eventData['exitCode'], 123);
+    expect(constructedEvent1.eventData['0'], '-ph,pkg1:1.2.3,pkg2:5.4.3');
+    expect(constructedEvent1.eventData['1'], '-p,pkg3:9.2.44,pkg4:6.4.3');
+    expect(constructedEvent1.eventData.length, 4);
+  });
+
   test('Event.flutterInjectDarwinPlugins constructed', () {
     Event generateEvent() => Event.flutterInjectDarwinPlugins(
           platform: 'ios',
@@ -784,7 +804,7 @@
 
     // Change this integer below if your PR either adds or removes
     // an Event constructor
-    final eventsAccountedForInTests = 31;
+    final eventsAccountedForInTests = 32;
     expect(eventsAccountedForInTests, constructorCount,
         reason: 'If you added or removed an event constructor, '
             'ensure you have updated '