Skip to content

Expose core StreamConnectionState as the public connection state (breaking)#1739

Merged
aleksandar-apostolov merged 3 commits into
develop-v2from
gsd/phase-2-03-connectionstate-rewrite
Jul 14, 2026
Merged

Expose core StreamConnectionState as the public connection state (breaking)#1739
aleksandar-apostolov merged 3 commits into
develop-v2from
gsd/phase-2-03-connectionstate-rewrite

Conversation

@aleksandar-apostolov

@aleksandar-apostolov aleksandar-apostolov commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Goal

Refs AND-1283

⚠ Breaking public API change. Removes the video-owned ConnectionState entirely — ClientState.connection now exposes core's StreamConnectionState directly, the same pattern the Feeds SDK uses (FeedsClient.state). No copy, no mapper, no drift risk.

Depends on #1738 (StreamClient wiring). Merge after parent.

Implementation

  • ClientState.connection becomes StateFlow<StreamConnectionState>; handleStreamState is a plain assignment fed by the StreamClient listener (onState).
  • Deleted: the ConnectionState sealed interface, ConnectionStateMapper + mapping test, and the dead legacy paths (handleState(VideoSocketState), handleError, the ConnectedEvent branch — core consumes the auth event internally).
  • XML app bar renderState(...) signatures move to the core type (pass-through, no behavior change).
  • API dump: pure deletion — 44 lines leave stream-video-android-core.api; the connection-state surface now ships in stream-android-core.

Testing

  • ./gradlew :stream-video-android-core:testDebugUnitTestClientStateTest asserts every reported core state is published unchanged; ClientAndAuthTest / AndroidDeviceTest assertions moved to the core type.
  • ./gradlew apiCheck spotlessCheck

Summary by CodeRabbit

  • Breaking Changes

    • Replaced the legacy connection-state model with the unified stream connection state across client and XML call app bar APIs.
    • Removed the public error-handling method from the client state interface.
    • Connection state is now exposed directly, including idle, connecting, connected, reconnecting, and disconnected states.
  • Bug Fixes

    • Improved propagation of connection-state updates from the stream client to observable client state.
    • Updated call UI components to reflect the unified connection state consistently.
  • Tests

    • Added coverage for connection-state propagation and direct state updates.

@aleksandar-apostolov aleksandar-apostolov added the pr:breaking-change API-breaking or behavioral change label Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-video-android-core 12.05 MB 12.35 MB 0.30 MB 🟡
stream-video-android-ui-xml 5.68 MB 5.73 MB 0.05 MB 🟢
stream-video-android-ui-compose 6.28 MB 5.86 MB -0.43 MB 🚀

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The client replaces its local ConnectionState model with StreamConnectionState, routes listener updates directly into ClientState, updates tests, and changes XML app bar rendering contracts and implementations to use the shared state type.

Changes

Connection state unification

Layer / File(s) Summary
Core connection state contract
stream-video-android-core/api/stream-video-android-core.api, stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/ClientState.kt, stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/socket/coordinator/v2/ConnectionStateMapper.kt
Removes the public ConnectionState family and handleError, removes the state mapper, and exposes StreamConnectionState directly from ClientState, initialized to Idle.
State routing and validation
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt, stream-video-android-core/src/test/..., stream-video-android-core/src/androidTest/...
Routes StreamClientListener.onState through ClientState.handleStreamState and updates unit, device, connection, and RTC assertions to use the new state types.
XML app bar state contract
stream-video-android-ui-xml/api/..., stream-video-android-ui-xml/src/main/kotlin/io/getstream/video/android/xml/widget/appbar/...
Changes app bar renderState contracts and default content overrides from ConnectionState to StreamConnectionState.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant StreamClientListener
  participant StreamVideoClient
  participant ClientState
  StreamClientListener->>StreamVideoClient: onState(StreamConnectionState)
  StreamVideoClient->>ClientState: handleStreamState(state)
  ClientState->>ClientState: publish connection state
Loading

Suggested labels: pr:improvement

Suggested reviewers: PratimMallick

Poem

I’m a rabbit with states in a neat little stream,
No mapping maze remains in the dream.
Idle hops forward, Connected shines bright,
App bars now render the same state just right.
Tests twitch their noses: all flows take flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed It clearly summarizes the main breaking API change from video-owned ConnectionState to public StreamConnectionState.
Description check ✅ Passed The description covers the goal, implementation, and testing, and only omits some non-critical template sections like UI changes and checklist items.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gsd/phase-2-03-connectionstate-rewrite

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.

@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-03-connectionstate-rewrite branch 2 times, most recently from eda7d6c to 5b4832d Compare July 3, 2026 07:38
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-02-streamclient-rewrite branch from 092085e to a632706 Compare July 7, 2026 09:32
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-03-connectionstate-rewrite branch 2 times, most recently from f5c9138 to b01d2d2 Compare July 7, 2026 13:26
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-02-streamclient-rewrite branch from 97f4003 to fa2eeb2 Compare July 7, 2026 16:29
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-03-connectionstate-rewrite branch 5 times, most recently from c14482e to 5378836 Compare July 8, 2026 09:41
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-02-streamclient-rewrite branch from c761587 to 6ecf46f Compare July 9, 2026 08:39
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-03-connectionstate-rewrite branch 7 times, most recently from c55f56f to 05ef80c Compare July 9, 2026 12:36
@aleksandar-apostolov aleksandar-apostolov changed the title Mirror ConnectionState onto core StreamConnectionState (breaking) Expose core StreamConnectionState as the public connection state (breaking) Jul 9, 2026
@aleksandar-apostolov aleksandar-apostolov marked this pull request as ready for review July 10, 2026 07:48
@aleksandar-apostolov aleksandar-apostolov requested a review from a team as a code owner July 10, 2026 07:48
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-02-streamclient-rewrite branch from 11e6329 to d03a473 Compare July 10, 2026 07:50
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-03-connectionstate-rewrite branch from 393ef1f to c05d2f7 Compare July 10, 2026 07:50

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/ClientState.kt (1)

138-140: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding a debug log in handleStreamState for observability.

The class already has a logger (line 50). A one-line debug log would help trace connection-state transitions during development without leaking sensitive data (StreamConnectionState carries user IDs, not JWTs/ICE tokens).

♻️ Optional: add debug log
 internal fun handleStreamState(streamState: StreamConnectionState) {
+    logger.d { "[handleStreamState] $streamState" }
     _connection.value = streamState
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/ClientState.kt`
around lines 138 - 140, Add a one-line debug log at the start of
ClientState.handleStreamState using the existing logger, recording the incoming
StreamConnectionState to trace connection transitions without logging sensitive
credentials.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/ClientState.kt`:
- Around line 138-140: Add a one-line debug log at the start of
ClientState.handleStreamState using the existing logger, recording the incoming
StreamConnectionState to trace connection transitions without logging sensitive
credentials.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3c7aa3f2-6fdc-4b6e-879d-384aef18cd9b

📥 Commits

Reviewing files that changed from the base of the PR and between 11e6329 and 393ef1f.

📒 Files selected for processing (16)
  • stream-video-android-core/api/stream-video-android-core.api
  • stream-video-android-core/src/androidTest/kotlin/io/getstream/video/android/core/AndroidDeviceTest.kt
  • stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/ClientState.kt
  • stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
  • stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/socket/coordinator/v2/ConnectionStateMapper.kt
  • stream-video-android-core/src/test/kotlin/io/getstream/video/android/core/ClientAndAuthTest.kt
  • stream-video-android-core/src/test/kotlin/io/getstream/video/android/core/ClientStateConnectionMappingTest.kt
  • stream-video-android-core/src/test/kotlin/io/getstream/video/android/core/ClientStateTest.kt
  • stream-video-android-core/src/test/kotlin/io/getstream/video/android/core/StreamVideoClientTest.kt
  • stream-video-android-core/src/test/kotlin/io/getstream/video/android/core/rtc/RtcSessionTest.kt
  • stream-video-android-ui-xml/api/stream-video-android-ui-xml.api
  • stream-video-android-ui-xml/src/main/kotlin/io/getstream/video/android/xml/widget/appbar/CallAppBarContent.kt
  • stream-video-android-ui-xml/src/main/kotlin/io/getstream/video/android/xml/widget/appbar/CallAppBarView.kt
  • stream-video-android-ui-xml/src/main/kotlin/io/getstream/video/android/xml/widget/appbar/internal/DefaultCallAppBarCenterContent.kt
  • stream-video-android-ui-xml/src/main/kotlin/io/getstream/video/android/xml/widget/appbar/internal/DefaultCallAppBarLeadingContent.kt
  • stream-video-android-ui-xml/src/main/kotlin/io/getstream/video/android/xml/widget/appbar/internal/DefaultCallAppBarTrailingContent.kt
💤 Files with no reviewable changes (3)
  • stream-video-android-core/src/test/kotlin/io/getstream/video/android/core/ClientStateConnectionMappingTest.kt
  • stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/socket/coordinator/v2/ConnectionStateMapper.kt
  • stream-video-android-core/api/stream-video-android-core.api

@rahul-lohra

rahul-lohra commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Nice PR. @aleksandar-apostolov

Low priority:
Stale Baseline Prof text Detected
stream-video-android-core/src/main/baseline-prof.txt:129
and demo-app/src/main/generated/baselineProfiles/baseline-prof.txt:27791 still reference io/getstream/video/android/core/ConnectionState

Base automatically changed from gsd/phase-2-02-streamclient-rewrite to develop-v2 July 13, 2026 10:23

@rahul-lohra rahul-lohra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

…tate

Delete the video-owned ConnectionState sealed interface instead of
reshaping it into a 1:1 mirror of core's StreamConnectionState: a
mirror forbidden from diverging is pure maintenance (copy + mapper +
mapping tests + drift risk) with no insulation benefit, since core is
already an api() dependency. The Feeds SDK sets the precedent — its
FeedsClient.state exposes StreamConnectionState directly, so both
core-v5 SDKs now surface the same connection state type.

ClientState.connection becomes StateFlow<StreamConnectionState>, fed by
handleStreamState as a plain assignment from the StreamClient listener.
Delete the dead legacy paths (handleState(VideoSocketState),
handleError, the ConnectedEvent branch — core consumes the auth event
internally) and ConnectionStateMapper with its mapping test. XML appbar
renderState signatures and the connection assertions in
ClientAndAuthTest, AndroidDeviceTest and RtcSessionTest move to the
core type; RtcSessionTest's assertion also switches to
RealtimeConnection, the type call.state.connection actually is.
Pure deletion: the video ConnectionState surface (44 lines) leaves the
dump; the public connection state now comes from stream-android-core.
The deletion-heavy diff leaves ~4 new lines, so the single uncovered
one (the onState body) fails Sonar's 80% new-code gate on its own.
@aleksandar-apostolov aleksandar-apostolov force-pushed the gsd/phase-2-03-connectionstate-rewrite branch from c05d2f7 to ca4f3d9 Compare July 14, 2026 14:52
@sonarqubecloud

Copy link
Copy Markdown

@aleksandar-apostolov aleksandar-apostolov merged commit 35e5836 into develop-v2 Jul 14, 2026
17 of 18 checks passed
@aleksandar-apostolov aleksandar-apostolov deleted the gsd/phase-2-03-connectionstate-rewrite branch July 14, 2026 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:breaking-change API-breaking or behavioral change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants