Skip to content

fix(mobile): show the update screen instead of native screens when the desktop has no page - #29956

Merged
Jinwoo-H merged 3 commits into
mainfrom
jinwoo/ota-wall-instead-of-native-fallback
Oct 17, 2026
Merged

Jinwoo-H merged 3 commits into
mainfrom
jinwoo/ota-wall-instead-of-native-fallback

Conversation

@Jinwoo-H

@Jinwoo-H Jinwoo-H commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 17 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​231 $\color{#cf222e}{\Huge{\mathbf{−}}}$​125 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​106
Prod 27 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​176 $\color{#cf222e}{\Huge{\mathbf{−}}}$​168 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​8

What changes for users

New phone builds only. When the paired desktop cannot provide the mobile workspace page, the phone now shows the existing "Update Orca on your computer" screen instead of opening the old native screens.

Desktop Today After
v1.4.218+ (page meets floor) page page (unchanged)
v1.4.206 to v1.4.217 (page below floor) "desktop too old" screen same (unchanged)
no page (older than v1.4.206, orcad before #29882, dev builds without out/mobile-web) native screens "desktop too old" screen

Both blocked cases now use one message, the existing desktop-too-old body. The separate "does not include the mobile workspace yet" body is deleted. Title stays "Update Orca on your computer".

Why

The OTA plan decided there is no native fallback: a host that cannot serve the page gets the update screen (docs/reference/plans/mobile-ota-phase-a.local.md). Step 0 (#29882, orcad servers ship the page) has merged. This PR is step 1a, the behaviour change only. Step 1b deletes the native screens that are now unreachable.

Release ordering: the desktop release that contains #29882 must ship before any phone build that contains this PR. Otherwise users paired to an orcad server get the update screen with no update available.

Design choices

  • Where the fallback was chosen. Three places now answer differently:
    • the gate (gateVerdict): bundle-unavailable is a wall like every other blocked verdict;
    • the manifest check (onManifestRead): a route the page does not serve is a wall. The compat check now runs first, so a page below the floor is always "desktop too old" even when it lacks the route. The route wall says which side is behind. If a shell with every grant would serve the route, the page needs a grant this app lacks (page-route-grant-missing, "Update Orca Mobile"). Otherwise the desktop's page predates the screen (page-route-unlisted, the shared desktop copy);
    • the cached-generation path (openByOwnRoutes): a cached bundle that lacks the route now gets a screen the caller picks. Offline it is the existing offline screen ("Connect to this host to download the latest app"), the same answer as having no cache. A host we cannot reach cannot be judged too old, and reconnecting restarts the flow. After a failed download it is the download-failed screen with Try again, because the newer manifest claimed the route (or never arrived), so the failure belongs to the download.
  • native-route removed. Nothing produces it any more, so the state kind and the shell's fallback prop are gone from MobileWebShellScreen and from every route call site, including web.tsx's redirect. Each switch keeps its native element only for the native-shell build path (shellSwitchDecision), which step 1c removes. The saved native-route update-failure outcome still parses, so older records read.
  • Unknown screens are not blamed on the desktop. The catch-all route (a host path this app has no screen for, like a stale deep link) and a manifest pattern this phone cannot parse keep the old message, "This workspace screen is not available on this host.", instead of the desktop-too-old wall. Smallest shape: one state with no payload, route-unavailable, which the shell renders as that screen. The catch-all opts in with appNamesRoute={false}. Known page routes that an older desktop doesn't list still show desktop-too-old.
  • Wide layouts (accepted). The host-area check (canOwnHostArea, added in v1.4.225) used to leave wide sessions native under an older page. It now walls them. iPad and foldable users paired to a v1.4.218 to v1.4.224 desktop see "Update Orca on your computer", which is true. Raising the page floor instead would be wrong, because MOBILE_WEB_PAGE_VERSION is still 1 on current desktops. Phones are not affected.
  • Diagnostics: two new wall codes and a route-unavailable outcome, with copy in Troubleshoot. The persisted native-route outcome is kept so older records still parse.

Mixed versions

The change is phone-only, with no wire change. Installed apps behave as before. Desktops are unaffected.

Testing

  • Unit: reducer (no bundle, unlisted route, missing grant, no routes field, schema/floor ordering, unknown path, unparseable pattern, recovery, retry, gates change), offline and refused-update decisions, wide layout, failure records, lifecycle log, shell screen, catch-all states, and ProtocolBlockScreen copy. All 23 changed or new cases fail against main's source.
  • Mobile tsc --noEmit, pnpm lint, oxfmt --check, full mobile vitest (10804 passed), root mobile-web script tests, pnpm run check:code-quality:changed.
  • Real app: release APK (EXPO_PUBLIC_MOBILE_SHELL=ota, change confirmed in the Hermes bundle) on an Android emulator against three isolated orca-dev serve hosts:
    • current host: page loads (WebView present);
    • host with out/mobile-web absent: wall with the shared copy. Both "Back to hosts" and system Back return to the host list, and re-entering shows the wall again;
    • v1.4.217 host (manifest has no pageVersion): same wall.
    • Control: the main APK against the no-page host opens native screens.
    • Re-run with an APK rebuilt after the review changes: the current host loads the page, and the no-page host shows the wall with Back returning to the host list.
Before (main APK, no-page host: native screen) After (this PR, no-page host: wall)
before after
After, v1.4.217 host After, current host (page) After, "Back to hosts"
v217 current back

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 004a7530-aa55-4f12-9e61-db4cbecf6795
📥 Commits

Reviewing files that changed from the base of the PR and between a753e6c and bcee891.

📒 Files selected for processing: 1
  • mobile/src/mobile-web-shell/page-route-policy.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

📝 Walkthrough

The mobile web shell now uses wall states for unsupported bundles and page routes, and a route-unavailable state when the app does not name a route. The shell renders an unavailable-route screen instead of returning a caller-provided native fallback. Route policy, session decisions, update-failure outcomes, lifecycle logs, route entry points, and tests were updated to use these states.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to bcee8

The reviewed route-refusal change has both policy-level and session-level coverage; no actionable merge risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 59.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 37 functions across 41 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: showing the update screen instead of native screens when the desktop has no page.
Description check Passed The description thoroughly explains the user impact, design decisions, compatibility behavior, testing, release ordering, and visual results. It does not include the template's explicit Linked Issue, …
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.
Full details: Description check

Explanation

The description thoroughly explains the user impact, design decisions, compatibility behavior, testing, release ordering, and visual results. It does not include the template's explicit Linked Issue, ELI5, or checklist sections, but the required change information is otherwise substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Jinwoo-H
Jinwoo-H merged commit b2419a5 into main Oct 17, 2026
34 checks passed
@Jinwoo-H
Jinwoo-H deleted the jinwoo/ota-wall-instead-of-native-fallback branch October 17, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant