Skip to content

sync(harmonyos): bring remote-control updates to 1.0.0-explore - #2378

Merged
wgqqqqq merged 11 commits into
GCWing:1.0.0-explorefrom
wgqqqqq:sync/harmonyos-remote-control
Aug 19, 2026
Merged

sync(harmonyos): bring remote-control updates to 1.0.0-explore#2378
wgqqqqq merged 11 commits into
GCWing:1.0.0-explorefrom
wgqqqqq:sync/harmonyos-remote-control

Conversation

@wgqqqqq

@wgqqqqq wgqqqqq commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • sync the latest HarmonyOS account device directory and per-device workspace browsing
  • preserve workspace-scoped session creation and bound unreachable desktop switches
  • add HarmonyOS Chinese/English locale switching and fold-aware sheet placement
  • carry the ArkTS SDK error-handling cleanup and related focused tests/design docs

Scope

This cherry-picks only the 10 HarmonyOS commits that are missing from 1.0.0-explore. The unrelated CLI app-server host, workspace search, usage, and other main-only changes are intentionally excluded.

Verification

  • pnpm run harmony:architecture
  • source scripts/ohos-env.sh && "$HVIGORW" --mode module -p product=default -p module=entry@default assembleHap --no-daemon
  • source scripts/ohos-env.sh && "$HVIGORW" --mode module -p module=entry@default -p ohos.test.type=LocalTest test --no-daemon
  • git diff --check upstream/1.0.0-explore..HEAD

The current project produced an unsigned HAP because signing configuration is intentionally local and absent from the repository, so this branch was not installed for real-device UI verification.

wgqqqqq and others added 10 commits August 19, 2026 15:42
ArkTS only treats catch as handling SDK-throwing APIs. Convert BusinessError
at each call site, declare the crypto NAPI types, and replace the deprecated
voice capturer read path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Creating a session in a workspace other than the open one first sent
set_workspace, so the phone moved the desktop's own view before the create
landed. CreateSession already binds whatever workspace_path it is handed, so
that round trip bought nothing and cost the desktop its place — harmless
enough with one machine in view, wrong once the sidebar lists several.

Carrying the path on CreateSessionOptions collapses the three-branch dance
around it, along with the recovery path that existed only to undo a host
workspace this no longer touches.

Co-authored-by: Cursor <cursoragent@cursor.com>
The remote surface only ever faced one machine: the workspace section drew
the desktop the phone was currently driving, and reaching another one meant
moving the global control target, which took the first one out of view. A
console that can only see where it happens to be pointed is not a console.

deviceRpc is already stateless — every call carries the relay URL, session
and target device — so a read-only directory can fan out without touching
RemoteSessionManager's single transport, which still owns the conversation.
Expanding a device is what dials it; offline rows are never dialed at all,
which is what keeps opening the drawer off a row of 130s timeouts.

Each device gets its own SidebarDeviceGroup because SessionListProjectionCache
holds a single slot keyed on the workspace, so one instance serving N devices
would miss on every rebuild. Catalogs persist per device_key and the live
device's own catalog is captured on publish, so a device keeps its rows after
the control target moves on.

Co-authored-by: Cursor <cursoragent@cursor.com>
Scoped to the HarmonyOS app: what was verified against main, why the
observation surface fans out per device while the conversation surface stays
on one, and why cross-device execution status is out of reach until the
remote SessionInfo payload carries a status field at all.
…ooked at

Device presence was fetched once at cold start and never again. The relay
keeps presence in a live socket registry, so its answer is current whenever
it is asked — the phone simply stopped asking, and a desktop that came
online after launch stayed grey in the sidebar until the app was killed.

Returning to the foreground and opening the sidebar each refetch, with a
15s freshness window so the two firing together on a cold start cost one
request rather than three.
Tapping a session on another desktop tears the current link down before
dialling the new one, so a desktop that has gone away used to cost the user
both machines for two minutes: AccountDeviceCommandTransport dropped the
caller's timeout on the floor and always took deviceRpc's hardcoded 130s,
nothing on screen said a switch was underway, and when it finally failed the
phone was left on no device at all with polling and the heartbeat stopped.

The timeout now travels from the transport through to deviceRpc, and the
connect handshake passes 15s of its own — a desktop that is running answers
get_workspace_info from memory, so silence there means it is gone, not busy.
The switch seam shows a toast, and a failed dial restores the device it
started from, snapshotting it before the teardown makes it unreadable.

Also from the same round on the device: the active desktop rendered grey
because the ForEach key for the unpaired placeholder collided with the real
row for that same machine, freezing the child on an object nothing updates;
and a live link now outranks the relay's presence answer, which is hearsay
from a socket registry that lags. Verified against two desktops, the failure
path reproduced by freezing one so the relay kept reporting it online.
The phone decides; it never executes. Detached Dispatch already has the
shape this needs — the phone remote-controls A, A is the controller that
owns the Git baseline, and B is the target that runs the worker. What was
missing was never authority, only an entry point on the phone.

So the design is written as a checklist of decisions, not of features: for
every decision the desktop can make about a job, the phone needs a verb,
and every desktop command left out has to say why it is work rather than a
decision. What cannot travel is the conversation — the submit request
carries no history, on any client — and that boundary is stated rather
than papered over.
The in-app language never changed because RemoteI18n only had a
hardcoded zh-CN map and no locale state. Keep catalogs, persistence,
and Settings selection on the phone so the current surface rebuilds
immediately after a switch.

Co-authored-by: Cursor <cursoragent@cursor.com>
Settings and the other overlay sheets now share a crease-aware policy so
they stay in one physical pane instead of centering across a hinge.
Settings subpages and local-model drafts survive fold rebuilds, and the
home list groups language and model under General.

Co-authored-by: Cursor <cursoragent@cursor.com>
Mate X7 reports the book hinge as a wide-flat rect. Treating that
rect as both vertical and horizontal made hover open a short bottom
sheet instead of the trailing pane. Sheet options now use the kind
height, illegal creases no longer apply the tablet floor, and RTL
sizes the leading pane.

Co-authored-by: Cursor <cursoragent@cursor.com>
@wgqqqqq
wgqqqqq merged commit 50edd00 into GCWing:1.0.0-explore Aug 19, 2026
6 of 8 checks passed
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