[Inspector V2] Fix inspector analytics  (#8684)

diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart
index f9d1f86..abbc177 100644
--- a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart
+++ b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart
@@ -23,6 +23,9 @@
 import 'package:vm_service/vm_service.dart';
 
 import '../../service/service_extensions.dart' as extensions;
+import '../../shared/analytics/analytics.dart' as ga;
+import '../../shared/analytics/constants.dart' as gac;
+import '../../shared/analytics/metrics.dart';
 import '../../shared/console/eval/inspector_tree.dart';
 import '../../shared/console/primitives/simple_items.dart';
 import '../../shared/diagnostics/diagnostics_node.dart';
@@ -666,6 +669,13 @@
       subtreeRoot = newSelection;
 
       applyNewSelection(newSelection, detailsSelection, true);
+
+      // Send an event that a widget was selected on the device.
+      ga.select(
+        gac.inspector,
+        gac.onDeviceSelection,
+        screenMetricsProvider: () => InspectorScreenMetrics.legacy(),
+      );
     } catch (error, st) {
       if (selectionGroups.next == group) {
         _log.shout(error, error, st);
diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart
index bbf47db..c737f4e 100644
--- a/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart
+++ b/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart
@@ -13,6 +13,7 @@
 import '../../service/service_extensions.dart' as extensions;
 import '../../shared/analytics/analytics.dart' as ga;
 import '../../shared/analytics/constants.dart' as gac;
+import '../../shared/analytics/metrics.dart';
 import '../../shared/console/eval/inspector_tree.dart';
 import '../../shared/globals.dart';
 import '../../shared/managers/error_badge_manager.dart';
@@ -265,7 +266,11 @@
   }
 
   void _refreshInspector() {
-    ga.select(gac.inspector, gac.refresh);
+    ga.select(
+      gac.inspector,
+      gac.refresh,
+      screenMetricsProvider: () => InspectorScreenMetrics.legacy(),
+    );
     unawaited(
       blockWhileInProgress(() async {
         // If the user is force refreshing the inspector before the first load has
@@ -275,7 +280,11 @@
           // We do not want to complete this timing operation because the force
           // refresh will skew the results.
           ga.cancelTimingOperation(InspectorScreen.id, gac.pageReady);
-          ga.select(gac.inspector, gac.refreshEmptyTree);
+          ga.select(
+            gac.inspector,
+            gac.refreshEmptyTree,
+            screenMetricsProvider: () => InspectorScreenMetrics.legacy(),
+          );
           controller.firstInspectorTreeLoadCompleted = true;
         }
         await controller.onForceRefresh();
diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart
index 0448d09..dcaaebe 100644
--- a/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart
+++ b/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart
@@ -447,7 +447,11 @@
 
   void onSelectNode(InspectorTreeNode? node) {
     selection = node;
-    ga.select(gac.inspector, gac.treeNodeSelection);
+    ga.select(
+      gac.inspector,
+      gac.treeNodeSelection,
+      screenMetricsProvider: () => InspectorScreenMetrics.legacy(),
+    );
     expandPath(node);
   }
 
@@ -1002,7 +1006,14 @@
     if (!controller.firstInspectorTreeLoadCompleted && widget.isSummaryTree) {
       final screenId = widget.screenId;
       if (screenId != null) {
-        ga.timeEnd(screenId, gac.pageReady);
+        ga.timeEnd(
+          screenId,
+          gac.pageReady,
+          screenMetricsProvider:
+              () => InspectorScreenMetrics.legacy(
+                rowCount: treeControllerLocal.numRows,
+              ),
+        );
         unawaited(
           serviceConnection.sendDwdsEvent(
             screen: screenId,
diff --git a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart
index 11d8f50..3c793b3 100644
--- a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart
+++ b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart
@@ -75,7 +75,7 @@
                       description:
                           'Disable the redesigned Flutter inspector. Please know that '
                           'the legacy inspector may be removed in a future release.',
-                      gaItem: gac.inspectorV2Enabled,
+                      gaItem: gac.inspectorV2Disabled,
                     ),
                   ),
                 const SizedBox(height: largeSpacing),
diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart
index 61b9c12..0e7255b 100644
--- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart
+++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart
@@ -25,6 +25,7 @@
 import '../../service/service_extensions.dart' as extensions;
 import '../../shared/analytics/analytics.dart' as ga;
 import '../../shared/analytics/constants.dart' as gac;
+import '../../shared/analytics/metrics.dart';
 import '../../shared/console/eval/inspector_tree_v2.dart';
 import '../../shared/console/primitives/simple_items.dart';
 import '../../shared/diagnostics/diagnostics_node.dart';
@@ -392,7 +393,11 @@
       // We do not want to complete this timing operation because the force
       // refresh will skew the results.
       ga.cancelTimingOperation(InspectorScreen.id, gac.pageReady);
-      ga.select(gac.inspector, gac.refreshEmptyTree);
+      ga.select(
+        gac.inspector,
+        gac.refreshEmptyTree,
+        screenMetricsProvider: () => InspectorScreenMetrics.v2(),
+      );
       firstInspectorTreeLoadCompleted = true;
     }
     await onForceRefresh();
@@ -766,6 +771,13 @@
         selectedNode: newSelection,
         group: group,
       );
+
+      // Send an event that a widget was selected on the device.
+      ga.select(
+        gac.inspector,
+        gac.onDeviceSelection,
+        screenMetricsProvider: () => InspectorScreenMetrics.v2(),
+      );
     } catch (error, st) {
       if (selectionGroups.next == group) {
         _log.shout(error, error, st);
diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart
index 7d918ff..233fe58 100644
--- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart
+++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart
@@ -11,6 +11,7 @@
 
 import '../../shared/analytics/analytics.dart' as ga;
 import '../../shared/analytics/constants.dart' as gac;
+import '../../shared/analytics/metrics.dart';
 import '../../shared/console/eval/inspector_tree_v2.dart';
 import '../../shared/globals.dart';
 import '../../shared/managers/banner_messages.dart';
@@ -219,7 +220,11 @@
   }
 
   void _refreshInspector() {
-    ga.select(gac.inspector, gac.refresh);
+    ga.select(
+      gac.inspector,
+      gac.refresh,
+      screenMetricsProvider: () => InspectorScreenMetrics.v2(),
+    );
     unawaited(
       blockWhileInProgress(() async {
         await controller.refreshInspector();
diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart
index 5678474..d189132 100644
--- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart
+++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart
@@ -553,7 +553,11 @@
 
   void onSelectNode(InspectorTreeNode? node) {
     setSelectedNode(node, notifyFlutterInspector: true);
-    ga.select(gac.inspector, gac.treeNodeSelection);
+    ga.select(
+      gac.inspector,
+      gac.treeNodeSelection,
+      screenMetricsProvider: () => InspectorScreenMetrics.v2(),
+    );
     final diagnostic = node?.diagnostic;
     if (diagnostic != null && diagnostic.groupIsHidden) {
       diagnostic.hideableGroupLeader?.toggleHiddenGroup();
@@ -1136,7 +1140,12 @@
         if (!controller.firstInspectorTreeLoadCompleted) {
           final screenId = widget.screenId;
           if (screenId != null) {
-            ga.timeEnd(screenId, gac.pageReady);
+            ga.timeEnd(
+              screenId,
+              gac.pageReady,
+              screenMetricsProvider:
+                  () => InspectorScreenMetrics.v2(rowCount: rows.length),
+            );
             unawaited(
               serviceConnection.sendDwdsEvent(
                 screen: screenId,
diff --git a/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart b/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart
index 178e081..2154cba 100644
--- a/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart
+++ b/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart
@@ -67,6 +67,8 @@
 
     // NOTE: Do not reorder any of these. Order here must match the order in the
     // Google Analytics console.
+    // IMPORTANT! Only string and int values are supported. All other value
+    // types will be ignored in GA4.
     String? user_app, // dimension1 (flutter or web)
     String? user_build, // dimension2 (debug or profile)
     String? user_platform, // dimension3 (android/ios/fuchsia/linux/mac/windows)
@@ -112,7 +114,7 @@
     String? android_app_id, //metric13
     String? ios_bundle_id, //metric14
     // Inspector screen metrics. See [InspectorScreenMetrics].
-    bool? is_v2_inspector, // metric15
+    String? is_v2_inspector, // metric15
   });
 
   factory GtagEventDevTools._create({
@@ -207,7 +209,9 @@
               : null,
       // [InspectorScreenMetrics]
       is_v2_inspector:
-          screenMetrics is InspectorScreenMetrics ? screenMetrics.isV2 : null,
+          screenMetrics is InspectorScreenMetrics
+              ? screenMetrics.isV2.toString()
+              : null,
     );
   }
 
@@ -243,7 +247,7 @@
   external int? get inspector_tree_controller_id;
   external String? get android_app_id;
   external String? get ios_bundle_id;
-  external bool? get is_v2_inspector;
+  external String? get is_v2_inspector;
 }
 
 extension type GtagExceptionDevTools._(JSObject _) implements GtagException {
@@ -254,6 +258,8 @@
 
     // NOTE: Do not reorder any of these. Order here must match the order in the
     // Google Analytics console.
+    // IMPORTANT! Only string and int values are supported. All other value
+    // types will be ignored in GA4.
     String? user_app, // dimension1 (flutter or web)
     String? user_build, // dimension2 (debug or profile)
     String? user_platform, // dimension3 (android or ios)
@@ -298,7 +304,7 @@
     String? android_app_id, //metric13
     String? ios_bundle_id, //metric14
     // Inspector screen metrics. See [InspectorScreenMetrics].
-    bool? is_v2_inspector, // metric15
+    String? is_v2_inspector, // metric15
   });
 
   factory GtagExceptionDevTools._create(
@@ -385,7 +391,9 @@
               : null,
       // [InspectorScreenMetrics]
       is_v2_inspector:
-          screenMetrics is InspectorScreenMetrics ? screenMetrics.isV2 : null,
+          screenMetrics is InspectorScreenMetrics
+              ? screenMetrics.isV2.toString()
+              : null,
     );
   }
 
@@ -1026,7 +1034,7 @@
   final int? rootSetCount;
   final int? rowCount;
   final int? inspectorTreeControllerId;
-  final bool? isV2Inspector;
+  final String? isV2Inspector;
 
   // [DeepLinkScreenMetrics]
   final String? androidAppId;
diff --git a/packages/devtools_app/lib/src/shared/analytics/constants.dart b/packages/devtools_app/lib/src/shared/analytics/constants.dart
index 83679f5..a3a714f 100644
--- a/packages/devtools_app/lib/src/shared/analytics/constants.dart
+++ b/packages/devtools_app/lib/src/shared/analytics/constants.dart
@@ -84,6 +84,7 @@
 const enableOnDeviceInspector = 'enableOnDeviceInspector';
 const showOnDeviceInspector = 'showInspector';
 const treeNodeSelection = 'treeNodeSelection';
+const onDeviceSelection = 'onDeviceSelection';
 const inspectorSettings = 'inspectorSettings';
 const loggingSettings = 'loggingSettings';
 const refreshPubRoots = 'refreshPubRoots';
@@ -119,6 +120,7 @@
 const verboseLogging = 'verboseLogging';
 const inspectorHoverEvalMode = 'inspectorHoverEvalMode';
 const inspectorV2Enabled = 'inspectorV2Enabled';
+const inspectorV2Disabled = 'inspectorV2Disabled';
 const inspectorAutoRefreshEnabled = 'inspectorAutoRefreshEnabled';
 const inspectorV2Docs = 'inspectorV2Docs';
 const clearLogs = 'clearLogs';
diff --git a/packages/devtools_app/lib/src/shared/analytics/metrics.dart b/packages/devtools_app/lib/src/shared/analytics/metrics.dart
index dc4ef4e..a3e1b9d 100644
--- a/packages/devtools_app/lib/src/shared/analytics/metrics.dart
+++ b/packages/devtools_app/lib/src/shared/analytics/metrics.dart
@@ -64,15 +64,15 @@
 
 class InspectorScreenMetrics extends ScreenAnalyticsMetrics {
   InspectorScreenMetrics.legacy({
-    required this.rootSetCount,
-    required this.rowCount,
-    required this.inspectorTreeControllerId,
+    this.rootSetCount,
+    this.rowCount,
+    this.inspectorTreeControllerId,
   }) : isV2 = false;
 
   InspectorScreenMetrics.v2({
-    required this.rootSetCount,
-    required this.rowCount,
-    required this.inspectorTreeControllerId,
+    this.rootSetCount,
+    this.rowCount,
+    this.inspectorTreeControllerId,
   }) : isV2 = true;
 
   static const summaryTreeGaId = 0;