Files
Xime/CLIPBOARD_SYNC_PLAN.md
2026-06-09 14:40:20 +08:00

7.2 KiB

Clipboard Sync Implementation Plan

1. Goal and Scope

Build clipboard synchronization between the Android input method in Xime/ and the Windows input method in winxime/, using a Docker-deployable HTTPS relay server.

MVP scope:

  • Sync text clipboard content only.
  • Devices join the same sync chain by entering a sync code.
  • Remote content is written to the local system clipboard, equivalent to a user copy action.
  • Android additionally exposes received synced text in the IME candidate bar so users can commit it directly.
  • Users can enable/disable sync in settings and must configure an HTTPS relay server URL.

Out of MVP scope:

  • Image/file/rich-text clipboard sync.
  • Automatic paste into the currently focused field.
  • Multi-user administration UI.
  • Cloud-hosted default relay.

2. Repository Layout Proposal

Add a new backend service at workspace root:

sync-server/
  Dockerfile
  docker-compose.yml
  src/
  README.md

Client integrations:

  • Android: Xime/app/src/main/java/com/kingzcheung/xime/settings, service, clipboard, and ui.
  • Windows: winxime/crates/winxime-server for clipboard watching, WebSocket sync, and local clipboard writes.
  • Shared protocol docs: CLIPBOARD_SYNC_PROTOCOL.md or sync-server/docs/protocol.md.

3. Core Product Rules

  • A sync chain is a group of devices allowed to exchange clipboard events.
  • A sync code authorizes a device to join a chain. It must be random, revocable, and regeneratable.
  • The server must reject non-HTTPS client relay URLs. For local development, allow explicit debug-only overrides such as http://localhost.
  • Every synced item must be inserted into the local clipboard and local clipboard history where the platform/app supports it.
  • Android must show the latest remote synced text in the candidate bar. Tapping it should commit the text through the IME.
  • Sync must be opt-in and pauseable per device.

4. Architecture

Use HTTPS REST for setup and WSS for live sync:

Android Xime  <--- HTTPS/WSS --->  Sync Relay Server  <--- HTTPS/WSS --->  WinXime

The server is a relay, not an editor. It authenticates devices, tracks sync chains, forwards clipboard events, and keeps short-lived replay data for reconnects.

Recommended backend stack:

  • Rust with tokio, axum, tower, serde, and sqlx/SQLite for a small self-hosted binary.
  • Docker image exposing one port, with TLS handled either by the service or by a reverse proxy such as Caddy/Nginx.
  • WebSocket heartbeat, reconnect support, and event replay by last acknowledged sequence.

5. Protocol and Data Model

REST endpoints:

GET  /healthz
POST /v1/chains
POST /v1/chains/join
POST /v1/chains/{chainId}/sync-code/rotate
GET  /v1/ws

Minimum tables/entities:

chains(id, code_hash, code_expires_at, created_at)
devices(id, chain_id, name, platform, token_hash, last_seen_at)
clipboard_events(id, chain_id, source_device_id, seq, content_type, content_hash, encrypted_payload, created_at, expires_at)

WebSocket event shape:

{
  "type": "clipboard.publish",
  "eventId": "uuid",
  "chainId": "uuid",
  "sourceDeviceId": "uuid",
  "sequence": 42,
  "contentType": "text/plain",
  "contentHash": "sha256:...",
  "payload": "base64 encrypted or encoded text",
  "createdAt": "2026-06-09T00:00:00Z",
  "ttlSeconds": 86400
}

Client requirements:

  • Ignore events from the same deviceId.
  • Cache recent eventId and contentHash values to prevent duplicate imports.
  • Suppress the next local clipboard-change callback after writing a remote event to avoid echo loops.
  • Limit payload size, for example 64 KiB for MVP.

6. Security Requirements

  • Relay URL validation must require https://; WebSocket connections must use wss://.
  • Store only token hashes and sync code hashes on the server.
  • Use TLS in all production deployments.
  • Prefer end-to-end encryption for clipboard payloads. At minimum, server-side event storage must be short-lived with a configurable TTL.
  • Sync codes should expire by default, for example after 10 minutes or after first successful join. Provide a manual rotate/revoke action.
  • Never log raw clipboard content on clients or server.

7. Android Implementation Plan

  1. Add settings fields: enable sync, relay server URL, sync code, device name, connection status, pause/resume, and disconnect.
  2. Persist config in SettingsPreferences.kt or a dedicated sync preferences class.
  3. Add a ClipboardSyncClient responsible for HTTPS join, WSS connection, heartbeats, reconnects, and event acknowledgements.
  4. Add a clipboard bridge that publishes local text copies and writes remote text via Android ClipboardManager.
  5. Add a local synced-item state source consumed by CandidateBar.kt or the relevant keyboard UI layer.
  6. When remote text arrives, update system clipboard and display it as a candidate. Tapping the candidate commits the text.
  7. Add unit tests for URL validation, dedupe, echo-loop suppression, and event parsing.

8. Windows Implementation Plan

  1. Add sync configuration to the existing Windows settings/config layer.
  2. Implement a WebSocket sync client inside winxime-server.
  3. Watch local clipboard changes from the server process and publish text changes.
  4. Write remote text into the Windows clipboard using the existing server/background process.
  5. Prevent loops by tagging remote writes and suppressing the resulting local notification.
  6. Surface connection status in tray/setup UI if practical.
  7. Validate with cargo build --quiet; do not use unwrap() or expect().

9. Backend Implementation Plan

  1. Scaffold sync-server with health check, config loading, structured logging, and Dockerfile.
  2. Implement chain creation, sync-code join, device token issuance, and code rotation.
  3. Implement authenticated WebSocket sessions with heartbeat and reconnect.
  4. Implement event fan-out to online devices in the same chain.
  5. Persist recent events for replay after reconnect, bounded by TTL and size limits.
  6. Add Docker Compose example with a reverse proxy HTTPS configuration.
  7. Add integration tests for join, auth failure, event fan-out, replay, TTL expiry, and duplicate suppression expectations.

10. Acceptance Criteria

  • A user can deploy the relay with Docker and access it over HTTPS.
  • Android and Windows settings reject plain http:// relay URLs outside debug/local mode.
  • Device A can create or rotate a sync code; Device B can join using that code.
  • Copying text on Windows updates Android clipboard and shows the text in the Android candidate bar.
  • Copying text on Android updates the Windows clipboard.
  • The same event is not re-broadcast indefinitely.
  • Reconnect after network loss resumes sync without requiring a new sync code.
  • Raw clipboard content does not appear in logs.

11. Implementation Order for Agents

  1. Protocol agent: finalize event schema, sync-code lifecycle, error codes, and protocol doc.
  2. Backend agent: implement relay, Docker image, tests, and deployment README.
  3. Windows agent: implement local clipboard watcher/writer and WSS client.
  4. Android agent: implement settings, WSS client, clipboard bridge, and candidate bar display.
  5. Integration agent: run end-to-end tests across one Android device/emulator, one Windows client, and the Docker relay.