From b1f37d3ed715e23788688bdd08f681192c0c7c65 Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 19 May 2026 10:18:09 -0700 Subject: [PATCH 1/5] [analytics] propagate ENV to deeplink sub-tool calls --- .../analytics/analytics_controller.dart | 9 +++ .../lib/src/shared/server/server.dart | 16 ++++- packages/devtools_app/pubspec.yaml | 2 +- .../lib/src/deeplink/deeplink_manager.dart | 69 ++++++++++++++++++- .../lib/src/server/handlers/_deeplink.dart | 22 +++++- packages/devtools_shared/pubspec.yaml | 1 + .../test/deeplink/deeplink_manager_test.dart | 49 ++++++++++++- packages/devtools_shared/test/fakes.dart | 24 ++++--- pubspec.lock | 28 ++++---- 9 files changed, 190 insertions(+), 30 deletions(-) diff --git a/packages/devtools_app/lib/src/shared/analytics/analytics_controller.dart b/packages/devtools_app/lib/src/shared/analytics/analytics_controller.dart index da0a4c615bf..52bb5710d0a 100644 --- a/packages/devtools_app/lib/src/shared/analytics/analytics_controller.dart +++ b/packages/devtools_app/lib/src/shared/analytics/analytics_controller.dart @@ -34,6 +34,15 @@ Future get analyticsController async { AnalyticsController? _analyticsController; +/// A synchronous check to see if analytics are enabled. +/// +/// Returns `false` if analytics are disabled or not yet initialized. +bool get isAnalyticsEnabled => + _analyticsController?.analyticsEnabled.value ?? false; + +/// Whether the analytics controller has been initialized. +bool get isAnalyticsControllerInitialized => _analyticsController != null; + typedef AsyncAnalyticsCallback = FutureOr Function(); class AnalyticsController { diff --git a/packages/devtools_app/lib/src/shared/server/server.dart b/packages/devtools_app/lib/src/shared/server/server.dart index 24a86c4f0cc..794ad45fc14 100644 --- a/packages/devtools_app/lib/src/shared/server/server.dart +++ b/packages/devtools_app/lib/src/shared/server/server.dart @@ -13,8 +13,10 @@ import 'package:http/http.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as path; +import '../analytics/analytics_controller.dart'; import '../development_helpers.dart'; import '../globals.dart'; +import '../primitives/query_parameters.dart'; import '../primitives/storage.dart'; import '../primitives/utils.dart'; @@ -73,7 +75,19 @@ Uri buildDevToolsServerRequestUri(String url) { // [_debugDevToolsServerFlag] environment variable declaration was not set // using `--dart-define`. const baseUri = _debugDevToolsServerEnvironmentVariable; - return Uri.parse(path.join(baseUri, url)); + final uri = Uri.parse(path.join(baseUri, url)); + + final queryParams = DevToolsQueryParams.load(); + // Forward the parent IDE name and the client-side analytics opt-out status + // to the server, so they can be propagated to any spawned subprocesses. + final newParams = { + ...uri.queryParameters, + if (queryParams.ide != null) 'ide': queryParams.ide!, + if (isAnalyticsControllerInitialized && !isAnalyticsEnabled) + 'suppress_analytics': 'true', + }; + + return uri.replace(queryParameters: newParams); } /// Helper to catch any server request which could fail. diff --git a/packages/devtools_app/pubspec.yaml b/packages/devtools_app/pubspec.yaml index a0985fab17c..c22911a8814 100644 --- a/packages/devtools_app/pubspec.yaml +++ b/packages/devtools_app/pubspec.yaml @@ -52,7 +52,7 @@ dependencies: sse: ^4.1.2 stack_trace: ^1.12.0 string_scanner: ^1.4.0 - unified_analytics: ^7.0.0 + unified_analytics: ^8.0.13 vm_service: ^15.0.2 vm_service_protos: ^2.0.0 vm_snapshot_analysis: ^0.7.6 diff --git a/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart b/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart index 2f10d997857..919f1233acd 100644 --- a/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart +++ b/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart @@ -7,6 +7,7 @@ import 'dart:io'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as path; +import 'package:unified_analytics/unified_analytics.dart'; class DeeplinkManager { /// A regex to retrieve the json part from the stdout of Android analyzer. @@ -32,6 +33,23 @@ class DeeplinkManager { /// APIs. static const kOutputJsonField = 'json'; + /// Mappings from case-insensitive IDE query parameter values to their + /// corresponding [DashTool] enum values used by `package:unified_analytics`. + /// + /// Contains multiple spelling and format variations (with/without hyphens + /// or suffixes) passed by different IDE integrations to ensure O(1) lookup. + static const _ideToDashToolMap = { + 'vs-code': DashTool.vscodePlugins, + 'vscode': DashTool.vscodePlugins, + 'vscodeplugins': DashTool.vscodePlugins, + 'intellij-idea': DashTool.intellijPlugins, + 'intellij': DashTool.intellijPlugins, + 'intellijplugins': DashTool.intellijPlugins, + 'android-studio': DashTool.androidStudioPlugins, + 'androidstudio': DashTool.androidStudioPlugins, + 'androidstudioplugins': DashTool.androidStudioPlugins, + }; + /// A regex to retrieve the file path from the stdout of iOS or Android /// analyzers. /// @@ -44,13 +62,39 @@ class DeeplinkManager { Future runProcess( String executable, { required List arguments, + String? ide, + bool suppressAnalytics = false, }) { + final environment = { + ...getEnvironment( + currentTool: ide != null ? _mapIdeToDashTool(ide) : DashTool.devtools, + suppressAnalytics: suppressAnalytics, + ), + if (ide != null) DashEnvVar.tool.name: ide, + }; + return Process.run( executable, arguments, + environment: environment, ); } + DashTool _mapIdeToDashTool(String ide) { + final lowerIde = ide.toLowerCase(); + final mappedTool = _ideToDashToolMap[lowerIde]; + if (mappedTool != null) { + return mappedTool; + } + + for (final value in DashTool.values) { + if (value.name.toLowerCase() == lowerIde) { + return value; + } + } + return DashTool.devtools; + } + @visibleForTesting String getFlutterBinary() { // FLUTTER_ROOT can be set by Dart-Code VSCode extension or dart shell @@ -81,9 +125,16 @@ class DeeplinkManager { Future _runFlutterCommand( List arguments, { required RegExp outputMatcher, + String? ide, + bool suppressAnalytics = false, }) async { final flutterPath = getFlutterBinary(); - final result = await runProcess(flutterPath, arguments: arguments); + final result = await runProcess( + flutterPath, + arguments: arguments, + ide: ide, + suppressAnalytics: suppressAnalytics, + ); if (result.exitCode != 0) { throw _FlutterProcessError( 'Flutter command exit with non-zero error code ${result.exitCode}\n${result.stderr}', @@ -126,10 +177,14 @@ class DeeplinkManager { Future> getAndroidBuildVariants({ required String rootPath, + String? ide, + bool suppressAnalytics = false, }) { return _runFlutterCommand( ['analyze', '--android', '--list-build-variants', rootPath], outputMatcher: _androidBuildVariantJsonRegex, + ide: ide, + suppressAnalytics: suppressAnalytics, ).then>( _handleJsonOutput, onError: _handleRunFlutterError, @@ -139,6 +194,8 @@ class DeeplinkManager { Future> getAndroidAppLinkSettings({ required String rootPath, required String buildVariant, + String? ide, + bool suppressAnalytics = false, }) { return _runFlutterCommand( [ @@ -149,6 +206,8 @@ class DeeplinkManager { rootPath, ], outputMatcher: _outputFilePathRegex, + ide: ide, + suppressAnalytics: suppressAnalytics, ).then>( _handleReadJsonFile, onError: _handleRunFlutterError, @@ -157,10 +216,14 @@ class DeeplinkManager { Future> getIosBuildOptions({ required String rootPath, + String? ide, + bool suppressAnalytics = false, }) { return _runFlutterCommand( ['analyze', '--ios', '--list-build-options', rootPath], outputMatcher: _iosBuildOptionsJsonRegex, + ide: ide, + suppressAnalytics: suppressAnalytics, ).then>( _handleJsonOutput, onError: _handleRunFlutterError, @@ -171,6 +234,8 @@ class DeeplinkManager { required String rootPath, required String configuration, required String target, + String? ide, + bool suppressAnalytics = false, }) { return _runFlutterCommand( [ @@ -182,6 +247,8 @@ class DeeplinkManager { rootPath, ], outputMatcher: _outputFilePathRegex, + ide: ide, + suppressAnalytics: suppressAnalytics, ).then>( _handleReadJsonFile, onError: _handleRunFlutterError, diff --git a/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart b/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart index b5c86417bfe..42d05ecc9e4 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart @@ -20,8 +20,11 @@ extension _DeeplinkApiHandler on Never { if (missingRequiredParams != null) return missingRequiredParams; final rootPath = queryParams[DeeplinkApi.deeplinkRootPathPropertyName]!; - final result = - await deeplinkManager.getAndroidBuildVariants(rootPath: rootPath); + final result = await deeplinkManager.getAndroidBuildVariants( + rootPath: rootPath, + ide: queryParams.ide, + suppressAnalytics: queryParams.suppressAnalytics, + ); return _resultOutputOrError(api, result); } @@ -47,6 +50,8 @@ extension _DeeplinkApiHandler on Never { final result = await deeplinkManager.getAndroidAppLinkSettings( rootPath: rootPath, buildVariant: buildVariant, + ide: queryParams.ide, + suppressAnalytics: queryParams.suppressAnalytics, ); return _resultOutputOrError(api, result); } @@ -65,7 +70,11 @@ extension _DeeplinkApiHandler on Never { if (missingRequiredParams != null) return missingRequiredParams; final rootPath = queryParams[DeeplinkApi.deeplinkRootPathPropertyName]!; - final result = await deeplinkManager.getIosBuildOptions(rootPath: rootPath); + final result = await deeplinkManager.getIosBuildOptions( + rootPath: rootPath, + ide: queryParams.ide, + suppressAnalytics: queryParams.suppressAnalytics, + ); return _resultOutputOrError(api, result); } @@ -90,6 +99,8 @@ extension _DeeplinkApiHandler on Never { rootPath: queryParams[DeeplinkApi.deeplinkRootPathPropertyName]!, configuration: queryParams[DeeplinkApi.xcodeConfigurationPropertyName]!, target: queryParams[DeeplinkApi.xcodeTargetPropertyName]!, + ide: queryParams.ide, + suppressAnalytics: queryParams.suppressAnalytics, ); return _resultOutputOrError(api, result); } @@ -107,3 +118,8 @@ extension _DeeplinkApiHandler on Never { ); } } + +extension on Map { + String? get ide => this['ide']; + bool get suppressAnalytics => this['suppress_analytics'] == 'true'; +} diff --git a/packages/devtools_shared/pubspec.yaml b/packages/devtools_shared/pubspec.yaml index dce148c2109..4eb250f8be8 100644 --- a/packages/devtools_shared/pubspec.yaml +++ b/packages/devtools_shared/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: path: ^1.8.0 shelf: ^1.1.0 sse: ^4.1.2 + unified_analytics: ^8.0.13 vm_service: ">=13.0.0 <16.0.0" web_socket_channel: '>=2.4.0 <4.0.0' webkit_inspection_protocol: ">=0.5.0 <2.0.0" diff --git a/packages/devtools_shared/test/deeplink/deeplink_manager_test.dart b/packages/devtools_shared/test/deeplink/deeplink_manager_test.dart index ce77240debb..e96d45b9500 100644 --- a/packages/devtools_shared/test/deeplink/deeplink_manager_test.dart +++ b/packages/devtools_shared/test/deeplink/deeplink_manager_test.dart @@ -60,6 +60,43 @@ Running Gradle task 'printBuildVariants'... 10.4s ); }); + test('getBuildVariants propagates parent IDE and analytics opt-out status', + () async { + const projectRoot = '/abc'; + manager.expectedCommands.add( + TestCommand( + executable: manager.mockedFlutterBinary, + arguments: [ + 'analyze', + '--android', + '--list-build-variants', + projectRoot, + ], + ide: 'VS-Code', + suppressAnalytics: true, + result: ProcessResult( + 0, + 0, + r''' +Running Gradle task 'printBuildVariants'... 10.4s +["debug"] + ''', + '', + ), + ), + ); + final response = await manager.getAndroidBuildVariants( + rootPath: projectRoot, + ide: 'VS-Code', + suppressAnalytics: true, + ); + expect(response[DeeplinkManager.kErrorField], isNull); + expect( + response[DeeplinkManager.kOutputJsonField], + '["debug"]', + ); + }); + test( 'getBuildVariants return internal server error if command failed', () async { @@ -217,15 +254,19 @@ class StubbedDeeplinkManager extends DeeplinkManager { Future runProcess( String executable, { required List arguments, + String? ide, + bool suppressAnalytics = false, }) async { if (expectedCommands.isNotEmpty) { final expectedCommand = expectedCommands.removeAt(0); - expect(expectedCommand.executable, executable); + expect(executable, expectedCommand.executable); expect( const ListEquality() - .equals(expectedCommand.arguments, arguments), + .equals(arguments, expectedCommand.arguments), isTrue, ); + expect(ide, expectedCommand.ide); + expect(suppressAnalytics, expectedCommand.suppressAnalytics); return expectedCommand.result; } throw 'Received unexpected command: $executable ${arguments.join(' ')}'; @@ -236,10 +277,14 @@ class TestCommand { const TestCommand({ required this.executable, required this.arguments, + this.ide, + this.suppressAnalytics = false, required this.result, }); final String executable; final List arguments; + final String? ide; + final bool suppressAnalytics; final ProcessResult result; @override diff --git a/packages/devtools_shared/test/fakes.dart b/packages/devtools_shared/test/fakes.dart index dd79a9c0358..7c8c7fbf853 100644 --- a/packages/devtools_shared/test/fakes.dart +++ b/packages/devtools_shared/test/fakes.dart @@ -11,23 +11,27 @@ class FakeDeeplinkManager extends DeeplinkManager { String? receivedBuildVariant; String? receivedConfiguration; String? receivedTarget; - late Map responseForGetAndroidBuildVariants; - late Map responseForGetAndroidAppLinkSettings; - late Map responseForGetIosBuildOptions; - late Map responseForGetIosUniversalLinkSettings; + late Map responseForGetAndroidBuildVariants; + late Map responseForGetAndroidAppLinkSettings; + late Map responseForGetIosBuildOptions; + late Map responseForGetIosUniversalLinkSettings; @override - Future> getAndroidBuildVariants({ + Future> getAndroidBuildVariants({ required String rootPath, + String? ide, + bool suppressAnalytics = false, }) async { receivedPath = rootPath; return responseForGetAndroidBuildVariants; } @override - Future> getAndroidAppLinkSettings({ + Future> getAndroidAppLinkSettings({ required String rootPath, required String buildVariant, + String? ide, + bool suppressAnalytics = false, }) async { receivedPath = rootPath; receivedBuildVariant = buildVariant; @@ -35,18 +39,22 @@ class FakeDeeplinkManager extends DeeplinkManager { } @override - Future> getIosBuildOptions({ + Future> getIosBuildOptions({ required String rootPath, + String? ide, + bool suppressAnalytics = false, }) async { receivedPath = rootPath; return responseForGetIosBuildOptions; } @override - Future> getIosUniversalLinkSettings({ + Future> getIosUniversalLinkSettings({ required String rootPath, required String configuration, required String target, + String? ide, + bool suppressAnalytics = false, }) async { receivedPath = rootPath; receivedConfiguration = configuration; diff --git a/pubspec.lock b/pubspec.lock index 2a6ed9a941c..1d02a449584 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -539,10 +539,10 @@ packages: dependency: transitive description: name: matcher - sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.20" + version: "0.12.19" material_color_utilities: dependency: transitive description: @@ -555,10 +555,10 @@ packages: dependency: transitive description: name: meta - sha256: df0c643f44ad098eb37988027a8e2b2b5a031fd3977f06bbfd3a76637e8df739 + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.18.2" + version: "1.18.0" mime: dependency: transitive description: @@ -863,26 +863,26 @@ packages: dependency: transitive description: name: test - sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f + sha256: "8d9ceddbab833f180fbefed08afa76d7c03513dfdba87ffcec2718b02bbcbf20" url: "https://pub.dev" source: hosted - version: "1.31.1" + version: "1.31.0" test_api: dependency: transitive description: name: test_api - sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.12" + version: "0.7.11" test_core: dependency: transitive description: name: test_core - sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 + sha256: "1991d4cfe85d5043241acac92962c3977c8d2f2add1ee73130c7b286417d1d34" url: "https://pub.dev" source: hosted - version: "0.6.18" + version: "0.6.17" typed_data: dependency: transitive description: @@ -895,10 +895,10 @@ packages: dependency: transitive description: name: unified_analytics - sha256: d581cd7007f5a60594195ee5d35337edea7d53757e4cff5a2f5168b82ec31d05 + sha256: "406724e9231f8e30119673133c1087f9b24e2a75ba7111ea071253d57bb8f3b9" url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "8.0.14" url_launcher: dependency: transitive description: @@ -967,10 +967,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "47a1b32ee755c3fcffa33db52a7258c137f97bdb2209a1075be847809fac4ccf" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.0" vm_service: dependency: transitive description: From 31e5ef23385b8bcc2c4b718b433a39d78a6eac1c Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 19 May 2026 10:25:57 -0700 Subject: [PATCH 2/5] de-dup --- .../lib/src/deeplink/deeplink_manager.dart | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart b/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart index 919f1233acd..be8e28e30d7 100644 --- a/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart +++ b/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart @@ -65,13 +65,10 @@ class DeeplinkManager { String? ide, bool suppressAnalytics = false, }) { - final environment = { - ...getEnvironment( - currentTool: ide != null ? _mapIdeToDashTool(ide) : DashTool.devtools, - suppressAnalytics: suppressAnalytics, - ), - if (ide != null) DashEnvVar.tool.name: ide, - }; + final environment = getEnvironment( + currentTool: ide != null ? _mapIdeToDashTool(ide) : DashTool.devtools, + suppressAnalytics: suppressAnalytics, + ); return Process.run( executable, From 561e474dc1cd1299d54aa890450c773b3b280942 Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 19 May 2026 11:56:00 -0700 Subject: [PATCH 3/5] fail safe --- packages/devtools_app/lib/src/shared/server/server.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/shared/server/server.dart b/packages/devtools_app/lib/src/shared/server/server.dart index 794ad45fc14..9bf135157d6 100644 --- a/packages/devtools_app/lib/src/shared/server/server.dart +++ b/packages/devtools_app/lib/src/shared/server/server.dart @@ -80,10 +80,12 @@ Uri buildDevToolsServerRequestUri(String url) { final queryParams = DevToolsQueryParams.load(); // Forward the parent IDE name and the client-side analytics opt-out status // to the server, so they can be propagated to any spawned subprocesses. + // Fail-safe: default to suppressing analytics if the controller is not yet + // initialized. final newParams = { ...uri.queryParameters, if (queryParams.ide != null) 'ide': queryParams.ide!, - if (isAnalyticsControllerInitialized && !isAnalyticsEnabled) + if (!isAnalyticsControllerInitialized || !isAnalyticsEnabled) 'suppress_analytics': 'true', }; From 9796ac9c6edd6e85bad16c8686138b36f991f567 Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 19 May 2026 12:57:36 -0700 Subject: [PATCH 4/5] step back ua dep --- packages/devtools_app/pubspec.yaml | 2 +- .../lib/src/deeplink/deeplink_manager.dart | 47 +++++++++---------- packages/devtools_shared/pubspec.yaml | 1 - pubspec.lock | 4 +- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/packages/devtools_app/pubspec.yaml b/packages/devtools_app/pubspec.yaml index c22911a8814..a0985fab17c 100644 --- a/packages/devtools_app/pubspec.yaml +++ b/packages/devtools_app/pubspec.yaml @@ -52,7 +52,7 @@ dependencies: sse: ^4.1.2 stack_trace: ^1.12.0 string_scanner: ^1.4.0 - unified_analytics: ^8.0.13 + unified_analytics: ^7.0.0 vm_service: ^15.0.2 vm_service_protos: ^2.0.0 vm_snapshot_analysis: ^0.7.6 diff --git a/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart b/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart index be8e28e30d7..b3958329ace 100644 --- a/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart +++ b/packages/devtools_shared/lib/src/deeplink/deeplink_manager.dart @@ -7,7 +7,6 @@ import 'dart:io'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as path; -import 'package:unified_analytics/unified_analytics.dart'; class DeeplinkManager { /// A regex to retrieve the json part from the stdout of Android analyzer. @@ -33,21 +32,26 @@ class DeeplinkManager { /// APIs. static const kOutputJsonField = 'json'; + // TODO(https://github.com/flutter/devtools/issues/9702): Use the `DashTool` + // and `DashEnvVar` enums and `getEnvironment()` helper directly from + // `package:unified_analytics` once the pinned Flutter candidate SDK in this + // repository is bumped to a stable Dart SDK version >= 3.10.0 (resolving the + // dev SDK version solving conflict on CI). /// Mappings from case-insensitive IDE query parameter values to their - /// corresponding [DashTool] enum values used by `package:unified_analytics`. + /// corresponding DashTool canonical label strings used by `package:unified_analytics`. /// /// Contains multiple spelling and format variations (with/without hyphens /// or suffixes) passed by different IDE integrations to ensure O(1) lookup. - static const _ideToDashToolMap = { - 'vs-code': DashTool.vscodePlugins, - 'vscode': DashTool.vscodePlugins, - 'vscodeplugins': DashTool.vscodePlugins, - 'intellij-idea': DashTool.intellijPlugins, - 'intellij': DashTool.intellijPlugins, - 'intellijplugins': DashTool.intellijPlugins, - 'android-studio': DashTool.androidStudioPlugins, - 'androidstudio': DashTool.androidStudioPlugins, - 'androidstudioplugins': DashTool.androidStudioPlugins, + static const _ideToDashToolMap = { + 'vs-code': 'vscode-plugins', + 'vscode': 'vscode-plugins', + 'vscodeplugins': 'vscode-plugins', + 'intellij-idea': 'intellij-plugins', + 'intellij': 'intellij-plugins', + 'intellijplugins': 'intellij-plugins', + 'android-studio': 'android-studio-plugins', + 'androidstudio': 'android-studio-plugins', + 'androidstudioplugins': 'android-studio-plugins', }; /// A regex to retrieve the file path from the stdout of iOS or Android @@ -65,10 +69,11 @@ class DeeplinkManager { String? ide, bool suppressAnalytics = false, }) { - final environment = getEnvironment( - currentTool: ide != null ? _mapIdeToDashTool(ide) : DashTool.devtools, - suppressAnalytics: suppressAnalytics, - ); + final environment = { + ...Platform.environment, + 'DASH__SUPPRESS_ANALYTICS': suppressAnalytics.toString(), + 'DASH__TOOL': ide != null ? _mapIdeToDashToolLabel(ide) : 'devtools', + }; return Process.run( executable, @@ -77,19 +82,13 @@ class DeeplinkManager { ); } - DashTool _mapIdeToDashTool(String ide) { + String _mapIdeToDashToolLabel(String ide) { final lowerIde = ide.toLowerCase(); final mappedTool = _ideToDashToolMap[lowerIde]; if (mappedTool != null) { return mappedTool; } - - for (final value in DashTool.values) { - if (value.name.toLowerCase() == lowerIde) { - return value; - } - } - return DashTool.devtools; + return 'devtools'; } @visibleForTesting diff --git a/packages/devtools_shared/pubspec.yaml b/packages/devtools_shared/pubspec.yaml index 4eb250f8be8..dce148c2109 100644 --- a/packages/devtools_shared/pubspec.yaml +++ b/packages/devtools_shared/pubspec.yaml @@ -22,7 +22,6 @@ dependencies: path: ^1.8.0 shelf: ^1.1.0 sse: ^4.1.2 - unified_analytics: ^8.0.13 vm_service: ">=13.0.0 <16.0.0" web_socket_channel: '>=2.4.0 <4.0.0' webkit_inspection_protocol: ">=0.5.0 <2.0.0" diff --git a/pubspec.lock b/pubspec.lock index 1d02a449584..4181db2e9b3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -895,10 +895,10 @@ packages: dependency: transitive description: name: unified_analytics - sha256: "406724e9231f8e30119673133c1087f9b24e2a75ba7111ea071253d57bb8f3b9" + sha256: d581cd7007f5a60594195ee5d35337edea7d53757e4cff5a2f5168b82ec31d05 url: "https://pub.dev" source: hosted - version: "8.0.14" + version: "7.0.2" url_launcher: dependency: transitive description: From 90cddb1fc02e1926029af7bac205ed596b1bc041 Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 19 May 2026 13:14:23 -0700 Subject: [PATCH 5/5] rollback --- pubspec.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 4181db2e9b3..2a6ed9a941c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -539,10 +539,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.20" material_color_utilities: dependency: transitive description: @@ -555,10 +555,10 @@ packages: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: df0c643f44ad098eb37988027a8e2b2b5a031fd3977f06bbfd3a76637e8df739 url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.18.2" mime: dependency: transitive description: @@ -863,26 +863,26 @@ packages: dependency: transitive description: name: test - sha256: "8d9ceddbab833f180fbefed08afa76d7c03513dfdba87ffcec2718b02bbcbf20" + sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f url: "https://pub.dev" source: hosted - version: "1.31.0" + version: "1.31.1" test_api: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.12" test_core: dependency: transitive description: name: test_core - sha256: "1991d4cfe85d5043241acac92962c3977c8d2f2add1ee73130c7b286417d1d34" + sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 url: "https://pub.dev" source: hosted - version: "0.6.17" + version: "0.6.18" typed_data: dependency: transitive description: @@ -967,10 +967,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "47a1b32ee755c3fcffa33db52a7258c137f97bdb2209a1075be847809fac4ccf" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" vm_service: dependency: transitive description: