-
Notifications
You must be signed in to change notification settings - Fork 56
Introduce connectOnInit flag to control initial WebSocket connection
#1595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Adds a new `autoConnect` boolean parameter to the `StreamVideoBuilder`, defaulting to `true`. When `autoConnect` is set to `false`, the `StreamVideo` client will not automatically attempt to connect upon initialization. This allows for more control over the connection lifecycle, which can be useful in scenarios where a connection is not immediately required. The `StreamVideoInitHelper` in the demo app is updated to use this new flag, setting `autoConnect` to `false`.
Removes the unused import for `HttpLoggingLevel` from `StreamVideoInitHelper.kt`.
This commit renames the `autoConnect` parameter in `StreamVideoBuilder` to `connectOnInit`. This change makes the parameter's purpose clearer: it controls whether the SDK attempts to connect to the websocket immediately upon user initialization, rather than upon any automatic condition. The documentation has also been updated to reflect this new, more precise naming.
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
WalkthroughThe changes introduce a new suspend Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt (1)
94-95: Consider clarifying KDoc wording.The phrase "as soon as a user is set" could be more precise. The user is set via constructor parameters, and the connection attempt occurs during
build()execution. Consider rewording to "during SDK initialization" or "when build() is called" for clarity.🔎 Suggested KDoc improvement
- * @property connectOnInit A flag that determines if the socket should attempt to connect as soon as a user is set. + * @property connectOnInit A flag that determines if the socket should connect during SDK initialization. * If `false`, the connection will only be established when explicitly requested or if core-sdk feature(s) like audio/video call is used
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.ktstream-video-android-core/api/stream-video-android-core.apistream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,java}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,java}: Use Kotlin with JVM toolchain 17; Java is legacy-only
Use 4-space indentation with no trailing whitespace
Avoid wildcard imports
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,kts}: Use PascalCase for types and Composables (e.g.,StreamCallActivity,ParticipantGrid)
Use camelCase for functions and values
Use UPPER_SNAKE_CASE for constants only when truly constant
Prefer explicit visibility modifiers; limitinternalleakage across modules
Keep critical RTC paths off the main thread; prefer coroutines with structured scopes
Monitor logging verbosity; rely onStreamVideoImpl.developmentModefor guardrails
Use KDoc (/** ... */) for public APIs and complex subsystems; link to Stream docs when relevant
Group large files with// regionjudiciously; keep commentary purposeful
Sanitize logs to avoid dumping JWTs, ICE tokens, or call IDs in verbose logs
Pause/resume capture on lifecycle changes; ensure background audio routing is intentional
Validate orientation, aspect ratio, and dynascale handling for both portrait/landscape phones and tablets
Keep concurrency deterministic—use structured coroutines and avoid global scope
Ensure cleanup/teardown paths handle cancellation and failure (important for sockets, queues, retries)
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,java,kts,gradle.kts}
📄 CodeRabbit inference engine (AGENTS.md)
Follow Spotless formatting; ensure custom license headers are in
spotless/directory
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
🧠 Learnings (2)
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Applies to stream-video-android-previewdata/**/*.{kt,kts} : Keep test fixtures in `stream-video-android-previewdata`; avoid duplicating builder logic
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.ktstream-video-android-core/api/stream-video-android-core.api
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Prefer Jetpack Compose for UI (`stream-video-android-ui-compose`); XML views supported via `stream-video-android-ui-xml`
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: base-android-ci / Build
- GitHub Check: base-android-ci / Run static checks
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: Build / compose apks
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
🔇 Additional comments (4)
stream-video-android-core/api/stream-video-android-core.api (1)
8468-8469: LGTM! Backward-compatible API addition forconnectOnInit.The new constructor overload correctly appends the
connectOnInitboolean (Z) parameter, and the synthetic constructor properly includes it with the default parameter handling. Existing constructor signatures (lines 8465-8467) are preserved, ensuring binary and source compatibility for current SDK consumers.demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt (1)
335-336: LGTM! Deferred connection aligns with PR objectives.Setting
connectOnInit = falseappropriately defers the WebSocket connection for the demo app, avoiding unnecessary connections at startup while preserving push device registration. The SDK will automatically connect when video features are actively used.stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt (2)
151-151: LGTM! Default value maintains backward compatibility.The
connectOnInitparameter with a default value oftrueensures existing integrations continue to connect automatically upon initialization, avoiding breaking changes.
297-304: LGTM! Conditional connection logic is correct.The implementation properly:
- Preserves push device registration before the
connectOnInitcheck (lines 294-296)- Scopes connection and its error handling within the conditional block
- Maintains backward compatibility (default behavior unchanged)
- Only affects non-anonymous users (guarded by line 291 check)
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt
Show resolved
Hide resolved
SDK Size Comparison 📏
|
Introduces a new `suspend fun connect(): Result<Unit>` method to the `StreamVideo` interface and its implementation in `StreamVideoClient`. This new function provides a suspending way to establish a WebSocket connection, returning a `Result` to indicate success or failure. This complements the existing `connectAsync` method by offering a more direct, coroutine-friendly alternative for connection management.
This commit introduces a new `suspend fun connect()` to the `StreamVideo` interface. This provides a more convenient and modern way to handle user connections compared to the existing `connectAsync()` which returns a `Deferred`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Fix all issues with AI Agents 🤖
In
@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt:
- Around line 469-482: connect() is missing guest user awaiting and token
refresh handling present in connectAsync(): before calling
socketImpl.connect(user) ensure guestUserJob?.await() is awaited (use the same
withContext(scope.coroutineContext) pattern as connectAsync()), and in the catch
for ErrorResponse detect e.code == TOKEN_EXPIRED and call and return
refreshToken(e) instead of immediately returning a Failure; otherwise preserve
existing error wrapping for other ErrorResponse and Throwable cases.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
stream-video-android-core/api/stream-video-android-core.apistream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideo.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,java}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,java}: Use Kotlin with JVM toolchain 17; Java is legacy-only
Use 4-space indentation with no trailing whitespace
Avoid wildcard imports
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideo.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,kts}: Use PascalCase for types and Composables (e.g.,StreamCallActivity,ParticipantGrid)
Use camelCase for functions and values
Use UPPER_SNAKE_CASE for constants only when truly constant
Prefer explicit visibility modifiers; limitinternalleakage across modules
Keep critical RTC paths off the main thread; prefer coroutines with structured scopes
Monitor logging verbosity; rely onStreamVideoImpl.developmentModefor guardrails
Use KDoc (/** ... */) for public APIs and complex subsystems; link to Stream docs when relevant
Group large files with// regionjudiciously; keep commentary purposeful
Sanitize logs to avoid dumping JWTs, ICE tokens, or call IDs in verbose logs
Pause/resume capture on lifecycle changes; ensure background audio routing is intentional
Validate orientation, aspect ratio, and dynascale handling for both portrait/landscape phones and tablets
Keep concurrency deterministic—use structured coroutines and avoid global scope
Ensure cleanup/teardown paths handle cancellation and failure (important for sockets, queues, retries)
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideo.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
**/*.{kt,java,kts,gradle.kts}
📄 CodeRabbit inference engine (AGENTS.md)
Follow Spotless formatting; ensure custom license headers are in
spotless/directory
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideo.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
🧠 Learnings (1)
📚 Learning: 2025-12-19T14:10:16.577Z
Learnt from: aleksandar-apostolov
Repo: GetStream/stream-video-android PR: 1587
File: stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/Call.kt:795-798
Timestamp: 2025-12-19T14:10:16.577Z
Learning: In the `rejoin()` function in `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/Call.kt`, the design invariant is that `rejoin()` should only be called when there is an active session (`this.session != null`). Therefore, using `this.session!!` is safe and intentional.
Applied to files:
stream-video-android-core/api/stream-video-android-core.api
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
- GitHub Check: base-android-ci / Run static checks
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: base-android-ci / Build
- GitHub Check: Build / compose apks
🔇 Additional comments (3)
stream-video-android-core/api/stream-video-android-core.api (2)
8469-8470: Constructor additions maintain backward compatibility.The new constructor overloads correctly add the
connectOnInitparameter with a default value (indicated by the synthetic constructor withDefaultConstructorMarker). Existing callers using previous constructor signatures will continue to work withconnectOnInitdefaulting totrue, preserving the original auto-connect behavior.
8409-8411: Public API addition toStreamVideointerface is acceptable.The new
suspend fun connect()method complements the existingconnectAsync()andconnectIfNotAlreadyConnected()methods, providing a cleaner coroutine-friendly entry point. The JVM signature is correct for a suspend function.Since
StreamVideois only implemented by the internalStreamVideoClientclass, adding this abstract method is safe and does not introduce breaking changes for external users.stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideo.kt (1)
148-148: LGTM: Clean API addition.The new
connect(): Result<Unit>method provides a straightforward coroutine-compatible alternative toconnectAsync(), eliminating the need to unwrap aDeferredwhen immediate connection is desired.
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
Outdated
Show resolved
Hide resolved
This commit ensures that the `guestUserJob` is awaited before attempting to establish a WebSocket connection. Additionally, it adds specific handling for token expiration errors (`VideoErrorCode.TOKEN_EXPIRED`). If a token has expired, it now attempts to refresh it and returns a more specific error message.
This commit refactors the `connect()` method in `StreamVideoClient`. Key changes: - The `connect()` method now returns `Result<Long>`, representing the duration of the connection process in milliseconds. - The previous implementation of `connect()` has been extracted into `connectAsync()` which returns a `Deferred<Result<Long>>`. - The `connect()` method now simply awaits the result of `connectAsync()`. - Error handling has been unified to catch all `Throwable` exceptions during connection.
Automatically connects the StreamVideo instance for E2E test builds. This change bypasses the need for push notifications to trigger the connection, which are not used in the E2E testing environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt (2)
164-169: Consider handling the connection Result and fix grammar.Two observations:
The
connect()call returnsResult<Long>but the result is not captured or handled. If the E2E connection fails, it may go unnoticed. Consider logging failures for observability.Grammar: "E2E tests does not rely" should be "E2E tests do not rely" (plural subject).
🔎 Proposed improvement
/** - * Because E2E tests does not rely on Push Notification + * Because E2E tests do not rely on Push Notifications */ if (StreamBuildFlavorUtil.isE2eTesting) { - StreamVideo.instance().connect() + val result = StreamVideo.instance().connect() + result.onFailure { error -> + Log.e("StreamVideoInitHelper", "E2E auto-connect failed", error) + } }
342-342: LGTM!The single-line
TelecomConfiginitialization is cleaner and functionally equivalent.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideo.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.kt
🚧 Files skipped from review as they are similar to previous changes (2)
- 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/StreamVideo.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,java}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,java}: Use Kotlin with JVM toolchain 17; Java is legacy-only
Use 4-space indentation with no trailing whitespace
Avoid wildcard imports
Files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,kts}: Use PascalCase for types and Composables (e.g.,StreamCallActivity,ParticipantGrid)
Use camelCase for functions and values
Use UPPER_SNAKE_CASE for constants only when truly constant
Prefer explicit visibility modifiers; limitinternalleakage across modules
Keep critical RTC paths off the main thread; prefer coroutines with structured scopes
Monitor logging verbosity; rely onStreamVideoImpl.developmentModefor guardrails
Use KDoc (/** ... */) for public APIs and complex subsystems; link to Stream docs when relevant
Group large files with// regionjudiciously; keep commentary purposeful
Sanitize logs to avoid dumping JWTs, ICE tokens, or call IDs in verbose logs
Pause/resume capture on lifecycle changes; ensure background audio routing is intentional
Validate orientation, aspect ratio, and dynascale handling for both portrait/landscape phones and tablets
Keep concurrency deterministic—use structured coroutines and avoid global scope
Ensure cleanup/teardown paths handle cancellation and failure (important for sockets, queues, retries)
Files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,java,kts,gradle.kts}
📄 CodeRabbit inference engine (AGENTS.md)
Follow Spotless formatting; ensure custom license headers are in
spotless/directory
Files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
🧠 Learnings (2)
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Applies to stream-video-android-previewdata/**/*.{kt,kts} : Keep test fixtures in `stream-video-android-previewdata`; avoid duplicating builder logic
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Prefer Jetpack Compose for UI (`stream-video-android-ui-compose`); XML views supported via `stream-video-android-ui-xml`
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: base-android-ci / Build
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: base-android-ci / Run static checks
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
- GitHub Check: Build / compose apks
🔇 Additional comments (2)
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt (2)
343-343: TheconnectOnInit = falseparameter correctly defers the automatic WebSocket connection. The parameter is properly defined inStreamVideoBuilderwith a default value oftrue, allowing the demo app to explicitly control connection timing as intended.
58-58: Import is valid and properly used.The
StreamBuildFlavorUtilclass exists atdemo-app/src/main/kotlin/io/getstream/video/android/tooling/util/StreamFlavors.ktwith theisE2eTestingproperty correctly defined. The import and its usage at line 167 are correct.
This commit refactors how the WebSocket connection is managed at application startup. Previously, the `StreamVideoInitHelper` would automatically connect the client if the build flavor was for E2E testing. This logic is now removed. Instead, the client is explicitly connected in the `App.kt` `onCreate` method. This change is made to support end-to-end tests that rely on WebSocket events for receiving calls, as the `connectOnInit` flag is set to `false` by default. Additionally, the documentation for the `connectOnInit` flag in `StreamVideoBuilder` has been improved to clarify its behavior, especially regarding push notifications and manual connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Fix all issues with AI Agents 🤖
In @demo-app/src/main/kotlin/io/getstream/video/android/App.kt:
- Line 74: Avoid blocking the main thread in Application.onCreate by removing
runBlocking around StreamVideo.instanceOrNull()?.connect(); instead create a
background coroutine (e.g., CoroutineScope(Dispatchers.IO +
SupervisorJob()).launch { ... }) and call
StreamVideo.instanceOrNull()?.connect() inside it, capturing the returned
Result<Long> into a val (e.g., val result = ...), then handle both success and
failure cases (log the connection id on success and log the throwable or failure
message on failure) so connection errors are not silent and startup cannot ANR.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
demo-app/src/main/kotlin/io/getstream/video/android/App.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,java}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,java}: Use Kotlin with JVM toolchain 17; Java is legacy-only
Use 4-space indentation with no trailing whitespace
Avoid wildcard imports
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.ktdemo-app/src/main/kotlin/io/getstream/video/android/App.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,kts}: Use PascalCase for types and Composables (e.g.,StreamCallActivity,ParticipantGrid)
Use camelCase for functions and values
Use UPPER_SNAKE_CASE for constants only when truly constant
Prefer explicit visibility modifiers; limitinternalleakage across modules
Keep critical RTC paths off the main thread; prefer coroutines with structured scopes
Monitor logging verbosity; rely onStreamVideoImpl.developmentModefor guardrails
Use KDoc (/** ... */) for public APIs and complex subsystems; link to Stream docs when relevant
Group large files with// regionjudiciously; keep commentary purposeful
Sanitize logs to avoid dumping JWTs, ICE tokens, or call IDs in verbose logs
Pause/resume capture on lifecycle changes; ensure background audio routing is intentional
Validate orientation, aspect ratio, and dynascale handling for both portrait/landscape phones and tablets
Keep concurrency deterministic—use structured coroutines and avoid global scope
Ensure cleanup/teardown paths handle cancellation and failure (important for sockets, queues, retries)
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.ktdemo-app/src/main/kotlin/io/getstream/video/android/App.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,java,kts,gradle.kts}
📄 CodeRabbit inference engine (AGENTS.md)
Follow Spotless formatting; ensure custom license headers are in
spotless/directory
Files:
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.ktdemo-app/src/main/kotlin/io/getstream/video/android/App.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
🧠 Learnings (3)
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Applies to stream-video-android-previewdata/**/*.{kt,kts} : Keep test fixtures in `stream-video-android-previewdata`; avoid duplicating builder logic
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/App.ktdemo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
📚 Learning: 2025-12-19T14:10:16.577Z
Learnt from: aleksandar-apostolov
Repo: GetStream/stream-video-android PR: 1587
File: stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/Call.kt:795-798
Timestamp: 2025-12-19T14:10:16.577Z
Learning: In the `rejoin()` function in `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/Call.kt`, the design invariant is that `rejoin()` should only be called when there is an active session (`this.session != null`). Therefore, using `this.session!!` is safe and intentional.
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/App.kt
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Prefer Jetpack Compose for UI (`stream-video-android-ui-compose`); XML views supported via `stream-video-android-ui-xml`
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build / compose apks
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: base-android-ci / Run static checks
- GitHub Check: base-android-ci / Build
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
🔇 Additional comments (6)
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt (3)
94-99: LGTM! Clear documentation.The KDoc clearly explains the behavior and push notification implications of
connectOnInit = false.
155-155: Parameter addition looks good.The default value of
truemaintains backward compatibility. Note the past comment about potentially changing the default tofalsein a future major release.
301-308: LGTM! Conditional connection logic is correct.The conditional correctly gates the initial WebSocket connection while preserving push device registration and error handling. The implementation maintains existing behavior when
connectOnInit = true.demo-app/src/main/kotlin/io/getstream/video/android/App.kt (1)
66-73: LGTM! Comment clearly explains the explicit connection.The comment effectively documents why manual connection control is needed for E2E tests.
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt (2)
335-335: LGTM! Simplified TelecomConfig construction.The single-line construction is cleaner and aligns with the updated TelecomConfig API.
336-336: LGTM! Consistent with explicit connection in App.kt.Setting
connectOnInit = falsehere aligns with the explicitconnect()call inApp.kt, enabling manual connection control for E2E testing scenarios.
| * This is required for end-to-end (E2E) tests, which rely on WebSocket events | ||
| * to receive calls instead of Push Notifications (PN). | ||
| */ | ||
| StreamVideo.instanceOrNull()?.connect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider non-blocking connection and error handling.
The runBlocking call in Application.onCreate() can block the main thread during app startup, potentially causing ANR if the connection hangs or takes too long. Additionally, the Result<Long> from connect() is not handled, which could lead to silent failures in E2E tests.
🔎 Recommended approach using a coroutine scope
- /**
- * The `connectOnInit` flag in `StreamVideoInitHelper` is set to `false` to give us
- * manual control over the connection.
- *
- * We explicitly call `connect()` here to establish a WebSocket connection at startup.
- * This is required for end-to-end (E2E) tests, which rely on WebSocket events
- * to receive calls instead of Push Notifications (PN).
- */
- StreamVideo.instanceOrNull()?.connect()
+ /**
+ * The `connectOnInit` flag in `StreamVideoInitHelper` is set to `false` to give us
+ * manual control over the connection.
+ *
+ * We explicitly call `connect()` here to establish a WebSocket connection at startup.
+ * This is required for end-to-end (E2E) tests, which rely on WebSocket events
+ * to receive calls instead of Push Notifications (PN).
+ */
+ CoroutineScope(Dispatchers.IO).launch {
+ StreamVideo.instanceOrNull()?.connect()?.onFailure { error ->
+ Log.e("App", "Failed to connect WebSocket for E2E tests", error)
+ }
+ }This approach:
- Avoids blocking the main thread
- Logs connection failures for debugging
- Uses appropriate dispatcher for I/O operations
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| StreamVideo.instanceOrNull()?.connect() | |
| /** | |
| * The `connectOnInit` flag in `StreamVideoInitHelper` is set to `false` to give us | |
| * manual control over the connection. | |
| * | |
| * We explicitly call `connect()` here to establish a WebSocket connection at startup. | |
| * This is required for end-to-end (E2E) tests, which rely on WebSocket events | |
| * to receive calls instead of Push Notifications (PN). | |
| */ | |
| CoroutineScope(Dispatchers.IO).launch { | |
| StreamVideo.instanceOrNull()?.connect()?.onFailure { error -> | |
| Log.e("App", "Failed to connect WebSocket for E2E tests", error) | |
| } | |
| } |
🤖 Prompt for AI Agents
In @demo-app/src/main/kotlin/io/getstream/video/android/App.kt around line 74,
Avoid blocking the main thread in Application.onCreate by removing runBlocking
around StreamVideo.instanceOrNull()?.connect(); instead create a background
coroutine (e.g., CoroutineScope(Dispatchers.IO + SupervisorJob()).launch { ...
}) and call StreamVideo.instanceOrNull()?.connect() inside it, capturing the
returned Result<Long> into a val (e.g., val result = ...), then handle both
success and failure cases (log the connection id on success and log the
throwable or failure message on failure) so connection errors are not silent and
startup cannot ANR.
Adds logging to the `StreamVideo.instanceOrNull()?.connect()` call within the demo app. This provides visibility into whether the WebSocket connection was successful or failed, which is useful for debugging.
Moves the manual `StreamVideo.instanceOrNull()?.connect()` call from `App.kt` to `StreamVideoInitHelper.kt`. This change ensures that the WebSocket connection is established immediately after the Stream Video SDK is initialized. This is a requirement for end-to-end (E2E) tests, which depend on WebSocket events for receiving calls rather than push notifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Fix all issues with AI Agents 🤖
In
@demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt:
- Around line 164-172: The StreamVideo.instanceOrNull()?.connect() call in
StreamVideoInitHelper ignores the Result<Long>, so a failed WebSocket connect
can be silently ignored while "Init successful" is logged; capture and inspect
the Result from connect() (StreamVideo.instanceOrNull()?.connect()), call
onSuccess to log a confirmed "WebSocket connection established" and onFailure to
Log.e the error (or propagate/abort initialization if failure should block
startup) before emitting the existing "Init successful" message.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,java}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,java}: Use Kotlin with JVM toolchain 17; Java is legacy-only
Use 4-space indentation with no trailing whitespace
Avoid wildcard imports
Files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{kt,kts}: Use PascalCase for types and Composables (e.g.,StreamCallActivity,ParticipantGrid)
Use camelCase for functions and values
Use UPPER_SNAKE_CASE for constants only when truly constant
Prefer explicit visibility modifiers; limitinternalleakage across modules
Keep critical RTC paths off the main thread; prefer coroutines with structured scopes
Monitor logging verbosity; rely onStreamVideoImpl.developmentModefor guardrails
Use KDoc (/** ... */) for public APIs and complex subsystems; link to Stream docs when relevant
Group large files with// regionjudiciously; keep commentary purposeful
Sanitize logs to avoid dumping JWTs, ICE tokens, or call IDs in verbose logs
Pause/resume capture on lifecycle changes; ensure background audio routing is intentional
Validate orientation, aspect ratio, and dynascale handling for both portrait/landscape phones and tablets
Keep concurrency deterministic—use structured coroutines and avoid global scope
Ensure cleanup/teardown paths handle cancellation and failure (important for sockets, queues, retries)
Files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
**/*.{kt,java,kts,gradle.kts}
📄 CodeRabbit inference engine (AGENTS.md)
Follow Spotless formatting; ensure custom license headers are in
spotless/directory
Files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
🧠 Learnings (2)
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Applies to stream-video-android-previewdata/**/*.{kt,kts} : Keep test fixtures in `stream-video-android-previewdata`; avoid duplicating builder logic
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
📚 Learning: 2025-12-19T09:15:37.269Z
Learnt from: CR
Repo: GetStream/stream-video-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T09:15:37.269Z
Learning: Applies to **/*.{kt,kts} : Monitor logging verbosity; rely on `StreamVideoImpl.developmentMode` for guardrails
Applied to files:
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build / compose apks
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
- GitHub Check: base-android-ci / Build
- GitHub Check: base-android-ci / Run static checks
🔇 Additional comments (1)
demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt (1)
344-345: LGTM! Deferred WebSocket connection aligns with PR objectives.The
connectOnInit = falseparameter correctly defers the automatic WebSocket connection during SDK initialization, and the manualconnect()call at line 172 ensures the connection is established when needed for E2E tests. The single-linetelecomConfigformatting is also clean.This implementation gives explicit control over the connection lifecycle as intended by the PR.
| /** | ||
| * The `connectOnInit` flag in `StreamVideoInitHelper` is set to `false` to give us | ||
| * manual control over the connection. | ||
| * | ||
| * We explicitly call `connect()` here to establish a WebSocket connection at startup. | ||
| * This is required for end-to-end (E2E) tests, which rely on WebSocket events | ||
| * to receive calls instead of Push Notifications (PN). | ||
| */ | ||
| StreamVideo.instanceOrNull()?.connect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Find the StreamVideo class and its connect() method
fd -e kt -e java | head -20Repository: GetStream/stream-video-android
Length of output: 2191
🏁 Script executed:
# Search for connect() function definition
rg -B2 -A10 'fun connect\(' --type=kt | head -50Repository: GetStream/stream-video-android
Length of output: 100
🏁 Script executed:
# Also check the StreamVideoInitHelper file structure around lines 164-172
fd StreamVideoInitHelper -e kt -exec wc -l {} \;Repository: GetStream/stream-video-android
Length of output: 260
🏁 Script executed:
# Search for connect() function definition in Kotlin files
rg -A10 'fun connect\(' . --type=kt | head -100Repository: GetStream/stream-video-android
Length of output: 100
🏁 Script executed:
# Find and read StreamVideoInitHelper.kt file
find . -name "StreamVideoInitHelper.kt" -type fRepository: GetStream/stream-video-android
Length of output: 157
🏁 Script executed:
# Search more broadly for StreamVideo class and connect method
rg 'class StreamVideo' . --type=kt -A5Repository: GetStream/stream-video-android
Length of output: 100
🏁 Script executed:
# Read the StreamVideoInitHelper.kt file
cat ./demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.ktRepository: GetStream/stream-video-android
Length of output: 15472
🏁 Script executed:
# Search for connect() function without type filter
rg -A10 'fun connect\(' . | head -150Repository: GetStream/stream-video-android
Length of output: 10720
Handle and log the connect() result—it returns Result<Long>, not Unit.
The connect() call returns Result<Long>, but the return value is discarded. The subsequent "Init successful" log (line 173) is misleading if the connection failed. For E2E tests that depend on WebSocket events, a silent connection failure would go undetected.
Extract and check the result:
StreamVideo.instanceOrNull()?.connect()?.onSuccess {
Log.d("StreamVideoInitHelper", "WebSocket connection established.")
}?.onFailure { error ->
Log.e("StreamVideoInitHelper", "Failed to establish WebSocket connection.", error)
}Alternatively, if the connection failure should fail initialization, propagate or handle it explicitly before logging "Init successful."
🤖 Prompt for AI Agents
In
@demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt
around lines 164-172, The StreamVideo.instanceOrNull()?.connect() call in
StreamVideoInitHelper ignores the Result<Long>, so a failed WebSocket connect
can be silently ignored while "Init successful" is logged; capture and inspect
the Result from connect() (StreamVideo.instanceOrNull()?.connect()), call
onSuccess to log a confirmed "WebSocket connection established" and onFailure to
Log.e the error (or propagate/abort initialization if failure should block
startup) before emitting the existing "Init successful" message.
|


Goal
To prevent the SDK from hitting API rate limits by changing the default connection behavior. Currently, the SDK automatically establishes a WebSocket connection upon initialization. This can lead to excessive, unnecessary connections for clients who initialize the SDK at startup but do not immediately use video features, causing them to hit rate limits.
Implementation
To fix this, this PR introduces a
connectOnInitflag in theStreamVideoBuilder. By settingconnectOnInit = false, developers can now defer the connection until it's explicitly required. The SDK will still automatically connect internally when a core action is performed (like starting a call), ensuring functionality remains seamless while giving developers the control to reduce unnecessary startup connections.Example Usage
🎨 UI Changes
None
Testing
Just perform audio/video call and check if you see cooridnator socket events
Summary by CodeRabbit
connectOnInitparameter to control automatic WebSocket connection behavior during app startup (enabled by default for backward compatibility)✏️ Tip: You can customize this high-level summary in your review settings.