chore: merge develop into develop-v2 - #1790
Open
PratimMallick wants to merge 92 commits into
Open
Conversation
* upgrade to m145 webrtc and noise-cancellation * Update to webrtc m145 and corresponding noiseCancellation lib * Remove the snapshot repo resolution
…ng (#1699) * feat(core): pick up SFU DegradationPreference and add WebRTC mapper Regenerate SFU protos to pick up the new DegradationPreference enum and its degradation_preference fields on PublishOption and VideoSender (plus TrackInfo.self_sub_audio_video), and refresh the public API dump. Add toRtcDegradationPreference() converting the SFU enum to org.webrtc.RtpParameters.DegradationPreference, returning null for UNSPECIFIED so callers can keep the current value. Includes unit tests covering every enum variant. Co-authored-by: Cursor <cursoragent@cursor.com> * publisher changes for applying degradation preferences * Remove duplicate handling of ChangePublishQualityEvent from callState. This event directly gets handled by RtcSession handleEvent method * Added test for the two call sites where degradation Preference is getting set to test for the case where sfu sends the same degrdation preference which is already set in the transcevier sender param --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…rted-participants init (#1701)
* demo: Add logic to add custom user * chore(demo-app): gate add user dialog to development flavor Hide the new add-user button and popup outside the development flavor so the production demo app doesn't expose internal user injection. --------- Co-authored-by: Aleksandar Apostolov <apostolov.alexandar@gmail.com>
When toggling a single track (e.g. muting the mic while the camera stays on, or turning the camera off while the mic stays on), RtcSession sent the full declarative mute-state map for all track types. Re-asserting an unchanged track as un-muted made the SFU re-emit a redundant TrackPublishedEvent for that track. That event carries a potentially stale published_tracks snapshot which re-enabled the just-disabled track, freezing the local self-view on the last frame / showing the avatar while no frames arrive. Send only the mute state of the track that actually changed, matching the web SDK. On SFU (re)connect/migration each enabled track is re-signalled individually via listenToMediaChanges, so the full state is still restored. Co-authored-by: Cursor <cursoragent@cursor.com>
…1705) deleteDevice previously only purged the cached Device on API success. When DELETE /devices returned 404 or the network failed, the stale token sat in deviceTokenStorage. The next createDevice for a different user short-circuited on token equality (when autoRegisterPushDevice=true) and returned Success without calling POST /devices, silently leaving the new user without a device row server-side and breaking incoming-call push. Local cleanup now runs unconditionally and is guarded so a storage failure doesn't mask the API outcome. CancellationException is re-thrown to preserve structured concurrency. Three regression tests added. AND-1214
… device registration (#1703) Guest user setup runs asynchronously: StreamVideoBuilder.build returns immediately while setupGuestUser kicks off a background createGuest call to fetch the JWT. Any authenticated request that fires in that window goes out with stream-auth-type "anonymous" and no Authorization header, so the backend silently registers it against the wrong identity. The customer-visible effect is push device registration succeeding under !anon and incoming-call pushes never reaching the guest user. apiCall now awaits guestUserJob before invoking the request block, with a self-job guard so createGuestUser — which also goes through apiCall — does not await its own enclosing job and deadlock. Adds two regression tests: one for the wait, one for the deadlock guard. AND-1202 Co-authored-by: Rahul Kumar Lohra <tgunix@gmail.com>
* fix(core): adopt response.user from createGuest to keep guest identity in sync The createGuest endpoint returns the server-resolved user (which may differ from what was passed in — e.g. normalized id). The SDK previously kept only the access token and left its in-memory user as the builder's input, so the WS auth payload and the JWT user_id claim could disagree. setupGuestUser now also updates client.user from response.user (matching the JS SDK's connectUser(response.user, response.access_token) semantics). userId becomes a computed property so every existing reader of client.userId picks up the new identity automatically. CoordinatorSocketConnection.user turns into a var so its onCreated() auth payload reads the latest user. Adds three regression tests: userId reactivity, the var update inside the socket connection's connect path, and a full setupGuestUser flow with the api mocked to return a different user id than the input. AND-1202 * fix(core): mirror adopted guest user into ClientState.user ClientState._user was snapshotted from the integrator-supplied user at construction, so observers of state.user kept the old id after setupGuestUser adopted the server-issued one. Propagate the adopted user via a new internal ClientState.setUser.
* refactor(core): introduce UserRepository as single source of truth for SDK user Replaces the parallel `var user` fields in `StreamVideoClient` and `CoordinatorSocketConnection` (and the `_user` mirror in `ClientState`) with a single `UserRepository`: - `UserRepository` — public, read-only access via `user` / `userFlow`. - `WritableUserRepository` — internal sub-interface with `setUser`. Only `StreamVideoClient` holds a write reference, so identity updates go through one path. - `StreamUserRepositoryImpl` — in-memory impl backed by a `MutableStateFlow`. `StreamVideoBuilder` constructs one instance and shares it between the client (writer) and the coordinator socket / `ClientState` (readers). `setupGuestUser` writes the adopted user to the repo once; readers pick it up automatically without any local copy to keep in sync. `connect()`/`reconnect()` no longer mutate a snapshot of the user on the socket — they only forward the call to `internalSocket`, and `onCreated()` reads from the repository when building the WS auth payload. * test(core): add direct unit tests for StreamUserRepositoryImpl Covers seed-from-constructor, user/userFlow reads, setUser write, emission to active StateFlow collectors, and replacement semantics. Lifts coverage on the new repository from indirect-only (via StreamVideoClient tests) to full coverage of the impl. * Auto-connect and register push device for guest users (#1707) * feat(core): auto-connect and register push device for guest users StreamVideoBuilder previously only ran the auto-register-push and auto-connect block for UserType.Authenticated. Guest users fell through, forcing every Guest integrator to write the same boilerplate (manual registerPushDevice + connect after build) — boilerplate the iOS and JS SDKs don't require. Widen the gate to include UserType.Guest. registerPushDevice() and connectAsync() inside StreamVideoClient already await guestUserJob, so both are safe to fire from the builder block before /video/guest completes. Anonymous users still don't have an identity to register a device against, so they remain excluded. AND-1202 * fix(core): wait for guestUserJob before registering push device StreamNotificationManager.createDevice() goes straight to api.createDevice() without the apiCall {} wrapper, so the guestUserJob await guard added in #1703 doesn't cover it. registerPushDevice() now waits for guest setup itself before delegating, so the push generator can't fire createDevice() before the coordinator's auth headers flip from anonymous to JWT.
* fix: include internal audio switch to fix concurrency issue * fix: include aar
The KDoc claimed `logOut` clears internal user state, removes push notification devices, and clears call state. The actual implementation only writes null to the local DeviceTokenStorage — no `DELETE /devices`, no socket disconnect, no in-memory clear. The name and the historical doc invite a customer to ship broken user-switching: anyone reading the API surface would reasonably assume a clean slate. Surfaced while diagnosing a customer integration where push delivery silently failed across user transitions. Annotate the interface declaration and the StreamVideoClient override with `@Deprecated`. Update the KDoc to describe current behavior accurately. Point `ReplaceWith` at `StreamVideo.removeClient()`, which triggers a real `cleanup()` and uninstalls the singleton. Customers who need to remove the server-side device row should call `deleteDevice()` before `removeClient()`. No binary signature change — `@Deprecated` is annotation-only, so the public `.api` file is unchanged. AND-1217 Co-authored-by: Rahul Kumar Lohra <tgunix@gmail.com>
…ce (#1711) Assign the DataStore.updateData() result to a local in DeviceTokenStorage.updateUserDevice so the suspend function is compiled as a state machine that returns Unit. Without it the compiler tail-call-optimizes the call and propagates the DevicePreferences result up the updateDevice suspend chain, which can surface as "DevicePreferences cannot be cast to kotlin.Unit" at the caller once R8 inlines the chain. Co-authored-by: Cursor <cursoragent@cursor.com>
…unt (#1712) Post-join, the SFU healthcheck delivers the authoritative participant count. Coordinator session events (participant_joined/left, counts_updated, anything carrying a CallSessionResponse) carry a smaller, stale snapshot that disagrees at scale. The previous guard checked only !is RealtimeConnection.Joined — a transient state immediately replaced by Connected — so every coordinator session event re-wrote the count, producing wild swings during livestreams (e.g. 25k -> 32k -> 42k -> 28k in seconds). Broaden the guard to cover the entire in-call lifetime (Joined, Connected, Reconnecting, Migrating). Pre-join, the session-derived path now uses max(byRoleCount, participants.size) for monotonicity during fast joins, matching the stream-video-js SDK. AND-926
) * fix(core): prevent "MediaSource has been disposed" crash on leave Guards the lazy audio/video source and track creation/disposal in MediaManagerImpl with a single reentrant lock, and adds a terminal `released` flag so the mic/camera mute paths no-op after cleanup instead of lazily resurrecting native objects. The crash occurred when a call was left while the first AudioSwitch setup was still in flight: cleanup() disposed the audio source on one thread while the deferred mic-disable callback recreated the audio track from that disposed source on stream-audio-thread. Co-authored-by: Cursor <cursoragent@cursor.com> * test(core): stub runOnAudioTrackIfAvailable in MicrophoneManager tests enable()/disable() now route the track toggle through mediaManager.runOnAudioTrackIfAvailable instead of the audioTrack getter, so the test helper stubs the new helper to invoke its block with the mock track. Fixes the 5 failing MicrophoneManagerTest verifications. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…elease of 1.26.0 (#1719) * Revert " Include internal audio switch to fix concurrency issue (#1710)" This reverts commit 9a8da36. * chore(release): reset version to 1.25.0 to allow re-release of 1.26.0 The 1.26.0 Maven publish failed due to the local AAR introduced in #1710. Resetting gradle.properties to 1.25.0 so the release workflow can re-tag and publish 1.26.0 cleanly from the reverted develop state.
The "setting up call" foreground-service notification was built without a
small icon for any non-incoming trigger (outgoing/ongoing/livestream). The
non-deprecated getSettingUpCallNotification(trigger, callId) delegated its
else branch to the deprecated no-arg overload, which never called
setSmallIcon. A small icon is mandatory for foreground-service
notifications, so Android 13+ rejected it with
CannotPostForegroundServiceNotificationException ("Bad notification for
startForeground") when the call foreground service started.
Extract a non-deprecated buildSettingUpCallNotification() helper that always
sets setSmallIcon(R.drawable.stream_video_ic_call), and have both the
non-deprecated else branch and the deprecated overload delegate to it. Add a
regression test covering the non-incoming (outgoing) trigger path.
Co-authored-by: Cursor <cursoragent@cursor.com>
* update open api generated models * update code gen script
* update open api generated models * update code gen script * fix: self cancelling coroutine code * fix: fix self cancelling coroutine code
…e call (3/4) (#1715) * update open api generated models * update code gen script * fix: self cancelling coroutine code * internal: add call leave reason * internal: update Call Leave Reason LLC * fix: fix unit tests * 📝 CodeRabbit Chat: Implement requested code changes * Update stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallLeaveReason.kt * chore: send correct leave reason from StreamCallActivity.kt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Aleksandar Apostolov <apostolov.alexandar@gmail.com>
…1773) * fix(core): enforce noise-cancellation capability and call settings Core checked neither OwnCapability.EnableNoiseCancellation nor the call type's noise_cancellation mode, so noise cancellation ran regardless of what the server granted. Android enforced neither check, and shipped the mode helpers in core while only the demo app consumed them. Add NoiseCancellationPolicy owning both checks, and reconcile against it from Call. Enabling is refused when either is withheld and withdrawn if either is taken away mid-call; disabling is always allowed so a withdrawal can never be blocked. The reconciler waits for settings to resolve rather than reading "not told yet" as a refusal, which would flap noise cancellation during join. The call type's auto-on default moves out of the demo app's lobby view model into core, so every app gets it rather than whoever remembered to wire it. Applying a wanted state no longer forces the peer-connection factory into existence: CallMediaManager remembers it and a factory created later picks it up. A factory built before join captures the pre-join audio bitrate profile and defeats ensureFactoryMatchesAudioProfile. Expose CallState.audioProcessingEnabled so consumers can observe SDK-driven changes; the demo app collects it instead of snapshotting, and now reads settings only to decide whether to show the menu item. * fix(core): close the noise-cancellation lifecycle gaps Three gaps between the policy gate and the deferred factory, all of which let state and enforcement drift apart. Withdrawal only acted when something was already processing. A state wanted before the factory existed is remembered and would be applied the moment one was built, after the server had withheld it. Withdrawal now clears the wanted state whether or not anything is running yet. The gate read the audio-processing state through the lazily-creating factory accessor, so opening the toggle before joining built a factory pinned to the pre-join audio bitrate profile. It now reads without creating one. The wanted state also outlived the call, so a reused Call would re-apply it to the factory built for the next session. Cleanup forgets it. Publishing and signalling now both follow the applied state rather than the request, matching the toggle path.
CHANGELOG.md is not used anymore. Release notes are generated from the PRs themselves, using the pr: labels and the categories configured in .github/release.yaml. Deletes the file, its ownership line in .github/CODEOWNERS, and the "Changelog is updated with client-facing changes" item in the PR template checklist. The remaining "changelog" matches in the repo are unrelated to this file and stay: the changelog: key in .github/release.yaml is GitHub's own release notes config, FASTLANE_HIDE_CHANGELOG in fastlane/.env is a fastlane internal flag, and the README link points to the roadmap page on GitHub Discussions. AND-1442
* Write analytics docs * Write analytics docs
* [AND-1445] Stabilize the flaky E2E emulator tests The nightly E2E cron was red on 11 of the last 13 runs. Most failures came from retry attempts that were not independent: the instrumentation runs inside the app process, so a failed attempt could leave the internet connection disabled or a call still active, and the remaining attempts inherited that state and failed the same way. - RetryRule now restores the connection and leaves any leftover call between attempts, and all post-failure steps are best-effort so an attachment error cannot replace the real failure or skip retries. - The UiAutomator wait helpers are replaced with the polling, stale-safe versions from stream-chat-android. Timeouts now throw a clear error naming the selector instead of an NPE. - All UserRobot clicks go through the new stale-safe waitToAppearAndClick. - Longer windows for joining a call and for the outgoing ringing screen, and the recording label assertion polls through the reconnect banner. - run_e2e_test accepts a test_class option, and the PR workflow exposes api_level and test_class dispatch inputs to sample one flaky test. - Failure artifacts include allure-results, and the E2E concurrency groups are scoped by workflow name. * [AND-1445] Address review findings and widen the view menu wait - Pass test_class to fastlane through the step environment with a quoted expansion, so the dispatch input cannot inject shell commands into the emulator action script. - Drop '$' from the allowed test_class characters: the local and device shells would expand it. All E2E test classes are top-level anyway. - Give the view menu items in setView a 15s window. In the failed batch 0 run, the Spotlight item was present in the hierarchy dump seconds after the 5s timeout: with many live video tiles the popup lands in the accessibility tree late on the emulator. * [AND-1445] Widen the connecting screen window to match the join window The connecting progress bar covers the same call join round-trip as waitForCallToStart, which can exceed 10s on a loaded CI emulator. This is the assertConnectingView failure seen on PR #1781.
* [AND-1446] Fix the flaky MockK Context setup in PictureInPictureTest * [AND-1446] Assert the built PictureInPictureParams values on TIRAMISU * [AND-1446] Strengthen the PiP params assertions per review
* Snapshot test baseline for the Compose Video SDK (AND-1417) Adopt the chat SDK Paparazzi conventions: a PaparazziComposeTest interface with snapshot, snapshotWithDarkMode, and snapshotWithDarkModeRow helpers plus shared hdpi device configs, replacing BaseComposeTest. Fix the flakiness behind the 10 ignored tests and enable them. The preview data now uses deterministic session ids, pins previewCall's own session id, populates all six participants once at init, and no longer clears shared state on every access. Extend coverage from 74 to 116 goldens: individual control actions, dialogs, spotlight renderers, livestream backstage, 7-participant grids, lobby states, and dark variants for the main screens. New coverage uses shared internal preview composables in src/debug called by both the @Preview wrapper and the test; those tests live in src/testDebug so the release unit test variant still compiles. Raise the Paparazzi test worker heap to 4g like the chat repo. * Apply chat snapshot conventions to names, dark coverage, and rendering Rename all snapshot test methods to the chat SDK style (lowercase phrases, dark variants suffixed with 'in dark mode') so golden file names follow the same convention as the chat repo. Cover light and dark for every surface: components use the combined snapshotWithDarkMode golden, full screens get an explicit dark mode sibling test, and screen sharing tests gain the light variant they were missing. Remove tests that duplicated the same composition. Use RenderingMode.SHRINK everywhere except the dialog tests (window level Dialog and Popup overlays) so component goldens crop to content. Give the grid renderer tests a dedicated call per participant count (previewGridCall). The renderers read remote participants from call state for the small layouts, so the shared six-participant previewCall could not represent one, two, or three participant calls. This also makes the 'N participants' goldens true to their names. * Fix snapshot verification failures found by Linux CI Record the case-only renames of the BaseComponentsTest goldens explicitly. The macOS filesystem is case insensitive, so git kept the old capitalized file names and the Linux runner could not find the lowercase ones the tests expect. Snapshot the participant actions menu content directly. The production wrapper renders through a window level Popup, which neither Paparazzi nor Android Studio previews capture, so the goldens were empty. The Popup content is extracted into ParticipantActionsDialogContent (internal, no API change) and the stale kick preview, which duplicated the default preview, is removed. Build the grid test call before the snapshot and wait for the sorted participants state to settle. The state propagates asynchronously on the call scope and the grid renderers return early while it is empty, so capturing the first frame raced with machine timing (CI diffed 51 to 59 percent on two grids). Set maxPercentDifference to 0.5. CI measured 0.10 to 0.30 percent antialiasing drift between macOS recorded goldens and Linux verification on Paparazzi 1.3.4 (the newest version usable with Kotlin 1.9). Revisit with the Kotlin 2 / Paparazzi 1.3.5 upgrade, where the chat repo runs the default threshold. * Fix clipped and oversized snapshot goldens Stack the wide component snapshots vertically instead of side by side. The dark and light Row halves cap each side at half the device width, which clipped the base component button rows and the call control actions. Split the portrait and landscape grid renderer tests into their own classes (PortraitVideoRendererTest, LandscapeVideoRendererTest) kept on full device rendering, and enable RenderingMode.SHRINK on the remaining participant component tests so their goldens crop to content instead of capturing a full screen. * Split tall base component snapshots into light and dark files The stacked dark and light halves cap each theme at half the device height, which clipped the input fields and regular buttons goldens at the bottom. These two tests now record a separate golden per theme, like the full screen tests. * Share preview composables between @Preview wrappers and snapshot tests Every snapshot test now renders a shared internal preview composable that the matching @Preview wrapper in src/debug also renders, so IDE previews and goldens cannot drift apart. The test content is the source of truth: the shared functions contain exactly what the tests composed, and all golden files stay byte identical (verified by re-recording). The test classes move to src/testDebug, keeping their packages, class names, and method names, because tests that call src/debug internals must compile only against the debug variant. previewGridCall moves to src/debug so the grid previews can use it too. The microphone indicator preview is renamed to resolve a pre-existing name clash with the sound indicator preview. * Address CodeRabbit review findings Share a remote participant's screen in the 'for other participant' screen sharing previews. Both fixtures shared the local user's screen, so the two snapshots rendered the same state; the goldens now show the '<name> is Presenting' variant. Use the AutoMirrored icon variants in the button previews instead of the deprecated ones. Rendering is identical in LTR, so no golden changed.
…1778) Add VideoComponentFactory, a public interface with default implementations for the components behind the existing lambda slots on CallContent, ParticipantVideo, ControlActions, CallLobby, CallAppBar and the ringing screens. Each method takes a single params holder class, following the ChatComponentFactory convention from the chat SDK. The factory is provided through VideoTheme(componentFactory) and exposed via VideoTheme.componentFactory. CompoundComponentFactory allows layering overrides per subtree, and StreamCallActivityComposeDelegate exposes an overridable componentFactory used by the screens it renders. All existing lambda slots keep their signatures and now delegate to the factory by default, so the change is source compatible and the snapshot suite is unchanged. The new VideoTheme parameter does change its JVM signature, so consumers need a recompile against this version. The demo app shows a sample override: DemoComponentFactory replaces the inline reaction and participant-action lambdas in CallScreen and is also installed on the activity delegate.
…ry (#1785) * [AND-1441] Route the remaining internal render paths through VideoComponentFactory * [AND-1441] Extract the shared screen sharing fallback default
Bring develop into develop-v2: VideoComponentFactory, noise-cancellation SFU signaling, join analytics, and conventions 0.14.0, while keeping the v2 Kotlin 2.2 / StreamClient / WebRTC 137 stack. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
Contributor
SDK Size Comparison 📏
|
…teNative The develop merge took the m145 `-libwebrtc` Maven coordinate and createNative(any()) while keeping NC 2.0.0 / WebRTC 137, which broke CI resolve and unit-test compilation. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Aug 31, 2026
* Null-check the stop intent before stopService in cleanup * Cover both stop-intent branches of cleanup with Robolectric tests
Bring in the NC signal test hardening, join-after-relogin wait, and stopService null-check from develop, keeping the v2 StreamClient cleanup tests. Co-authored-by: Cursor <cursoragent@cursor.com>
|
| jobs: | ||
| pr-clean-stale: | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/pr-clean-stale.yaml@v0.13.1 | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/pr-clean-stale.yaml@v0.14.0 |
| jobs: | ||
| pr-checklist: | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/pr-quality.yml@v0.13.1 | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/pr-quality.yml@v0.14.0 |
| permissions: | ||
| contents: write | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/release.yml@v0.13.1 | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/release.yml@v0.14.0 |
| jobs: | ||
| compare-sdk-sizes: | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/sdk-size-checks.yml@v0.13.1 | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/sdk-size-checks.yml@v0.14.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Goal
resolves AND-1464
Bring
developup to date ondevelop-v2so v2 keeps the latest product, analytics, and CI work from the v1 line without abandoning the v2 architecture (Kotlin 2.2,StreamClient, Call decomposition, WebRTC 137).This is a follow-up to the previous develop→develop-v2 merge (#1761).
Implementation
origin/developintodevelop-v2and resolved ~116 conflicts.stream-android-core+StreamClient, WebRTC 137.1.1 and noise-cancellation 2.0.0 (did not take develop’s m145 / NC 3.0 / Kotlin 1.9 stack).VideoComponentFactoryand the Compose snapshot-test baseline (Introduce VideoComponentFactory as the component override mechanism #1778, Route the remaining internal render paths through VideoComponentFactory #1785, Snapshot test baseline for the Compose Video SDK #1776)wasPrevConnectedanalytics scope (Fix peer connection previous-connect analytics scope #1763)number-as-floatgenerator opt (Keep Float in generated OpenAPI models #1766)CHANGELOG.mdremoval (Remove CHANGELOG.md and all references to it from the repo #1779), SDK version 1.31.0Testing
:stream-video-android-core:compileDebugKotlin,:stream-video-android-ui-compose:compileDebugKotlin,:stream-video-android-previewdata:compileDebugKotlin— succeeded after conflict resolution:stream-video-android-core:apiDump/:stream-video-android-ui-compose:apiDump— regenerated./gradlew spotlessApply— required for the pre-push hookspotlessCheck+apiCheck— succeeded./gradlew test/./gradlew check— not run on the full suite after the merge; CI should cover thisVideoComponentFactoryrewires Compose slots, worth a smoke pass on lobby, incoming/outgoing, and screen-shareConflict-resolution notes for reviewers
☑️Contributor Checklist
General
developbranchThis PR targets
develop-v2, notdevelop.Code & documentation
stream-video-examples)Develop already shipped tests for NC signaling, VideoComponentFactory, and analytics; those land on v2 via this merge. Changelog file was removed on develop (#1779).
☑️Reviewer Checklist
Please smoke lobby / ringing / screen-share Compose paths because of
VideoComponentFactory.🎉 GIF
Skipped — merge/sync PR, no new user-facing animation.
Made with Cursor