From 8b3e42bbce19bb80838c425033d3255fa35fe42e Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Tue, 20 Oct 2026 16:30:32 +0000 Subject: [PATCH 01/10] Upgrade flutter candidate and DCM version --- .github/workflows/build.yaml | 2 +- flutter-candidate.txt | 2 +- .../inspector/layout_explorer/flex/flex.dart | 2 +- .../flutter_frames/flutter_frames_chart.dart | 2 +- .../shared/diagnostics/inspector_service.dart | 2 +- .../lib/src/shared/primitives/utils.dart | 2 +- .../devtools_app/lib/src/shared/ui/hover.dart | 2 +- .../utils/future_work_tracker_test.dart | 6 +- packages/devtools_app_shared/CHANGELOG.md | 1 + .../lib/src/service/eval_on_dart_library.dart | 8 +- .../lib/src/service/isolate_state.dart | 2 +- pubspec.lock | 212 ++++++++---------- 12 files changed, 114 insertions(+), 129 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 94763cb278e..c9d358ac377 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -75,7 +75,7 @@ jobs: wget -qO- https://dcm.dev/pgp-key.public | sudo gpg --dearmor -o /usr/share/keyrings/dcm.gpg echo 'deb [signed-by=/usr/share/keyrings/dcm.gpg arch=amd64] https://dcm.dev/debian stable main' | sudo tee /etc/apt/sources.list.d/dart_stable.list sudo apt-get update - sudo apt-get install dcm=1.38.3-1 # To avoid errors add `-1` (build number) to the version + sudo apt-get install dcm=1.40.0-1 # To avoid errors add `-1` (build number) to the version sudo chmod +x /usr/bin/dcm echo "$(dcm --version)" - name: Setup Dart SDK diff --git a/flutter-candidate.txt b/flutter-candidate.txt index 83e45d2b59f..bbe295fa680 100644 --- a/flutter-candidate.txt +++ b/flutter-candidate.txt @@ -1 +1 @@ -fab991537bf1ffb063579a0dd8a47cd4f2874618 +9cba7392c62645f790ccd8c2efda0a6658d260d7 diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart index 964f30fe5f7..897ef1809c7 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart @@ -131,7 +131,7 @@ class FlexLayoutExplorerWidgetState alignmentEnumEntries = MainAxisAlignment.values; selected = propertiesLocal.mainAxisAlignment; } else { - alignmentEnumEntries = CrossAxisAlignment.values.toList(growable: true); + alignmentEnumEntries = CrossAxisAlignment.values.toList(); if (propertiesLocal.textBaseline == null) { // TODO(albertusangga): Look for ways to visualize baseline when it is null alignmentEnumEntries.remove(CrossAxisAlignment.baseline); diff --git a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart index ce015a0808e..e38487f9405 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart @@ -588,7 +588,7 @@ class FlutterFramesChartItem extends StatelessWidget { child: Column( children: [ // Dummy child so that the InkWell does not take up the entire column. - const Expanded(child: SizedBox()), + const Spacer(), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ui, raster], diff --git a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart index 23d4d028cbc..58b5ac420e8 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart @@ -1270,7 +1270,7 @@ class InspectorObjectGroupManager { void _setNextNull() { _next = null; if (_pendingNext != null) { - _pendingNext!.complete(null); + _pendingNext!.complete(); _pendingNext = null; } } diff --git a/packages/devtools_app/lib/src/shared/primitives/utils.dart b/packages/devtools_app/lib/src/shared/primitives/utils.dart index e40cf699791..415c03dc9c7 100644 --- a/packages/devtools_app/lib/src/shared/primitives/utils.dart +++ b/packages/devtools_app/lib/src/shared/primitives/utils.dart @@ -288,7 +288,7 @@ class RateLimiter { _pendingRequest = Completer(); await callback(); } finally { - _pendingRequest!.complete(null); + _pendingRequest!.complete(); } } diff --git a/packages/devtools_app/lib/src/shared/ui/hover.dart b/packages/devtools_app/lib/src/shared/ui/hover.dart index a77536c639f..4a3a7753591 100644 --- a/packages/devtools_app/lib/src/shared/ui/hover.dart +++ b/packages/devtools_app/lib/src/shared/ui/hover.dart @@ -583,7 +583,7 @@ class _HoverCardTooltipState extends State { unawaited( hoverCardDataFuture.then( (data) => completer.complete(data), - onError: (_) => completer.complete(null), + onError: (_) => completer.complete(), ), ); return completer; diff --git a/packages/devtools_app/test/shared/utils/future_work_tracker_test.dart b/packages/devtools_app/test/shared/utils/future_work_tracker_test.dart index 7f329df94ea..f5a24ea8328 100644 --- a/packages/devtools_app/test/shared/utils/future_work_tracker_test.dart +++ b/packages/devtools_app/test/shared/utils/future_work_tracker_test.dart @@ -36,12 +36,12 @@ void main() { advanceClock(async); expect(tracker.active.value, isTrue); - completer1.complete(null); + completer1.complete(); unawaited(completer1.future); advanceClock(async); expect(tracker.active.value, isTrue); - completer2.complete(null); + completer2.complete(); unawaited(completer2.future); advanceClock(async); expect(tracker.active.value, isFalse); @@ -66,7 +66,7 @@ void main() { advanceClock(async); expect(tracker.active.value, isTrue); - completer2.complete(null); + completer2.complete(); unawaited(completer2.future); advanceClock(async); expect(tracker.active.value, isFalse); diff --git a/packages/devtools_app_shared/CHANGELOG.md b/packages/devtools_app_shared/CHANGELOG.md index 683bc2bdaf9..023e2ed62fe 100644 --- a/packages/devtools_app_shared/CHANGELOG.md +++ b/packages/devtools_app_shared/CHANGELOG.md @@ -4,6 +4,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. --> ## 0.5.2-wip +* Remove redundant argument values. * Fix a `RangeError` thrown by `SplitPane` when the number of children changes between rebuilds. * Fix garbage collection and timeout issues with the result list in `asyncEval` on both native VM and web. diff --git a/packages/devtools_app_shared/lib/src/service/eval_on_dart_library.dart b/packages/devtools_app_shared/lib/src/service/eval_on_dart_library.dart index e831211384c..ba55c03fba6 100644 --- a/packages/devtools_app_shared/lib/src/service/eval_on_dart_library.dart +++ b/packages/devtools_app_shared/lib/src/service/eval_on_dart_library.dart @@ -605,7 +605,7 @@ class EvalOnDartLibrary extends DisposableController // This is an optimization to avoid sending stale requests across the wire. void wrappedRequest() async { if (isAlive != null && isAlive.disposed || disposed) { - response.complete(null); + response.complete(); return; } try { @@ -613,11 +613,11 @@ class EvalOnDartLibrary extends DisposableController if (!disposed && value is! Sentinel) { response.complete(value); } else { - response.complete(null); + response.complete(); } } catch (e) { if (disposed || isAlive?.disposed == true) { - response.complete(null); + response.complete(); } else { response.completeError(e); } @@ -629,7 +629,7 @@ class EvalOnDartLibrary extends DisposableController wrappedRequest(); } else { if (isAlive != null && isAlive.disposed || disposed) { - response.complete(null); + response.complete(); return response.future; } diff --git a/packages/devtools_app_shared/lib/src/service/isolate_state.dart b/packages/devtools_app_shared/lib/src/service/isolate_state.dart index 4f7a1077a4f..7ef89c66498 100644 --- a/packages/devtools_app_shared/lib/src/service/isolate_state.dart +++ b/packages/devtools_app_shared/lib/src/service/isolate_state.dart @@ -47,7 +47,7 @@ class IsolateState { _isolateNow = null; _isolateLoadCompleter.safeComplete( null, - () => _isolateLoadCompleter = Completer()..complete(null), + () => _isolateLoadCompleter = Completer()..complete(), ); _isPaused.dispose(); } diff --git a/pubspec.lock b/pubspec.lock index e12fee18dd7..f0e999e926d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "1b0e6a07425a3e460666e88bf1c949ccc7bb0116ad562ce94a1eca60fe820725" + sha256: "48e48f73a431eb269eec66d243a63a07ed90ef9417a74047a3b98d52338626ad" url: "https://pub.dev" source: hosted - version: "103.0.0" + version: "109.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "61c04d0c1bfed555c681ea079519933f071a5a026578ff73c4ff0df2d3462e5e" + sha256: "6d377901d198536b648172974d9d4f277910502cad92193466869cac0ff34990" url: "https://pub.dev" source: hosted - version: "13.3.0" + version: "14.5.0" archive: dependency: transitive description: name: archive - sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff + sha256: "0d58d1fa1fddf6588251ccf2819f3fb3b6d0452c1b2813ac7413a05592bfbefe" url: "https://pub.dev" source: hosted - version: "4.0.9" + version: "4.5.2" args: dependency: transitive description: @@ -61,50 +61,50 @@ packages: dependency: transitive description: name: build - sha256: "45d14a0fb23e018d8287c32fc98d726ce466b231928ed9b9200f29bd3ccd39ae" + sha256: "8a5c5761af8e31748bba3c82f68925ace40f3225c3eea25be9beb57eca7cd7a8" url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "4.0.11" build_config: dependency: transitive description: name: build_config - sha256: "94eaf6708fe64408c632ef2689ca3777b112f9421306ccf4f8c84d7c5c9f83f8" + sha256: d466ed2dc9c6cd1d169948879b84ee061eb5e22c64a7c6089879c6296d272a8d url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" build_daemon: dependency: transitive description: name: build_daemon - sha256: "8c0535c3b2f625619f4dd1036ef1127f2e77bfedf89ed2eb2676ef076e0b6712" + sha256: "39ab65f7c60c19af64b9ef96e6a5d3ab48355f7dddfd98a9079d55a8cb6628fc" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.7" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "5367e521935b102bdf1e735d2aab461e36b2edca6517662d088dd04cc39f8d16" + sha256: "6feadd32d90a68253c1f7b4fcff76adb4b41ad32a53f8bad835dc65f01ac9dc5" url: "https://pub.dev" source: hosted - version: "2.15.1" + version: "2.16.2" built_collection: dependency: transitive description: name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + sha256: "44922ecebd8e3d0cef743dadd3b54df4e87e2a4c52a29465a1872aa9e192caa8" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.1.2" built_value: dependency: transitive description: name: built_value - sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" + sha256: f87ea98192116f7093cb214551ce1929caae0681fdba282b3d8b4462adee7bb7 url: "https://pub.dev" source: hosted - version: "8.12.6" + version: "8.13.0" characters: dependency: transitive description: @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: code_builder - sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d" + sha256: "811709c1badd02fc054039a13f66e0db1961865f9a314175f68c3eaeebec786f" url: "https://pub.dev" source: hosted - version: "4.11.1" + version: "4.13.0" collection: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "92c9c43c383bfa1c32079d3bc492d55d6d4318044b7b47edaff8971cbb555c51" + sha256: f141ea4f277af142a0356955707f6556f37b03947d39d55585981a06ca437bd6 url: "https://pub.dev" source: hosted - version: "0.3.5+4" + version: "0.3.5+5" crypto: dependency: transitive description: @@ -197,10 +197,10 @@ packages: dependency: transitive description: name: cupertino_ui - sha256: c23816577a1280cff409e989541767887011f8f1d8c1863a794ed308af46f2a9 + sha256: "8e14acc2817ff469b925b0e275ab85ecc6c769621360dd0af1331c47f916e247" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.3" dap: dependency: transitive description: @@ -221,10 +221,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "82ade9fc4273f29ed673e33166944465225b4f7fc5d4aaef48605cc751c18fc1" + sha256: a0e4f65339b31eb6a9e6a12e14b4682a48d46fbc54a82f4a702396fbdbac63a7 url: "https://pub.dev" source: hosted - version: "3.1.13" + version: "3.1.14" dds_service_extensions: dependency: transitive description: @@ -285,34 +285,34 @@ packages: dependency: transitive description: name: file_selector_android - sha256: "1d45e9910f68c16eb0c74f0b10097ad81aed516ea28054c027137e8f7d75e840" + sha256: d670cd0ce77a2e785b18d8b4d0a8d6a222d6a813ec9b7ddf2790a1b4fb6fa92c url: "https://pub.dev" source: hosted - version: "0.5.2+9" + version: "0.5.2+11" file_selector_ios: dependency: transitive description: name: file_selector_ios - sha256: e2ecf2885c121691ce13b60db3508f53c01f869fb6e8dc5c1cfa771e4c46aeca + sha256: "5b42ec0ef7626124b4624ea244341e9df780406793c204e89fa68a2e71af115c" url: "https://pub.dev" source: hosted - version: "0.5.3+5" + version: "0.5.3+7" file_selector_linux: dependency: transitive description: name: file_selector_linux - sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" + sha256: da76400e7872ce7637ffdce12749ec24169c25f6195c28372208e65a24bcd2ab url: "https://pub.dev" source: hosted - version: "0.9.4" + version: "0.9.4+1" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" + sha256: d785431f1910aac8a50e5c492cae912320158030a88703c67b9ef7f1f96fd7ba url: "https://pub.dev" source: hosted - version: "0.9.5" + version: "0.9.5+2" file_selector_platform_interface: dependency: transitive description: @@ -333,10 +333,10 @@ packages: dependency: transitive description: name: file_selector_windows - sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" + sha256: fbefc5fb92c6d3cbe8d284a2cd971b593bb07d2cd6da8557b81a862250b4acec url: "https://pub.dev" source: hosted - version: "0.9.3+5" + version: "0.9.3+6" fixnum: dependency: transitive description: @@ -397,10 +397,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + sha256: "404dbf9bce29beafbe9dcb19219447b6f7d49900cd42b8d3b7af102b24508e25" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.1.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -410,10 +410,10 @@ packages: dependency: transitive description: name: glob - sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + sha256: "218aeb56050c714f62a3182775320dfa04602b55074873e24e31bbd39bda96fb" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.2.0" graphs: dependency: transitive description: @@ -450,10 +450,10 @@ packages: dependency: transitive description: name: image - sha256: "6300175e00616bbc832e2fc91bfa4d776af5402c81c7151bee6905bb08473c52" + sha256: "89ed75b2f8231fe676808c5564f9590d728024ded7ac782a7ed8474f1c95b72a" url: "https://pub.dev" source: hosted - version: "4.9.1" + version: "4.12.0" integration_test: dependency: transitive description: flutter @@ -471,10 +471,10 @@ packages: dependency: transitive description: name: io - sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + sha256: "2635216ca6a737e60de577ffa1a48a0bec76ca8a62917cfc1bb88c14c570646f" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.1.0" json_annotation: dependency: transitive description: @@ -567,10 +567,10 @@ packages: dependency: transitive description: name: material_ui - sha256: "134ab2f0843545c4e661e4ba2753fe1bcf0753cb690d5a9ee4870638a40411e9" + sha256: e4031746f96c8316864d9b92bce375f1320a36ed56e166307e1e1bda9d90b4ab url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.8.0" meta: dependency: transitive description: @@ -583,10 +583,10 @@ packages: dependency: transitive description: name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + sha256: bd47de35f07e27267e69c8c8b22edf9473bfee170a60d60fcc93730c5144b7f6 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" mockito: dependency: transitive description: @@ -615,10 +615,10 @@ packages: dependency: transitive description: name: package_config - sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "3.0.0" path: dependency: transitive description: @@ -634,22 +634,14 @@ packages: relative: true source: path version: "0.0.1" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" - url: "https://pub.dev" - source: hosted - version: "7.0.2" platform: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: a36d119c13416516a7b5913fbe8af8531e11633d784c550b2125f76c758524ec url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.2.0" plugin_platform_interface: dependency: transitive description: @@ -662,10 +654,10 @@ packages: dependency: transitive description: name: pointer_interceptor - sha256: "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523" + sha256: "9ad8889f36a417649ad7578fdb6df967157208cb90f69facd043660424020710" url: "https://pub.dev" source: hosted - version: "0.10.1+2" + version: "0.10.1+3" pointer_interceptor_ios: dependency: transitive description: @@ -694,10 +686,10 @@ packages: dependency: transitive description: name: pool - sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + sha256: "4177f68c237ea2128d1bee66ac17b2ce05ba3dbaafcbdd54c5d40a39d0b6b11c" url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "1.5.3" posix: dependency: transitive description: @@ -710,10 +702,10 @@ packages: dependency: transitive description: name: process - sha256: c6248e4526673988586e8c00bb22a49210c258dc91df5227d5da9748ecf79744 + sha256: "4242ba3508d37e01808bdf71ad1d5bb93a8d671bf2e7450e6b1b353fb0808891" url: "https://pub.dev" source: hosted - version: "5.0.5" + version: "5.0.6" protobuf: dependency: transitive description: @@ -734,26 +726,26 @@ packages: dependency: transitive description: name: pub_semver - sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + sha256: c38b81cbf34450b67e0265d73433569d12e34782e30ed769c9cc99c9d5f2e796 url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.0" shelf: dependency: transitive description: name: shelf - sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + sha256: e75e9cf311d7fd712048038cc17c25199c38536c20330d53e7db058b543d5a48 url: "https://pub.dev" source: hosted - version: "1.4.2" + version: "1.4.3" shelf_packages_handler: dependency: transitive description: @@ -766,10 +758,10 @@ packages: dependency: transitive description: name: shelf_static - sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + sha256: "480504af9e5323899c5be26a4f6c2fc4437d50954d39842f0290f4ae733d57b4" url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "1.2.0" shelf_web_socket: dependency: transitive description: @@ -782,10 +774,10 @@ packages: dependency: transitive description: name: skills_lint - sha256: "5daeff89c8c9d812cfa811e119ae88a32bb81d28c73aa7e899155885b2e63a63" + sha256: "5638b7ea79b265f0b2029abec61013296590e545eb6ecdb474bee1b94c06af79" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.5.2" sky_engine: dependency: transitive description: flutter @@ -795,10 +787,10 @@ packages: dependency: transitive description: name: source_gen - sha256: a603f1fb984a7391ae5978d1b92bfaaa08b350dca5c825256f925818f7943bf5 + sha256: "833ea7d15b5be79949d3d6c077da0267a0bd93c16897b36a771395a91e63086e" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "4.3.1" source_map_stack_trace: dependency: transitive description: @@ -811,10 +803,10 @@ packages: dependency: transitive description: name: source_maps - sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898" url: "https://pub.dev" source: hosted - version: "0.10.13" + version: "0.10.14" source_span: dependency: transitive description: @@ -859,10 +851,10 @@ packages: dependency: transitive description: name: stream_transform - sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + sha256: a00e5f18bffc764f923e7dec1038527f7fe7a1791361a7117f0358193f13d53a url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -891,26 +883,26 @@ packages: dependency: transitive description: name: test - sha256: de5d145b0afff7921e5e788a880f52d7e5f3ae24068a202f6fd3b58e4ba26323 + sha256: "44b2fccf4407bcdb5e105c064c5d6b5e2a640c87761f8b03cdce8cf532d98cfa" url: "https://pub.dev" source: hosted - version: "1.32.0" + version: "1.33.0" test_api: dependency: transitive description: name: test_api - sha256: "0a10344e901e5b2e63819567951cb6a06673ed6b84f40462188ff5a0c41f371f" + sha256: "47481c58bb92d0b1d218f0510ff5647e768f8e1256d07077a151fb520923b51d" url: "https://pub.dev" source: hosted - version: "0.7.14" + version: "0.7.15" test_core: dependency: transitive description: name: test_core - sha256: "80f3fb49087454e07e7e07c67578cfdd156c8c3a5227d8b3f47c7b2d019c2e93" + sha256: "9dec4c178bd61493e1cd2060ffe701fcb61c43da2493e99590fb1b0cc82eb4af" url: "https://pub.dev" source: hosted - version: "0.6.20" + version: "0.6.21" typed_data: dependency: transitive description: @@ -931,42 +923,42 @@ packages: dependency: transitive description: name: url_launcher - sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + sha256: e8cc955c97e06df9879140a1fe301f3d493f01b7c62dec7f46834be31d7e9fda url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32 + sha256: "611e87fb320b70d1dd721dc46af89c98aceccea9b31fde49e084591414e0c610" url: "https://pub.dev" source: hosted - version: "6.3.32" + version: "6.3.33" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + sha256: "8faa1aab294f1ab4040b43660c887b0418d5fa4f0cffef76a484e6aa1092eb4a" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.4.2" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + sha256: "10f86fef4c2c43563fa6c211ff9cf757adf4d3ab762c56bd430664a947d70cd0" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.3" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + sha256: "5e835a3b869c2d70325349c81c5a45c28e20791265b67b2669da6b08c5cd5201" url: "https://pub.dev" source: hosted - version: "3.2.5" + version: "3.2.6" url_launcher_platform_interface: dependency: transitive description: @@ -987,10 +979,10 @@ packages: dependency: transitive description: name: url_launcher_windows - sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + sha256: "6c5ad3f22cd4c38e089b81963b3cd7bb83b111b2df5dce008bb066162f42e429" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" vector_math: dependency: transitive description: @@ -1003,10 +995,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0" + sha256: "89b11d62e1040ee681af3b4f1c97a803ecbf010c6e8b9c5896ee5b08c3bf7b78" url: "https://pub.dev" source: hosted - version: "15.3.0" + version: "15.4.0" vm_service_protos: dependency: transitive description: @@ -1067,10 +1059,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" + sha256: "28b82ec894fed45dd71c23ba62d1af973ed97dd59a4f5790a4d38b0b13e5657e" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.2.0" webkit_inspection_protocol: dependency: transitive description: @@ -1079,22 +1071,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" - xml: - dependency: transitive - description: - name: xml - sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4" - url: "https://pub.dev" - source: hosted - version: "7.0.1" yaml: dependency: transitive description: name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" yaml_edit: dependency: transitive description: From ca661db91acd338682295fcde5451d6d9cbf97f7 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Tue, 20 Oct 2026 18:33:38 +0000 Subject: [PATCH 02/10] Fix test for new SDK version --- .../shared/diagnostics/variable_factory.dart | 34 ++++++++++++++++++- .../debugger/typed_data_variable_test.dart | 24 +------------ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart b/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart index 5ffd61b7fca..e46e2ce700d 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart @@ -455,7 +455,7 @@ List createVariablesForBytes( variables.add( DartObjectNode.fromValue( name: '[$name]', - value: result[i], + value: _formatSimdValue(result[i]) ?? result[i], isolateRef: isolateRef, artificialName: true, ), @@ -464,6 +464,38 @@ List createVariablesForBytes( return variables; } +/// The number of decimal places used to display the lanes of a [Float32x4] or +/// [Float64x2] value. +const _simdFloatFractionDigits = 6; + +/// The number of hex digits used to display a 32-bit lane of an [Int32x4] +/// value. +const _simdInt32HexDigits = 8; + +/// Returns a display string for [value] if it is a SIMD value ([Int32x4], +/// [Float32x4], or [Float64x2]), or null otherwise. +/// +/// We format these values manually instead of relying on `toString()` because +/// the output of `toString()` for SIMD types is platform dependent (the Dart +/// VM returns the opaque string 'V128', and the web returns a different format +/// than the VM historically did). Formatting the lanes ourselves ensures that +/// users see the actual values on every platform. +String? _formatSimdValue(Object? value) { + String formatFloat(double lane) => + lane.toStringAsFixed(_simdFloatFractionDigits); + String formatInt32(int lane) => + (lane & 0xFFFFFFFF).toRadixString(16).padLeft(_simdInt32HexDigits, '0'); + + return switch (value) { + Int32x4(:final x, :final y, :final z, :final w) => + '[${[x, y, z, w].map(formatInt32).join(', ')}]', + Float32x4(:final x, :final y, :final z, :final w) => + '[${[x, y, z, w].map(formatFloat).join(', ')}]', + Float64x2(:final x, :final y) => '[${[x, y].map(formatFloat).join(', ')}]', + _ => null, + }; +} + List createVariablesForSets( Instance instance, IsolateRef? isolateRef, diff --git a/packages/devtools_app/test/screens/debugger/typed_data_variable_test.dart b/packages/devtools_app/test/screens/debugger/typed_data_variable_test.dart index dc3c4d34fd3..b0f0325e643 100644 --- a/packages/devtools_app/test/screens/debugger/typed_data_variable_test.dart +++ b/packages/devtools_app/test/screens/debugger/typed_data_variable_test.dart @@ -372,13 +372,6 @@ void main() { expect( variable.children.first.displayValue, '[ffffffff, 00000000, ffffffff, 00000000]', - skip: kIsWeb, - ); - // Formatting is different on the web. - expect( - variable.children.first.displayValue, - '[-1, 0, -1, 0]', - skip: !kIsWeb, ); }); @@ -408,12 +401,6 @@ void main() { expect( variable.children.first.displayValue, '[0.000000, -232.199997, 2.330000, 9.000000]', - skip: kIsWeb, - ); - expect( - variable.children.first.displayValue, - '[0, -232.1999969482422, 2.3299999237060547, 9]', - skip: !kIsWeb, ); }); @@ -438,16 +425,7 @@ void main() { await buildVariablesTree(variable); - expect( - variable.children.first.displayValue, - '[0.000000, -1232.222000]', - skip: kIsWeb, - ); - expect( - variable.children.first.displayValue, - '[0, -1232.222]', - skip: !kIsWeb, - ); + expect(variable.children.first.displayValue, '[0.000000, -1232.222000]'); }); test( From 14080a048dcd807766682bbf6fface9d0f9f3357 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Tue, 20 Oct 2026 11:51:08 -0700 Subject: [PATCH 03/10] Update packages/devtools_app_shared/CHANGELOG.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/devtools_app_shared/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app_shared/CHANGELOG.md b/packages/devtools_app_shared/CHANGELOG.md index 023e2ed62fe..82f02cbc36a 100644 --- a/packages/devtools_app_shared/CHANGELOG.md +++ b/packages/devtools_app_shared/CHANGELOG.md @@ -4,7 +4,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. --> ## 0.5.2-wip -* Remove redundant argument values. +* Removed redundant argument values. * Fix a `RangeError` thrown by `SplitPane` when the number of children changes between rebuilds. * Fix garbage collection and timeout issues with the result list in `asyncEval` on both native VM and web. From 2c93daa92905a4f328529fe5d83578a2e90e1ec5 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Tue, 20 Oct 2026 11:51:17 -0700 Subject: [PATCH 04/10] Update packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../lib/src/shared/diagnostics/variable_factory.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart b/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart index e46e2ce700d..6945ec8252f 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/variable_factory.dart @@ -484,7 +484,7 @@ String? _formatSimdValue(Object? value) { String formatFloat(double lane) => lane.toStringAsFixed(_simdFloatFractionDigits); String formatInt32(int lane) => - (lane & 0xFFFFFFFF).toRadixString(16).padLeft(_simdInt32HexDigits, '0'); + lane.toUnsigned(32).toRadixString(16).padLeft(_simdInt32HexDigits, '0'); return switch (value) { Int32x4(:final x, :final y, :final z, :final w) => From 7130fb23244200da0191689c04641900a1f56c8e Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Tue, 20 Oct 2026 19:55:13 +0000 Subject: [PATCH 05/10] increase bundle size --- packages/devtools_app/benchmark/web_bundle_size_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/benchmark/web_bundle_size_test.dart b/packages/devtools_app/benchmark/web_bundle_size_test.dart index f9fa08fabd9..dd28b61d0ce 100644 --- a/packages/devtools_app/benchmark/web_bundle_size_test.dart +++ b/packages/devtools_app/benchmark/web_bundle_size_test.dart @@ -11,7 +11,7 @@ import 'package:path/path.dart' as path; import 'package:test/test.dart'; // Benchmark size in kB. -const bundleSizeBenchmark = 6000; +const bundleSizeBenchmark = 6200; const gzipBundleSizeBenchmark = 1750; void main() { From 468387e7c05f161ba4f809e02d52e82ec6ec4a61 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Tue, 20 Oct 2026 20:25:34 +0000 Subject: [PATCH 06/10] increase zip size too --- packages/devtools_app/benchmark/web_bundle_size_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/benchmark/web_bundle_size_test.dart b/packages/devtools_app/benchmark/web_bundle_size_test.dart index dd28b61d0ce..328304f7081 100644 --- a/packages/devtools_app/benchmark/web_bundle_size_test.dart +++ b/packages/devtools_app/benchmark/web_bundle_size_test.dart @@ -12,7 +12,7 @@ import 'package:test/test.dart'; // Benchmark size in kB. const bundleSizeBenchmark = 6200; -const gzipBundleSizeBenchmark = 1750; +const gzipBundleSizeBenchmark = 1900; void main() { group('Web Compile', () { From b62df225b4820b2c6fa230486f046b3ab7719a94 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Mon, 26 Oct 2026 21:58:20 +0000 Subject: [PATCH 07/10] upgrade flutter --- flutter-candidate.txt | 2 +- pubspec.lock | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/flutter-candidate.txt b/flutter-candidate.txt index bbe295fa680..045ef52e574 100644 --- a/flutter-candidate.txt +++ b/flutter-candidate.txt @@ -1 +1 @@ -9cba7392c62645f790ccd8c2efda0a6658d260d7 +ad22e79b227ce0d138228890ac7d28655a7dccf7 diff --git a/pubspec.lock b/pubspec.lock index f0e999e926d..59bcf28e9ab 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "48e48f73a431eb269eec66d243a63a07ed90ef9417a74047a3b98d52338626ad" + sha256: "9bfb8122e2505aca17219018593c384a87166cfe860d11c7ae927e7f978eb05f" url: "https://pub.dev" source: hosted - version: "109.0.0" + version: "110.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "6d377901d198536b648172974d9d4f277910502cad92193466869cac0ff34990" + sha256: "74c36179c4de542efea24c9dff78324375e4b118a2c1e14e8a7659f457947f8d" url: "https://pub.dev" source: hosted - version: "14.5.0" + version: "14.6.0" archive: dependency: transitive description: @@ -189,18 +189,18 @@ packages: dependency: transitive description: name: crypto - sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + sha256: e3626ae6270383c9e3a549f34c9e4cd26c09ae6a9adaab2bf4737a00340efdc4 url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "3.0.8" cupertino_ui: dependency: transitive description: name: cupertino_ui - sha256: "8e14acc2817ff469b925b0e275ab85ecc6c769621360dd0af1331c47f916e247" + sha256: a47c4e7c66fd7444a063a602597fceb238f705c3f6b1322bc0053d0a2638ee6e url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "1.1.4" dap: dependency: transitive description: @@ -397,10 +397,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "404dbf9bce29beafbe9dcb19219447b6f7d49900cd42b8d3b7af102b24508e25" + sha256: "2b56423afc7651a81da53ed3a4f9f51e92572293f54d0d54e19b759f13714849" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.2.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -434,10 +434,10 @@ packages: dependency: transitive description: name: http_multi_server - sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + sha256: "361668bdd71f0ae2dc6d17b75a593520f3c414af6534f9eed1aa72049dd71d18" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.3" http_parser: dependency: transitive description: @@ -694,10 +694,10 @@ packages: dependency: transitive description: name: posix - sha256: bc1bad54ad2b735816e31f8d4600cfde6c7839975085ddfbca48b6c9f7c4044e + sha256: "6312deb534ce3812a1b454143740ffe721a17dc3a33bfc978f3a6d7bc5833edf" url: "https://pub.dev" source: hosted - version: "6.5.2" + version: "6.5.3" process: dependency: transitive description: @@ -734,10 +734,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: c38b81cbf34450b67e0265d73433569d12e34782e30ed769c9cc99c9d5f2e796 + sha256: "9ac81c01ffd6a9cf9b2713288834fbaaf6aebde05ffdf02d380e68b8e06f27d8" url: "https://pub.dev" source: hosted - version: "1.6.0" + version: "1.7.0" shelf: dependency: transitive description: @@ -1027,10 +1027,10 @@ packages: dependency: transitive description: name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + sha256: e119e82ac4795c7925103b7cf3768191f33941b99e7ccffbd6c645201d9f606b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" web_benchmarks: dependency: transitive description: From 82f52c3fa744fb7975408888b0054a3df5f2c617 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Tue, 27 Oct 2026 21:41:27 +0000 Subject: [PATCH 08/10] Work around macOS dart:io posix_spawn hang in dt Only forward dt's stdin to child processes when stdin is a terminal. On CI, stdin is /dev/null. package:io's sharedStdIn reads it to EOF, which makes dart:io close fd 0. With the posix_spawn-based macOS process implementation (Dart SDK commit 0171629a5478), spawning children after fd 0 is closed breaks their stdio, so nested dt invocations (e.g. `dt pub-get` under `dt generate-code`) hang forever waiting on a child that already exited. This hung every macOS CI job with the new Flutter candidate. See https://github.com/dart-lang/sdk/issues/64744. --- tool/bin/dt.dart | 10 +++++--- tool/lib/commands/analyze.dart | 3 +-- tool/lib/commands/build.dart | 3 +-- tool/lib/commands/fix_goldens.dart | 3 +-- tool/lib/commands/generate_code.dart | 3 +-- tool/lib/commands/presubmit.dart | 2 +- tool/lib/commands/pub_get.dart | 3 +-- tool/lib/commands/release_helper.dart | 2 +- tool/lib/commands/release_notes_helper.dart | 4 ++-- tool/lib/commands/run.dart | 3 +-- tool/lib/commands/serve.dart | 3 +-- tool/lib/commands/sync.dart | 3 +-- tool/lib/commands/tag_version.dart | 3 +-- tool/lib/commands/update_dart_sdk_deps.dart | 3 +-- tool/lib/commands/update_flutter_sdk.dart | 3 +-- tool/lib/commands/update_perfetto.dart | 4 ++-- tool/lib/utils.dart | 26 +++++++++++++++++++++ 17 files changed, 50 insertions(+), 31 deletions(-) diff --git a/tool/bin/dt.dart b/tool/bin/dt.dart index 4a6c98a41b3..bba3d293a67 100755 --- a/tool/bin/dt.dart +++ b/tool/bin/dt.dart @@ -6,14 +6,18 @@ import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:devtools_tool/devtools_command_runner.dart'; +import 'package:devtools_tool/utils.dart'; import 'package:io/io.dart'; void main(List args) async { final runner = DevToolsCommandRunner(); try { - final dynamic result = await runner - .run(args) - .whenComplete(sharedStdIn.terminate); + final dynamic result = await runner.run(args).whenComplete(() async { + // Only touch [sharedStdIn] if it may have been used. Accessing it starts + // listening to stdin, which we must avoid when stdin is not a terminal. + // See [shouldForwardStdin]. + if (shouldForwardStdin) await sharedStdIn.terminate(); + }); exit(result is int ? result : 0); } catch (e, st) { diff --git a/tool/lib/commands/analyze.dart b/tool/lib/commands/analyze.dart index e220919a03c..ed9e605eadc 100644 --- a/tool/lib/commands/analyze.dart +++ b/tool/lib/commands/analyze.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'package:args/command_runner.dart'; import 'package:cli_util/cli_logging.dart'; -import 'package:io/io.dart'; import '../model.dart'; import '../utils.dart'; @@ -45,7 +44,7 @@ class AnalyzeCommand extends Command { Future run() async { final log = Logger.standard(); final repo = DevToolsRepo.getInstance(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final skipUnimportant = argResults![_skipUnimportantArg] as bool; final packages = repo.getPackages( skip: skipUnimportant ? _unimportantDirectories : [], diff --git a/tool/lib/commands/build.dart b/tool/lib/commands/build.dart index 3f7078088c5..56a244d7d9c 100644 --- a/tool/lib/commands/build.dart +++ b/tool/lib/commands/build.dart @@ -7,7 +7,6 @@ import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:devtools_tool/commands/shared.dart'; import 'package:devtools_tool/model.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import '../utils.dart'; @@ -58,7 +57,7 @@ class BuildCommand extends Command { @override Future run() async { final repo = DevToolsRepo.getInstance(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final results = argResults!; final updateFlutter = results[SharedCommandArgs.updateFlutter.flagName] as bool; diff --git a/tool/lib/commands/fix_goldens.dart b/tool/lib/commands/fix_goldens.dart index a7661f485a7..ad2c4d72bdb 100644 --- a/tool/lib/commands/fix_goldens.dart +++ b/tool/lib/commands/fix_goldens.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import '../utils.dart'; @@ -32,7 +31,7 @@ class FixGoldensCommand extends Command { @override String get name => 'fix-goldens'; - final processManager = ProcessManager(); + final processManager = createProcessManager(); @override FutureOr? run() async { diff --git a/tool/lib/commands/generate_code.dart b/tool/lib/commands/generate_code.dart index 8e9b1d42ffd..fe2f2688bfc 100644 --- a/tool/lib/commands/generate_code.dart +++ b/tool/lib/commands/generate_code.dart @@ -4,7 +4,6 @@ import 'package:args/command_runner.dart'; import 'package:devtools_tool/model.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import '../utils.dart'; @@ -40,7 +39,7 @@ class GenerateCodeCommand extends Command { @override Future run() async { final repo = DevToolsRepo.getInstance(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); Future runOverPackages( CliCommand command, { diff --git a/tool/lib/commands/presubmit.dart b/tool/lib/commands/presubmit.dart index 66648807486..911ef56a384 100644 --- a/tool/lib/commands/presubmit.dart +++ b/tool/lib/commands/presubmit.dart @@ -37,7 +37,7 @@ class PresubmitCommand extends Command { Future run() async { final log = Logger.standard(); final repo = DevToolsRepo.getInstance(); - final pm = processManager ?? ProcessManager(); + final pm = processManager ?? createProcessManager(); final fix = argResults!['fix'] as bool; log.stdout('Running pub get...'); diff --git a/tool/lib/commands/pub_get.dart b/tool/lib/commands/pub_get.dart index 8397efaa424..dcdceb01268 100644 --- a/tool/lib/commands/pub_get.dart +++ b/tool/lib/commands/pub_get.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'package:args/command_runner.dart'; import 'package:cli_util/cli_logging.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import '../model.dart'; @@ -38,7 +37,7 @@ class PubGetCommand extends Command { Future run() async { final log = Logger.standard(); final repo = DevToolsRepo.getInstance(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final packages = repo.getPackages(); final upgrade = argResults![_upgradeFlag] as bool; diff --git a/tool/lib/commands/release_helper.dart b/tool/lib/commands/release_helper.dart index 4e68d112991..ee8a16571fb 100644 --- a/tool/lib/commands/release_helper.dart +++ b/tool/lib/commands/release_helper.dart @@ -36,7 +36,7 @@ class ReleaseHelperCommand extends Command { @override FutureOr? run() async { final log = Logger.standard(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final debug = argResults![_debugFlag] as bool; final currentBranchResult = await processManager.runProcess( diff --git a/tool/lib/commands/release_notes_helper.dart b/tool/lib/commands/release_notes_helper.dart index 624483629b2..436b67e3022 100644 --- a/tool/lib/commands/release_notes_helper.dart +++ b/tool/lib/commands/release_notes_helper.dart @@ -9,7 +9,7 @@ import 'package:args/command_runner.dart'; import 'package:cli_util/cli_logging.dart'; import 'package:devtools_tool/model.dart'; import 'package:devtools_tool/utils.dart'; -import 'package:io/io.dart'; +import 'package:io/io.dart' show copyPath; import 'package:path/path.dart' as p; class ReleaseNotesCommand extends Command { @@ -42,7 +42,7 @@ class ReleaseNotesCommand extends Command { @override FutureOr? run() async { final log = Logger.standard(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final devToolsReleaseNotesDirectory = Directory( p.join( diff --git a/tool/lib/commands/run.dart b/tool/lib/commands/run.dart index 4183865a2ae..b12f1cb45fb 100644 --- a/tool/lib/commands/run.dart +++ b/tool/lib/commands/run.dart @@ -4,7 +4,6 @@ import 'package:args/command_runner.dart'; import 'package:devtools_tool/commands/shared.dart'; -import 'package:io/io.dart'; import '../utils.dart'; @@ -30,7 +29,7 @@ class RunCommand extends Command { @override Future run() async { - final processManager = ProcessManager(); + final processManager = createProcessManager(); final process = await processManager.runProcess( CliCommand.tool([ 'serve', diff --git a/tool/lib/commands/serve.dart b/tool/lib/commands/serve.dart index 9eb7cff86c1..96bb338aee7 100644 --- a/tool/lib/commands/serve.dart +++ b/tool/lib/commands/serve.dart @@ -8,7 +8,6 @@ import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:devtools_tool/model.dart'; import 'package:devtools_tool/utils.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import 'shared.dart'; @@ -142,7 +141,7 @@ class ServeCommand extends Command { ); final repo = DevToolsRepo.getInstance(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final results = argResults!; final buildApp = results[_buildAppFlag] as bool; diff --git a/tool/lib/commands/sync.dart b/tool/lib/commands/sync.dart index 5455c20dfd0..9b3cf9eb4de 100644 --- a/tool/lib/commands/sync.dart +++ b/tool/lib/commands/sync.dart @@ -3,7 +3,6 @@ // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. import 'package:args/command_runner.dart'; -import 'package:io/io.dart'; import '../utils.dart'; import 'shared.dart'; @@ -22,7 +21,7 @@ class SyncCommand extends Command { @override Future run() async { - final processManager = ProcessManager(); + final processManager = createProcessManager(); await processManager.runProcess( CliCommand.git(['pull', 'upstream', 'master']), ); diff --git a/tool/lib/commands/tag_version.dart b/tool/lib/commands/tag_version.dart index 17996d04b65..356b913f81e 100644 --- a/tool/lib/commands/tag_version.dart +++ b/tool/lib/commands/tag_version.dart @@ -7,7 +7,6 @@ import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:cli_util/cli_logging.dart'; import 'package:devtools_tool/model.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import 'package:yaml/yaml.dart'; import '../utils.dart'; @@ -41,7 +40,7 @@ class TagVersionCommand extends Command { final version = yamlMap['version'].toString(); log.stdout('Current DevTools version: $version'); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final gitTag = 'v$version'; log.stdout('Creating git tag: $gitTag'); diff --git a/tool/lib/commands/update_dart_sdk_deps.dart b/tool/lib/commands/update_dart_sdk_deps.dart index 49bb085be7f..2c0505df1c4 100644 --- a/tool/lib/commands/update_dart_sdk_deps.dart +++ b/tool/lib/commands/update_dart_sdk_deps.dart @@ -5,7 +5,6 @@ import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:io/io.dart'; import 'package:path/path.dart' as path; import '../utils.dart'; @@ -41,7 +40,7 @@ class UpdateDartSdkDepsCommand extends Command { Future run() async { final commit = argResults![_argCommit] as String; final dartSdkLocation = localDartSdkLocation(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); print('Preparing a local Dart SDK branch...'); await DartSdkHelper.fetchAndCheckoutMaster(processManager); diff --git a/tool/lib/commands/update_flutter_sdk.dart b/tool/lib/commands/update_flutter_sdk.dart index 73a95f5070c..23682c71616 100644 --- a/tool/lib/commands/update_flutter_sdk.dart +++ b/tool/lib/commands/update_flutter_sdk.dart @@ -7,7 +7,6 @@ import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:cli_util/cli_logging.dart'; import 'package:devtools_tool/model.dart'; -import 'package:io/io.dart'; import '../utils.dart'; import 'shared.dart'; @@ -43,7 +42,7 @@ class UpdateFlutterSdkCommand extends Command { argResults![SharedCommandArgs.updateOnPath.flagName] as bool; final log = Logger.standard(); final repo = DevToolsRepo.getInstance(); - final processManager = ProcessManager(); + final processManager = createProcessManager(); final String? flutterVersion; final versionStr = repo.readFile(Uri.parse('flutter-candidate.txt')).trim(); diff --git a/tool/lib/commands/update_perfetto.dart b/tool/lib/commands/update_perfetto.dart index 1fce2f2a1c4..5c991ec0745 100644 --- a/tool/lib/commands/update_perfetto.dart +++ b/tool/lib/commands/update_perfetto.dart @@ -6,7 +6,7 @@ import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:devtools_tool/model.dart'; -import 'package:io/io.dart'; +import 'package:io/io.dart' show copyPath; import 'package:path/path.dart' as path; import '../utils.dart'; @@ -52,7 +52,7 @@ class UpdatePerfettoCommand extends Command { throw 'Updating Perfetto is not currently supported on Windows'; } - final processManager = ProcessManager(); + final processManager = createProcessManager(); final authenticate = argResults![_authFlag] as bool; if (authenticate) { diff --git a/tool/lib/utils.dart b/tool/lib/utils.dart index 45ecdc8b280..23d6227b350 100644 --- a/tool/lib/utils.dart +++ b/tool/lib/utils.dart @@ -51,6 +51,32 @@ String localDartSdkLocation() { return localDartSdkLocation; } +/// Whether `dt` should forward its own stdin to the child processes it spawns. +/// +/// We only forward stdin when it is attached to a terminal, which is the case +/// where a user may actually type input for a child process (for example, +/// hot reload commands for `flutter run` launched by `dt run`). +/// +/// When stdin is not a terminal (for example, `/dev/null` on the CI bots), +/// listening to it reads it to EOF, and dart:io then closes file descriptor 0. +/// On macOS, the `posix_spawn`-based dart:io process implementation +/// (introduced in Dart SDK commit 0171629a5478) mishandles spawning child +/// processes once fd 0 has been closed and reused, which causes nested `dt` +/// invocations to hang forever waiting for a child process that has already +/// exited. Never listening to a non-terminal stdin avoids this. See +/// https://github.com/dart-lang/sdk/issues/64744. +// TODO(https://github.com/dart-lang/sdk/issues/64744): forward stdin +// unconditionally again once this is fixed in the Dart SDK. +final shouldForwardStdin = stdin.hasTerminal; + +/// Creates a [ProcessManager] for spawning child processes from `dt`. +/// +/// Use this instead of the default [ProcessManager] constructor, which always +/// listens to (and forwards) stdin. See [shouldForwardStdin] for details. +ProcessManager createProcessManager() => ProcessManager( + stdin: shouldForwardStdin ? sharedStdIn : const Stream>.empty(), +); + class CliCommand { CliCommand( this.exe, From f33df2f39fff3ad629f0f4f188cbe6059f044076 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Wed, 28 Oct 2026 18:03:54 +0000 Subject: [PATCH 09/10] Fall back when DDS does not collect history for a stream DDS only collects event history for a stream if the connected VM service supports it. The web debug service has no Timer stream, so with the new DDS implementation in the Dart SDK, `getStreamHistory('Timer')` fails with an invalid params error. `DdsExtension.onEventWithHistory` calls `getStreamHistory` when first listened to, and that error cannot be handled by listeners, which broke the Logging view (and the live connection integration test) for web apps. Check whether history is collected for a stream before using the DDS history stream, and fall back to the regular stream if not. --- .../lib/src/service/vm_service_wrapper.dart | 67 +++++++++++++++++-- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/packages/devtools_app/lib/src/service/vm_service_wrapper.dart b/packages/devtools_app/lib/src/service/vm_service_wrapper.dart index 87724a96d85..4cb9bc62e25 100644 --- a/packages/devtools_app/lib/src/service/vm_service_wrapper.dart +++ b/packages/devtools_app/lib/src/service/vm_service_wrapper.dart @@ -230,50 +230,103 @@ class VmServiceWrapper extends VmService { Stream get onExtensionEventWithHistorySafe { return _maybeReturnStreamWithHistory( - onExtensionEventWithHistory, + EventStreams.kExtension, + ddsStream: onExtensionEventWithHistory, fallbackStream: onExtensionEvent, ); } Stream get onLoggingEventWithHistorySafe { return _maybeReturnStreamWithHistory( - onLoggingEventWithHistory, + EventStreams.kLogging, + ddsStream: onLoggingEventWithHistory, fallbackStream: onLoggingEvent, ); } Stream get onStderrEventWithHistorySafe { return _maybeReturnStreamWithHistory( - onStderrEventWithHistory, + EventStreams.kStderr, + ddsStream: onStderrEventWithHistory, fallbackStream: onStderrEvent, ); } Stream get onStdoutEventWithHistorySafe { return _maybeReturnStreamWithHistory( - onStdoutEventWithHistory, + EventStreams.kStdout, + ddsStream: onStdoutEventWithHistory, fallbackStream: onStdoutEvent, ); } Stream get onTimerEventWithHistorySafe { return _maybeReturnStreamWithHistory( - onTimerEventWithHistory, + EventStreams.kTimer, + ddsStream: onTimerEventWithHistory, fallbackStream: onTimerEvent, ); } Stream _maybeReturnStreamWithHistory( - Stream ddsStream, { + String streamId, { + required Stream ddsStream, required Stream fallbackStream, }) { assert(_supportedProtocolsInitialized.isCompleted); if (_ddsSupported) { - return ddsStream; + return _streamWithHistoryIfCollected( + streamId, + ddsStream: ddsStream, + fallbackStream: fallbackStream, + ); } return fallbackStream; } + /// Returns [ddsStream] if DDS collects event history for [streamId], and + /// [fallbackStream] otherwise. + /// + /// DDS only collects event history for a stream when the VM service it is + /// connected to supports that stream. For example, the web debug service + /// does not support the `Timer` stream, so DDS rejects `getStreamHistory` + /// requests for it with an invalid params error. The DDS history streams + /// (e.g. [DdsExtension.onTimerEventWithHistory]) call `getStreamHistory` + /// when first listened to, and that error cannot be handled by listeners, so + /// we check whether history is collected before using [ddsStream]. + Stream _streamWithHistoryIfCollected( + String streamId, { + required Stream ddsStream, + required Stream fallbackStream, + }) async* { + final historyCollected = await _isStreamHistoryCollected.putIfAbsent( + streamId, + () => _checkStreamHistoryCollected(streamId), + ); + yield* historyCollected ? ddsStream : fallbackStream; + } + + /// Cache of whether DDS collects event history for a given stream id. + final _isStreamHistoryCollected = >{}; + + Future _checkStreamHistoryCollected(String streamId) async { + try { + await getStreamHistory(streamId); + return true; + } on RPCError catch (e) { + if (e.code != RPCErrorKind.kInvalidParams.code) { + // Do not cache unexpected failures so that we check again next time. + unawaited(_isStreamHistoryCollected.remove(streamId)); + rethrow; + } + _log.fine( + 'Event history is not collected for stream "$streamId". Falling back ' + 'to the stream without history.', + ); + return false; + } + } + // Begin Dart IO extension method wrappers. We wrap these methods so that we // can override them in tests. From 574a18acf57e8f6267e1933ae41cce6dee125304 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson Date: Wed, 28 Oct 2026 18:37:05 +0000 Subject: [PATCH 10/10] change rpc order --- .../test/live_connection/service_connection_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart index 93e3f5f335b..db145d2e069 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart @@ -70,9 +70,9 @@ void main() { 'setFlag', 'requirePermissionToResume', 'getFlagList', + 'getVM', 'getDartDevelopmentServiceVersion', 'getDartDevelopmentServiceVersion', - 'getVM', ]), reason: 'Unexpected order of vm service calls upon connection. '