Repository navigation
[flutter_tools] Fix wireless ADB device discovery when serial contains spaces - #187943
Conversation
…s spaces When ADB registers a wireless device, it uses the mDNS service name as the device serial. If there is an mDNS name conflict, ADB appends a suffix like " (2)" to the service name, resulting in a serial with a space (e.g. "adb-SERIAL (2)._adb-tls-connect._tcp"). Previously, the regex used to parse `adb devices -l` output truncated the serial at the first space, leading to corrupted device IDs and "device not found" errors. This change updates the regex to use an anchored lazy match that correctly identifies the boundary between the serial and the state, allowing spaces in the serial. It explicitly handles the "no permissions" state (which contains a space) and uses a generic match for all other single-word states. An exhaustive test case has been added to verify various combinations of serials (with/without spaces, containing state keywords) and states.
There was a problem hiding this comment.
Code Review
This pull request updates the regular expression _kDeviceRegex in android_device_discovery.dart to support parsing device serials with spaces and 'no permissions' states, and adds comprehensive unit tests to verify various adb devices output formats. Feedback suggests refining the regular expression to allow optional trailing whitespace and carriage returns to prevent matching failures on Windows.
|
|
||
| // 015d172c98400a03 device usb:340787200X product:nakasi model:Nexus_7 device:grouper | ||
| static final _kDeviceRegex = RegExp(r'^(\S+)\s+(\S+)(.*)'); | ||
| static final _kDeviceRegex = RegExp(r'^(.*?)\s+(no permissions|\S+)(?:\s+(\w+:.*)|$)'); |
There was a problem hiding this comment.
If the output line contains any trailing whitespace (such as a trailing space or a carriage return \r on Windows), the current regular expression will fail to match. This is because the last group (?:\s+(\w+:.*)|$) expects either a space followed by key-value pairs, or the absolute end of the string ($). If there is trailing whitespace, neither branch matches, causing the entire regex match to fail.\n\nTo make the parsing more robust against trailing whitespace and carriage returns, we can change the end-of-string anchor $ to \s*$ to allow optional trailing whitespace.
| static final _kDeviceRegex = RegExp(r'^(.*?)\s+(no permissions|\S+)(?:\s+(\w+:.*)|$)'); | |
| static final _kDeviceRegex = RegExp(r'^(.*?)\s+(no permissions|\S+)(?:\s+(\w+:.*)|\s*$)'); |
Add detailed comments explaining the structure of the regex used to parse `adb devices -l` output, specifically why we explicitly handle the "no permissions" state (due to it containing a space) and how the anchored lazy match prevents false positives.
…eturns Address feedback from gemini-code-assist. On Windows, `adb devices -l` output lines may end with `\r` (carriage return). When split by `\n`, the trailing `\r` remains on the line, which can cause matching failures with our anchored regex (as `$` matches after `\r`, but `\S+` stops before it, leaving `\r` unmatched by the anchor). Trimming each line at the start of the loop robustly removes any trailing `\r` (and other leading/trailing whitespace), ensuring reliable parsing on all platforms.
|
Just FYI: #187845 also seeks to address this issue. |
# Conflicts: # packages/flutter_tools/lib/src/android/android_device_discovery.dart
…12169) Manual roll Flutter from 91939cc4db78 to dc2a8703e12b (50 revisions) Manual roll requested by bensonluk@google.com flutter/flutter@91939cc...dc2a870 2026-07-09 chris@bracken.jp [ios,macos] Update swiftc.py flags to match swiftc (flutter/flutter#189174) 2026-07-09 jesswon@google.com [AGP 9] Update Warn Version to AGP 9+ (flutter/flutter#189109) 2026-07-09 154381524+flutteractionsbot@users.noreply.github.com Sync CHANGELOG.md from stable (flutter/flutter#189203) 2026-07-09 mdebbar@google.com [web] Roll Chrome to 145 (framework) (flutter/flutter#182861) 2026-07-09 engine-flutter-autoroll@skia.org Roll Packages from 52d84d6 to 20928d5 (6 revisions) (flutter/flutter#189194) 2026-07-09 zhongliu88889@gmail.com [web] Avoid absolute positioning for base CanvasKit canvas (flutter/flutter#188337) 2026-07-09 engine-flutter-autoroll@skia.org Roll Dart SDK from cdb7217e65aa to a11fb7ed40a5 (6 revisions) (flutter/flutter#189195) 2026-07-09 matt.kosarek@canonical.com Fix dereference of nullptr in the moved-to-rect signal in the Linux embedder (flutter/flutter#189152) 2026-07-09 katelovett@google.com Fix data for design packages (flutter/flutter#189140) 2026-07-09 engine-flutter-autoroll@skia.org Roll Skia from 7b42d1251d54 to ab3a7b98c94d (2 revisions) (flutter/flutter#189181) 2026-07-09 engine-flutter-autoroll@skia.org Roll Skia from 05d9d214e0b7 to 7b42d1251d54 (2 revisions) (flutter/flutter#189175) 2026-07-09 engine-flutter-autoroll@skia.org Roll Skia from 542c8bdd7f4f to 05d9d214e0b7 (4 revisions) (flutter/flutter#189169) 2026-07-09 97480502+b-luk@users.noreply.github.com UberSDF rect handling for thin (line-like) rectangles (flutter/flutter#188821) 2026-07-09 engine-flutter-autoroll@skia.org Roll Skia from dd572c07f63c to 542c8bdd7f4f (4 revisions) (flutter/flutter#189160) 2026-07-09 markzipan@google.com [flutter_tools] Fix hot restart for WASM web builds (flutter/flutter#187898) 2026-07-08 robert.ancell@canonical.com Split FlViewRenderer into OpenGL and software backends (flutter/flutter#188824) 2026-07-08 awolff@google.com Promote android_hardware_smoke_tests out of bringup in CI (flutter/flutter#189081) 2026-07-08 engine-flutter-autoroll@skia.org Roll Skia from 8df24be66531 to dd572c07f63c (4 revisions) (flutter/flutter#189150) 2026-07-08 matt.kosarek@canonical.com Expose LinuxWindowRegistrar on _window_linux.dart in order to better support out of tree LinuxWindowingOwners (flutter/flutter#188917) 2026-07-08 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#189149) 2026-07-08 codefu@google.com fix(ci): harden some workflows (flutter/flutter#189087) 2026-07-08 engine-flutter-autoroll@skia.org Roll Skia from 51a62da33da0 to 8df24be66531 (1 revision) (flutter/flutter#189139) 2026-07-08 iinozemtsev@google.com Roll Dart SDK to Dart 3.13 beta3 (flutter/flutter#189122) 2026-07-08 digvijaysinghiam@gmail.com [flutter_tools] Don't crash on non-UTF-8 plugin pubspec.yaml (flutter/flutter#188976) 2026-07-08 bkonyi@google.com [flutter_tools] Watch transitive #include headers for FragmentProgram hot reload (flutter/flutter#187945) 2026-07-08 engine-flutter-autoroll@skia.org Roll Skia from 040d9f55de00 to 51a62da33da0 (1 revision) (flutter/flutter#189135) 2026-07-08 engine-flutter-autoroll@skia.org Roll Packages from 92525f5 to 52d84d6 (7 revisions) (flutter/flutter#189134) 2026-07-08 bkonyi@google.com [flutter_tools] Forcefully kill hung subprocesses 5 seconds after timeout (flutter/flutter#187178) 2026-07-08 malo.allee@gmail.com Expose the app's build name and number as compile-time constants (flutter/flutter#187935) 2026-07-08 engine-flutter-autoroll@skia.org Roll Skia from 1ff92f879815 to 040d9f55de00 (1 revision) (flutter/flutter#189131) 2026-07-08 engine-flutter-autoroll@skia.org Roll Skia from 6137414bef5c to 1ff92f879815 (6 revisions) (flutter/flutter#189126) 2026-07-08 brackenavaron@gmail.com [test cross imports] More test/rendering + flutter_test/test fixes (flutter/flutter#188954) 2026-07-08 112751483+shivanshu877@users.noreply.github.com engine: explain why each candidate build was skipped in Flutter web loader (flutter/flutter#186254) 2026-07-08 chris@bracken.jp vscode: add missing unicode.h (flutter/flutter#189102) 2026-07-08 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from 7RjQJBW3m-3Jl-7jr... to QcRFUtvCw2EobfJ8s... (flutter/flutter#189104) 2026-07-08 engine-flutter-autoroll@skia.org Roll Skia from 075fbe4778d9 to 6137414bef5c (10 revisions) (flutter/flutter#189106) 2026-07-08 112751483+shivanshu877@users.noreply.github.com engine: warn on WASM load failure when not crossOriginIsolated (flutter/flutter#186252) 2026-07-08 engine-flutter-autoroll@skia.org Roll Dart SDK from c9bccc09e733 to db2155f56bf3 (2 revisions) (flutter/flutter#189105) 2026-07-08 bkonyi@google.com [flutter_tools] Prevent interactive device selection in machine mode (flutter/flutter#188267) 2026-07-08 bkonyi@google.com [flutter_tools] Fix wireless ADB device discovery when serial contains spaces (flutter/flutter#187943) 2026-07-07 zhongliu88889@gmail.com [web] Fix grouped autofill on iOS Chrome (flutter/flutter#187459) 2026-07-07 rmolivares@renzo-olivares.dev Fix TextSelectionOverlay crash when layout is degenerate (flutter/flutter#188672) 2026-07-07 87962825+kyungilcho@users.noreply.github.com [flutter_tools] Provision Android NDK in the main Gradle invocation (flutter/flutter#186337) 2026-07-07 awolff@google.com Android_hardware_smoke_test: Migrate to AGP 9 (flutter/flutter#189082) ...
|
This breaks some of our Mokeys!
|
Description
When ADB registers a wireless device, it uses the mDNS service name as the device serial. If there is an mDNS name conflict (e.g. due to toggling wireless debugging off and on quickly), ADB appends a suffix like
" (2)"to the service name, resulting in a serial with a space (e.g.adb-SERIAL (2)._adb-tls-connect._tcp).Previously, the regex used to parse
adb devices -loutput truncated the serial at the first space, leading to corrupted device IDs and "device not found" errors when the tool tried to communicate with the device.This change updates the regex in
android_device_discovery.dartto use an anchored lazy match that correctly identifies the boundary between the serial and the state, allowing spaces in the serial.It explicitly handles the
"no permissions"state (which is the only known state containing a space) and uses a generic match (\S+) for all other single-word states.Detailed comments have been added to the regex to explain this design.
Related Issues
Tests
android_device_discovery_test.dart(AndroidDevices can parse various adb device outputs exhaustively) that verifies various combinations of serials (with/without spaces, containing state keywords) and states.packages/flutter_tools/test/general.shard/android/android_device_discovery_test.dartand they passed.