Skip to content

Session Configuration and Connection Lifecycle

星冉 edited this page Jul 21, 2026 · 1 revision

Session Configuration and Connection Lifecycle

中文 · Runtime Main Path

This page defines ownership for persisted configuration, device capabilities, connection candidates, the active session, and resources from one scrcpy connection attempt. Its goal is to prevent field-by-field mirrors, preferred addresses overriding the actual connection, and partially cleaned runtimes.

Ownership model

Data Owner Lifetime
Saved session record SessionData / SessionRepository Persistent
User-editable scrcpy configuration ScrcpyConfig Persistent session
Automatically detected codec capability DeviceCapabilityCache Cache invalidated by device identity
Connection strategy List<ConnectionCandidate> Persisted, with priority adjusted from results
Current runtime snapshot ScrcpyOptions Active session
Active session SessionManager.activeSession From start through cleanup
Mutable runtime state and reconnect budget SessionRuntimeState Internal to Session
Winning ADB object Session.adbConnection Active session
Attempt tying SCID, tunnel, and sockets together ActiveScrcpyConnection One connection attempt

SessionData.toScrcpyOptions() reuses the complete ScrcpyConfig, capability cache, and candidate list instead of maintaining a second field-by-field configuration. ScrcpyOptions requires at least one candidate. After ADB wins, Session.deviceIdentifier comes from the actual connection; only before that does it fall back to the preferred candidate identity.

Configuration and capability rules

  • ScrcpyConfig expresses user intent only, including display, media, control, and ScrcpyTunnelMode.
  • DeviceCapabilityCache represents remote encoders and final automatic selections only; changing the device serial resets it as a whole.
  • Explicit user choices outrank automatic cache values. The cache is used only when the choice is empty.
  • Codec detection and temporary decoder fallback must not silently rewrite user selections.
  • Profiles should apply complete configuration semantics instead of a partial field map that can drift.

Tunnel modes:

  • DIRECT_ADB: open the remote localabstract stream directly and adapt it as a socket.
  • ADB_FORWARD: create an ADB forward from local TCP to the remote localabstract socket.

Candidate race

raceAdbConnections may attempt different ADB candidates concurrently. This is separate from the rule that scrcpy sockets must connect sequentially.

  • The race layer owns candidate deduplication, the USB preference window, winner selection, and loser cleanup.
  • AdbConnectionManager owns per-device locking, the connection pool, and TCP/mDNS/USB routing.
  • The connector returns the actual AdbConnection; server startup, monitoring, control, and cleanup all use that same winning object.
  • Persisted candidates may record success time and failure count to influence later ordering, but a “preferred candidate” must never masquerade as the connected device for this run.

One scrcpy attempt

ActiveScrcpyConnection freezes the sessionId, actual adbConnection, local port, SCID, socket name, and tunnel mode. Cleanup must use this attempt snapshot instead of re-deriving resource identity from configuration that may have changed.

See Runtime Main Path for the full sequence. The sequential video → optional audio → control socket order is an invariant of the protocol.

Reconnection

  • The session's single event Channel serializes reconnect requests. Duplicates are ignored while state is Reconnecting or Failed.
  • Reconnect budget exists only in SessionRuntimeState. Its limit comes from ScrcpyConstants.MAX_RECONNECT_ATTEMPTS (currently 3), not a UI-local counter.
  • Entering SessionState.Connected immediately resets the budget, so a later outage starts from attempt one.
  • Reconnection rebuilds the scrcpy server, tunnel, sockets, and media path. The ADB object is reused only while healthy.
  • Temporary decoder-size recovery changes maxSize only for the current session and does not persist it.

Explicit cancellation and cleanup

Explicit stop and failure-triggered reconnection have different semantics:

  1. Cancel pending reconnect or connection work.
  2. Process RequestCleanup so the session deterministically reaches Idle and clears component state.
  3. Stop media, health monitoring, and the controller.
  4. Under the lifecycle mutex, close sockets and shell resources, remove the forward, and terminate the server for the current SCID.
  5. Stop session monitoring and event processing and release session references.

When connection work is cancelled, created scrcpy resources are reclaimed in a NonCancellable region before CancellationException continues upward. Do not record user cancellation as an ordinary failure, and do not require a generated device id before cleanup can run.

Connection-close logging

EOF, socket/stream closed, connection reset, broken pipe, closed channel, and classified ADB-close exceptions are disconnection signals. They should produce a concise reason and enter the unified policy. Protocol corruption, malformed packets, MediaCodec failures, and unknown I/O errors should retain complete diagnostics.

Regression requirements

  • The winning candidate object is the one used by the session, server, monitoring, and control.
  • Exiting during connection leaves no session, server, forward, or sockets and does not start background reconnection.
  • Reconnect budget resets after every successful recovery; the next outage starts at attempt one.
  • Each rebuild creates a new SCID and preserves protocol socket order.
  • Disconnection events caused by explicit closure do not start another reconnect.
  • Tests for configuration saving, candidate policy, racing, socket order, close classification, and codec fallback remain green.

Clone this wiki locally