Skip to content

[flutter_tools] Add device log streaming support to DeviceService and ExtensionBackedDevice - #194964

Merged
auto-submit[bot] merged 17 commits into
flutter:masterfrom
bkonyi:ft-ext-device-log-streaming
Oct 27, 2026
Merged

auto-submit[bot] merged 17 commits into
flutter:masterfrom
bkonyi:ft-ext-device-log-streaming

Conversation

@bkonyi

@bkonyi bkonyi commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Adds device log streaming support for tool-extension-backed target devices (flutter logs and flutter run console output):

  • Adds startLogStreamMethod (device.startLogStream), stopLogStreamMethod (device.stopLogStream), logEntryNotificationMethod (device.logEntry), lineKey, startLogStream, stopLogStream, and emitLogLine to DeviceService (package:flutter_tools_extension).
  • Implements startLogStream and stopLogStream on ExtensionDeviceClient, introduces ExtensionDeviceLogReader, and updates ExtensionBackedDevice.getLogReader to cache and dispose a per-device log reader.
  • Updates LogsCommand.runCommand() to skip applicationPackages.getPackageForPlatform when targetPlatform == TargetPlatform.unsupported (such as custom-platform extension devices).
  • Adds hermetic unit and isolate RPC tests in test/general.shard/extension_protocol/extension_device_test.dart and an end-to-end LogsCommand integration test in test/commands.shard/hermetic/tool_extensions_device_test.dart.

Part of #190755
Part of #190750

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

…n support to tool extension protocol

Adds bidirectional JSON-RPC 2.0 notification support (, , and ), sliding inactivity timeout monitoring with progress/heartbeat resets (), and cooperative request cancellation ( and ).

Updates  to use  instead of an unbounded .

Part of flutter#190755

Part of flutter#190746

Fixes flutter#193955
… ExtensionBackedDevice

Adds device log streaming RPCs (`device.startLogStream` and `device.stopLogStream`) and notification delivery (`device.logEntry`) to `DeviceService`, implements `ExtensionDeviceLogReader`, and updates `ExtensionBackedDevice.getLogReader` to stream logs from tool extension isolates.

Part of flutter#190755
Part of flutter#190750
@bkonyi bkonyi added the CICD Run CI/CD label Oct 21, 2026
@github-actions github-actions Bot added the tool Affects the "flutter" command-line tool. See also t: labels. label Oct 21, 2026
… and post-handshake isolate exit handling

Simplifies the extension protocol changes to focus on bidirectional JSON-RPC 2.0 notification support and resilient post-handshake isolate exit and error handling, removing request cancellation and heartbeat APIs.

Part of flutter#190755
Part of flutter#190746
…-device-log-streaming

# Conflicts:
#	packages/flutter_tools/packages/flutter_tools_extension/lib/src/protocol_base/provider.dart
…nd isolate exit handling

- Log unhandled extension isolate errors using logger.printError instead of trace so failure reasons are visible at default verbosity.
- Close receive port, error port, exit port, and notification controllers on unexpected isolate exit.
- Validate onNotification payload type and warn on malformed payloads rather than falling back to an empty map.
- Strengthen unit test assertions on StateError messages and verify notification streams emit done on unexpected isolate exit.

Part of flutter#190755
Part of flutter#190746
Fixes flutter#193955
…t listeners

- Switch _errorPort and _exitPort from RawReceivePort to ReceivePort.
- Add _handleIsolateError and _handleIsolateExit helper methods with documentation explaining unhandled error list payloads and unexpected exit handling.
- Wire stream listeners in ExtensionConnection.spawn before isolate spawning and dispatch to active connection once created.

Part of flutter#190755
Part of flutter#190746
…e controller cleanup

- Delegate unexpected isolate exit handling in _handleIsolateExit to dispose() to centralize resource teardown.
- Inline _closeNotificationControllers directly into dispose() as it is the single cleanup path.

Part of flutter#190755
Part of flutter#190746
…gReader and ExtensionBackedDevice

- Add async factory ExtensionDeviceLogReader.create that awaits deviceService.startLogStream before returning.
- Buffer early log lines until a listener attaches to logLines.
- Make ExtensionDeviceLogReader.dispose() asynchronous and await subscription cancellation, stopLogStream, and stream controller closure.
- Make ExtensionBackedDevice.getLogReader() return Future<DeviceLogReader> and await reader disposal in dispose().
- Update unit tests to await getLogReader, create, and dispose.

Part of flutter#190755
Part of flutter#190746
gaaclarke pushed a commit to gaaclarke/flutter that referenced this pull request Oct 22, 2026
…isolate exit handling to ExtensionConnection (flutter#194961)

Adds extension-to-host JSON-RPC notification support
(`ToolExtensionService.sendNotification` and
`ExtensionConnection.onNotification`, first consumed by device log
streaming in flutter#194964) and keeps
`onError`/`onExit` ports open after the handshake so unexpected isolate
exits or unhandled errors immediately fail pending `sendRequest(...,
timeout: null)` calls and close notification streams instead of hanging
forever.

Part of flutter#190755
Part of flutter#190746
…treaming

# Conflicts:
#	packages/flutter_tools/packages/flutter_tools_extension/lib/src/device.dart
…ommand integration test

Use private named initializers on `ExtensionBackedDevice`, scope `DeviceService.startLogStream` and `ExtensionDeviceLogReader` per `deviceId` without `appId`, revert `protocol_base/provider.dart` so `DeviceService` is not referenced from the base protocol, add explicit `String` type annotations to `DeviceService` constants, close `ExtensionDeviceLogReader.logLines` on isolate exit or startup failure, and guard `LogsCommand` against `TargetPlatform.unsupported` with an end-to-end `LogsCommand` integration test.
@bkonyi
bkonyi marked this pull request as ready for review October 23, 2026 19:31

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements device log streaming support for tool extension devices, introducing ExtensionDeviceLogReader to stream logs via RPC and updating ExtensionBackedDevice to manage its lifecycle. Feedback focuses on improving robustness and preventing resource leaks, specifically by avoiding private field formals in public constructors, cancelling subscriptions on log stream start failures, preventing log reader creation after disposal, and limiting the buffer size of pending log lines to avoid unbounded memory growth.

…nd guard post-dispose getLogReader

Cancel the notification subscription and mark `ExtensionDeviceLogReader` disposed when `startLogStream` fails, cap buffered pending log lines at `_maxPendingLines`, and return a `NoOpDeviceLogReader` if `ExtensionBackedDevice.getLogReader` is called after `dispose()`.

/// A [DeviceLogReader] that streams log lines from a tool extension isolate
/// via [DeviceService.logEntryNotificationMethod] notifications.
class ExtensionDeviceLogReader extends DeviceLogReader {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love streams. No actions needed, just venting 😂

@flutter-dashboard

Copy link
Copy Markdown

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #194964 at sha 2c62460

@flutter-dashboard flutter-dashboard Bot added the will affect goldens Changes to golden files label Oct 26, 2026

@loic-sharma loic-sharma left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@bkonyi bkonyi added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 27, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into flutter:master with commit 4e9c63a Oct 27, 2026
27 of 28 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 27, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Oct 28, 2026
flutter/flutter@d4c8577...0c2473c

2026-10-28 [email protected] Roll Packages from a8549ae to 13d38e0 (9 revisions) (flutter/flutter#195488)
2026-10-28 [email protected] Use int.oneBitCount in PersistentHashMap and scope 53-bit caps to JS (flutter/flutter#195005)
2026-10-28 [email protected] Roll pub packages (flutter/flutter#195483)
2026-10-28 [email protected] [iPhone Duo] Use the correct UIScreen to report the display size and update when fold/unfold (flutter/flutter#195199)
2026-10-28 [email protected] [fuchsia] Fix portable_ui_test.h includes for newer Fuchsia SDKs (flutter/flutter#195420)
2026-10-28 [email protected] Change default pipeline options to match production draw calls (flutter/flutter#194597)
2026-10-28 [email protected] Roll Fuchsia Test Scripts from 2T18KC7-LDQtmQiLP... to xl1LWBuppzu-BnOzV... (flutter/flutter#195450)
2026-10-27 [email protected] [flutter_tools] Inject dependencies into Darwin build targets, native assets, and Xcode build settings (flutter/flutter#194052)
2026-10-27 [email protected] Revert: Reland square corners fix (flutter/flutter#195436)
2026-10-27 [email protected] [flutter_tools] Add DeviceService app launch and flutter run support for tool extensions (flutter/flutter#194589)
2026-10-27 [email protected] [engine] Honor targetWidth/targetHeight for animated images (flutter/flutter#194615)
2026-10-27 [email protected] [Android][a11y] Set visibleToUser=false for hidden semantics nodes (flutter/flutter#194411)
2026-10-27 [email protected] Fix repo deletion test flake (flutter/flutter#195349)
2026-10-27 [email protected] Roll Packages from 23a05b6 to a8549ae (10 revisions) (flutter/flutter#195434)
2026-10-27 [email protected] [web] Capture pointers to the Flutter view so drags survive platform view iframes (flutter/flutter#195187)
2026-10-27 [email protected] [web] Add opt-in raw samples, measured sample count and warm-up phase hook to the web benchmark recorder (flutter/flutter#195118)
2026-10-27 [email protected] Link migration guide in deprecation messages (flutter/flutter#195361)
2026-10-27 [email protected] Pin basic_material_app_macos__compile to macOS 26 (flutter/flutter#195429)
2026-10-27 [email protected] Add benchmark for warmed pipeline usage (flutter/flutter#195001)
2026-10-27 [email protected] [flutter_tools] Add device log streaming support to DeviceService and ExtensionBackedDevice (flutter/flutter#194964)
2026-10-27 [email protected] Roll Dart SDK from 1d16c04dc346 to 65fc979759ca (4 revisions) (flutter/flutter#195383)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…isolate exit handling to ExtensionConnection (flutter#194961)

Adds extension-to-host JSON-RPC notification support
(`ToolExtensionService.sendNotification` and
`ExtensionConnection.onNotification`, first consumed by device log
streaming in flutter#194964) and keeps
`onError`/`onExit` ports open after the handshake so unexpected isolate
exits or unhandled errors immediately fail pending `sendRequest(...,
timeout: null)` calls and close notification streams instead of hanging
forever.

Part of flutter#190755
Part of flutter#190746
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
… ExtensionBackedDevice (flutter#194964)

Adds device log streaming support for tool-extension-backed target
devices (`flutter logs` and `flutter run` console output):

- Adds `startLogStreamMethod` (`device.startLogStream`),
`stopLogStreamMethod` (`device.stopLogStream`),
`logEntryNotificationMethod` (`device.logEntry`), `lineKey`,
`startLogStream`, `stopLogStream`, and `emitLogLine` to `DeviceService`
(`package:flutter_tools_extension`).
- Implements `startLogStream` and `stopLogStream` on
`ExtensionDeviceClient`, introduces `ExtensionDeviceLogReader`, and
updates `ExtensionBackedDevice.getLogReader` to cache and dispose a
per-device log reader.
- Updates `LogsCommand.runCommand()` to skip
`applicationPackages.getPackageForPlatform` when `targetPlatform ==
TargetPlatform.unsupported` (such as custom-platform extension devices).
- Adds hermetic unit and isolate RPC tests in
`test/general.shard/extension_protocol/extension_device_test.dart` and
an end-to-end `LogsCommand` integration test in
`test/commands.shard/hermetic/tool_extensions_device_test.dart`.

Part of flutter#190755
Part of flutter#190750

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
bkonyi added a commit to bkonyi/flutter that referenced this pull request Nov 3, 2026
…5389)

Updates `DeviceLogReader.dispose` to return `Future<void>` and awaits
disposal across device log reader implementations and callers.

Follow-up to
flutter#194964 (comment)
Part of flutter#190755
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD tool Affects the "flutter" command-line tool. See also t: labels. will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants