Skip to content

fix(pair)!: map Android PlatformType to Chrome, drop Unknown variant#601

Merged
jlucaso1 merged 2 commits intomainfrom
fix/pair-android-maps-to-chrome
Apr 27, 2026
Merged

fix(pair)!: map Android PlatformType to Chrome, drop Unknown variant#601
jlucaso1 merged 2 commits intomainfrom
fix/pair-android-maps-to-chrome

Conversation

@jlucaso1
Copy link
Copy Markdown
Collaborator

Summary

  • Auto-derivation of companion_platform_id for PlatformType::AndroidPhone/Tablet/Ambiguous now produces Chrome ('1') + "Chrome (Android)", matching what real WA Web on Chrome-Android emits per WAWebCompanionRegClientUtils.DEVICE_PLATFORM. Empirical reproduction showed the server rejects the dedicated Android letters 'e'/'d'/'f' (introduced in fix(pair): emit empirically correct companion_platform_id for Android #595) with 400 bad-request from any client that lacks Android-side attestation. The letters are still reachable through explicit opt-in via PairCodeOptions::platform_id for callers with legitimate Android signing material.
  • CompanionWebClientType::Unknown (wire byte '0') is removed from the public enum. WA Web only emits '0' when info().name is null — unreachable in real browsers — and the server rejects it from any non-WA-Web caller. #[default] now points to OtherWebClient ('9'), the catch-all WA Web actually emits when browser detection returns an unknown name. Breaking for the pre-1.0 API.
  • Refactor: pair_code.rs factors the shared os→display step into a private build_id_and_display helper, and a few table-shaped tests were merged into single parametrised loops.

Test plan

  • cargo test -p wacore --lib — 644 pass
  • cargo build --workspace
  • cargo clippy --all --tests — clean
  • cargo fmt --all -- --check — clean
  • End-to-end: pair-code stage 1 against the live server with DeviceProps { platform_type: AndroidPhone, os: "Android", .. } returns a link_code_pairing_ref (no 400 bad-request)

PR #595 mapped `PlatformType::AndroidPhone/Tablet/Ambiguous` to the
dedicated wire letters `'e'`/`'d'`/`'f'`. Empirical reproduction shows
the server rejects those bytes with `400 bad-request` from any client
that doesn't carry Android-side attestation, so the auto-derivation
now collapses Android values to `Chrome` (`'1'`) — what real WA Web on
Chrome-Android emits per `WAWebCompanionRegClientUtils.DEVICE_PLATFORM`
(`info().name === "Chrome"`) and what the server accepts.

The `Unknown` variant (wire byte `'0'`) is removed from the public enum.
WA Web only ever produces `'0'` when `info().name` is null, which is
unreachable in real browsers; the server rejects it from any non-WA-Web
caller. `#[default]` now points to `OtherWebClient` (`'9'`), the
catch-all WA Web emits when the browser detection returns an unknown
name. Callers that need the Android letters can still opt in via
`PairCodeOptions::platform_id` for contexts with legitimate Android
attestation.

While here, factored out a private `build_id_and_display` helper in
`pair_code.rs` (the os→display step is now in one place) and merged
some table-shaped tests into single parametrised loops.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3d0f3d53-5fe4-4721-82a6-9cb885076f03

📥 Commits

Reviewing files that changed from the base of the PR and between 933e764 and 82da072.

📒 Files selected for processing (3)
  • wacore/src/companion_reg.rs
  • wacore/src/pair.rs
  • wacore/src/pair_code.rs

📝 Walkthrough

Summary by CodeRabbit

  • Refactoring

    • Simplified and centralized platform detection and companion platform resolution; default handling for unrecognized platforms now falls back to a generic web client.
    • Android device types are now surfaced as the Chrome-family companion platform in displays and pairing metadata.
  • Tests

    • Updated test expectations and coverage to match the new platform mappings and defaulting behavior.

Walkthrough

This PR removes the CompanionWebClientType::Unknown variant, makes OtherWebClient the default for missing/invalid platforms, and collapses various proto/unknown platform types to OtherWebClient. Android proto platform types now map to Chrome when derived from device props; tests and pairing/QR expectations updated accordingly.

Changes

Cohort / File(s) Summary
Core enum and platform mapping
wacore/src/companion_reg.rs
Removes CompanionWebClientType::Unknown; moves #[default] to OtherWebClient (wire '9'). companion_web_client_type_for_platform and companion_web_client_type_for_props now default invalid/unknown platforms to OtherWebClient. Android proto platform types collapse to OtherWebClient/Chrome mapping changes described below.
Pairing QR and pair-code logic & tests
wacore/src/pair.rs, wacore/src/pair_code.rs
Tests and assertions updated: Android proto types (AndroidPhone/AndroidTablet/AndroidAmbiguous) expect Chrome wire byte ('1') when derived from DeviceProps; unknown proto now uses '9'. pair_code.rs refactored with build_id_and_display to centralize props→(id,display) derivation and updated tests to reflect new mappings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly indicates the main changes: Android PlatformType mapping to Chrome and removal of Unknown variant, with breaking change notation (!). Directly reflects the core modifications.
Description check ✅ Passed Description thoroughly explains the rationale behind changes: server rejection of Android-specific bytes, empirical testing results, API implications, and refactoring work. Directly aligned with changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pair-android-maps-to-chrome

Comment @coderabbitai help to get the list of available commands and usage tips.

Drop test docstrings that just rephrase the test name, drop the
DRY-explanation on `build_id_and_display`, and shorten the doc on
`companion_web_client_type_for_platform` and the enum to keep just the
attestation/server-rejection rationale.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
wacore/src/pair_code.rs (1)

733-785: ⚠️ Potential issue | 🟡 Minor

Tighten this allow-list or the regression gets too soft.

SERVER_ACCEPT_LIST still admits '0' and the Android letters, and KNOWN_LABELS still admits Android. So this test can keep passing even if auto-derived mapping slips back to values this PR is explicitly moving away from. For the derived path, lock it to browser labels and '1'..'9'.

Suggested test tightening
-        const SERVER_ACCEPT_LIST: &[u8] = b"0123456789abcdefghijklm";
-        const KNOWN_LABELS: &[&str] = &[
-            "Chrome", "Edge", "Firefox", "IE", "Opera", "Safari", "Android",
-        ];
+        const DERIVED_WIRE_BYTES: &[u8] = b"123456789";
+        const KNOWN_LABELS: &[&str] = &[
+            "Chrome", "Edge", "Firefox", "IE", "Opera", "Safari",
+        ];
@@
-                SERVER_ACCEPT_LIST.contains(&id.wire_byte()),
-                "{pt:?} wire byte {:?} outside server accept list",
+                DERIVED_WIRE_BYTES.contains(&id.wire_byte()),
+                "{pt:?} wire byte {:?} outside derived allow-list",
                 id.wire_byte() as char,
             );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wacore/src/pair_code.rs` around lines 733 - 785, The test
derive_display_uses_known_label_for_every_proto_variant is too permissive:
update SERVER_ACCEPT_LIST and KNOWN_LABELS used in that test so the derived path
is locked to browser labels and the wire bytes '1'..'9' only; specifically,
change SERVER_ACCEPT_LIST to only allow bytes for '1' through '9' and remove
non-browser entries such as "Android" from KNOWN_LABELS (keep only "Chrome",
"Edge", "Firefox", "IE", "Opera", "Safari"), leaving the rest of the assertions
(derive_companion_platform, props(...) and the trailing " (Linux)" check)
unchanged.
wacore/src/companion_reg.rs (1)

15-55: 🛠️ Refactor suggestion | 🟠 Major

Move the wire bytes onto the enum definition.

This is still a wire-facing enum with a separate wire_byte() match, which leaves the source of truth split right where this PR is changing the public variants. Derive WireEnum and put the byte on each variant so the wire contract can't drift from the enum.

As per coding guidelines, "Every protocol enum must use #[derive(WireEnum)]; the #[wire = \"...\"] or #[wire = NUM] attribute is the single source of truth for each variant's wire value; do not also derive serde::Serialize/Deserialize or add #[serde(rename_all)]."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wacore/src/companion_reg.rs` around lines 15 - 55, Convert this into a true
wire enum: add #[derive(WireEnum)] to CompanionWebClientType, annotate each
variant with the per-variant wire attribute (e.g. #[wire = "1"] for Chrome, "2"
for Edge, "3" for Firefox, "4" for Ie, "5" for Opera, "6" for Safari, "7" for
Electron, "8" for Uwp, "9" for OtherWebClient, "d"/"e"/"f" for the Android
variants), then remove the manual wire_byte() impl so the wire mapping is
single-source-of-truth on the enum variants; keep the #[default] on
OtherWebClient and update any call sites that used
CompanionWebClientType::wire_byte() to use the WireEnum-provided accessor (or
the new canonical API).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@wacore/src/companion_reg.rs`:
- Around line 15-55: Convert this into a true wire enum: add #[derive(WireEnum)]
to CompanionWebClientType, annotate each variant with the per-variant wire
attribute (e.g. #[wire = "1"] for Chrome, "2" for Edge, "3" for Firefox, "4" for
Ie, "5" for Opera, "6" for Safari, "7" for Electron, "8" for Uwp, "9" for
OtherWebClient, "d"/"e"/"f" for the Android variants), then remove the manual
wire_byte() impl so the wire mapping is single-source-of-truth on the enum
variants; keep the #[default] on OtherWebClient and update any call sites that
used CompanionWebClientType::wire_byte() to use the WireEnum-provided accessor
(or the new canonical API).

In `@wacore/src/pair_code.rs`:
- Around line 733-785: The test
derive_display_uses_known_label_for_every_proto_variant is too permissive:
update SERVER_ACCEPT_LIST and KNOWN_LABELS used in that test so the derived path
is locked to browser labels and the wire bytes '1'..'9' only; specifically,
change SERVER_ACCEPT_LIST to only allow bytes for '1' through '9' and remove
non-browser entries such as "Android" from KNOWN_LABELS (keep only "Chrome",
"Edge", "Firefox", "IE", "Opera", "Safari"), leaving the rest of the assertions
(derive_companion_platform, props(...) and the trailing " (Linux)" check)
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 20aac55d-2839-4a11-bc70-af1547169585

📥 Commits

Reviewing files that changed from the base of the PR and between b79a9c5 and 933e764.

📒 Files selected for processing (3)
  • wacore/src/companion_reg.rs
  • wacore/src/pair.rs
  • wacore/src/pair_code.rs

@jlucaso1 jlucaso1 merged commit 4b8835b into main Apr 27, 2026
11 of 12 checks passed
@jlucaso1 jlucaso1 deleted the fix/pair-android-maps-to-chrome branch April 27, 2026 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant