Correctly update Ringing State on CallEnded event#1621
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
WalkthroughRefactoring of the CallState class to consolidate logging through a structured per-module logger (ringingLogger) and augment ringing state logic with call-ended state awareness, enabling proper state transitions when calls end. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt (1)
1261-1262: MoveringingLoggerto a class-level property to avoid recreating the delegate wrapper on everyupdateRingingState()call.The local delegated
val ringingLogger by taggedLogger("RingingState")at line 1261 creates a new delegate wrapper object on each invocation. SinceupdateRingingState()is called frequently (at least 7+ times across state changes: accepted/rejected events, member updates, session changes, etc.), this incurs unnecessary allocation overhead.Follow the existing pattern used for
loggerat line 226:private val logger by taggedLogger("CallState") +private val ringingLogger by taggedLogger("RingingState")Then remove the local declaration at line 1261.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt` around lines 1261 - 1262, Declare a class-level property for the logger instead of recreating it inside updateRingingState(): move the local delegated val ringingLogger by taggedLogger("RingingState") to a top-level property in the class (mirroring the existing logger declaration used at line 226) and then remove the local declaration inside updateRingingState(); update usages in updateRingingState() to reference the new class-level ringingLogger to avoid repeated delegate-wrapper allocations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt`:
- Around line 1280-1282: The isCallEnded branch in updateRingingState()
transitions to RingingState.RejectedByAll but omits call.leave(), causing
resources to leak when updateRingingState() is invoked from other paths
(updateFromResponse, getOrCreateMembers, CallSessionParticipantJoinedEvent);
modify the isCallEnded branch in updateRingingState() to call call.leave(...)
with a clear reason (e.g., "updateRingingState-ended") prior to cancelTimeout(),
mirroring the other rejection branches so call.leave() is always invoked before
returning RingingState.RejectedByAll.
---
Nitpick comments:
In
`@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt`:
- Around line 1261-1262: Declare a class-level property for the logger instead
of recreating it inside updateRingingState(): move the local delegated val
ringingLogger by taggedLogger("RingingState") to a top-level property in the
class (mirroring the existing logger declaration used at line 226) and then
remove the local declaration inside updateRingingState(); update usages in
updateRingingState() to reference the new class-level ringingLogger to avoid
repeated delegate-wrapper allocations.
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt
Outdated
Show resolved
Hide resolved
SDK Size Comparison 📏
|
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt
Show resolved
Hide resolved
|
|
🚀 Available in v1.20.0 |




Goal
Correctly update
RingingStateonCallEndedeventBackground: When an incoming call is declined by the caller via
call.end()rather thancall.reject(), the callee currently transitions fromRingingState.IncomingtoRingingState.Idle. This change corrects the transition toRingingState.RejectedByAll.Implementation
Used
call.endedAtto determine if call has been ended🎨 UI Changes
Before
Screen.Recording.2026-02-20.at.6.39.14.PM.mov
After
Screen.Recording.2026-02-20.at.6.34.22.PM.mov
Testing
call.reject()in StreamActivity.cancel() withcall.endto reproduce this behaviour.Summary by CodeRabbit