Commit 5165523
[AdbRunner] Add ADB forward port management (#351)
(follow-up to #305)
Adds the symmetric forward-port pair to the reverse-port methods that landed
in #305. Same `AdbPortSpec` / `AdbPortRule` / `AdbProtocol` types — just four
new methods.
| Method | adb command |
|-------------------------------------------------|--------------------------------------------|
| ForwardPortAsync(serial, local, remote) | adb -s <serial> forward <local> <remote> |
| RemoveForwardPortAsync(serial, local) | adb -s <serial> forward --remove <local> |
| RemoveAllForwardPortsAsync(serial) | adb -s <serial> forward --remove-all |
| ListForwardPortsAsync(serial) | adb forward --list (filtered by serial) |
`adb forward` and `adb reverse` are not interchangeable — they connect
opposite directions. `forward` is host->device (the IDE/harness reaches a
service running on the device) and is the path used for JDWP debugger
attach (`forward tcp:N jdwp:<pid>`), perf-tracing endpoints exposed by the
runtime, and host-side DevFlow agent connect when the agent listens on a
device port.
Output-format note for `--list`: `adb forward --list` emits one line per
rule across all devices in the form `<serial> <local> <remote>` (different
from `(reverse) <remote> <local>`). `ListForwardPortsAsync` uses the
unscoped `adb forward --list` and filters to the requested serial in
`ParseForwardListOutput`. Serial match is case-sensitive (matches adb).
- 12 new parser tests in `ParseForwardListOutput_*` mirroring the reverse
parser tests (single rule, multiple rules, serial filtering, empty
output, malformed lines, non-tcp specs, Windows line endings, tab
separation, case sensitivity).
- 7 new parameter-validation tests covering empty serial / null spec for
the four new public methods.
- VS Code MAUI extension ServiceHub->CLI migration (`forwardPort` in
`MauiAndroidPlatform.ts` — debugger configurations, perf tooling).
- MAUI DevTools CLI (dotnet/maui-labs#197) — `maui android port forward`
group, sibling of the existing `reverse` surface.
- Visual Studio `ClientTools.Platform` — same paths that drive reverse
today.
Discussed in
#305 (comment)
### Address review feedback: capture stdout in ThrowIfFailed, parser asymmetry comment, drop null!, remove test region dividers
- ForwardPortAsync/RemoveForwardPortAsync/RemoveAllForwardPortsAsync now capture stdout and pass it to ProcessUtils.ThrowIfFailed (matches repo convention; adb sometimes writes errors to stdout).
- Added <remarks> block on ParseForwardListOutput calling out the field-order asymmetry vs ParseReverseListOutput (forward: serial local remote; reverse: (reverse) remote local).
- Replaced '(AdbPortSpec) null!' with '(AdbPortSpec) null' in 3 forward-port test sites to match reverse-test convention and repo no-null-forgiving rule.
- Removed all '// --- ... ---' region-like divider comments in AdbRunnerTests.cs (per jonathanpeppers feedback in PR #351).
### Fix RemoveAllForwardPortsAsync to honour per-serial scope
The underlying 'adb forward --remove-all' (and the wire-protocol equivalent 'host-serial:<serial>:killforward-all') is daemon-global -- the '-s <serial>' flag does not scope it. The previous implementation would silently remove forwards for every connected device despite the method's per-device API contract.
Reimplement by listing forwards for the given serial via ListForwardPortsAsync and removing them individually via RemoveForwardPortAsync. Update the XML docs to describe the actual behaviour.
Add two new tests using a recording subclass of AdbRunner that overrides ListForwardPortsAsync and RemoveForwardPortAsync to verify (1) only ports for the requested serial are removed, and (2) an empty listing is a no-op.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 06a0867 commit 5165523
4 files changed
Lines changed: 427 additions & 22 deletions
File tree
- src/Xamarin.Android.Tools.AndroidSdk
- PublicAPI
- net10.0
- netstandard2.0
- Runners
- tests/Xamarin.Android.Tools.AndroidSdk-Tests
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
202 | 206 | | |
203 | 207 | | |
204 | 208 | | |
| |||
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
202 | 206 | | |
203 | 207 | | |
204 | 208 | | |
| |||
Lines changed: 139 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
355 | 355 | | |
356 | 356 | | |
357 | 357 | | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
358 | 497 | | |
359 | 498 | | |
360 | 499 | | |
| |||
0 commit comments