Build on compileSdk/targetSdk 37 (Android 17): AGP 9.1 + Gradle 9.3 + Kotlin 2.2 - #1756
Build on compileSdk/targetSdk 37 (Android 17): AGP 9.1 + Gradle 9.3 + Kotlin 2.2#1756rahul-lohra wants to merge 15 commits into
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
The metrics module uses the plain `io.getstream.video.android.application` convention (not the `.compose` variant), so `configureAndroidCompose()` never runs and the Compose BOM is not applied. Its compose flavors added unversioned Compose artifacts (foundation, ui, ui-tooling) whose versions come from the BOM, so resolution failed with: Could not find androidx.compose.foundation:foundation: Add the BOM platform to each compose flavor's Implementation configuration so the unversioned artifacts resolve.
Pointing the baseline-profile output/source dir at src/main made AGP 9's prepareReleaseArtProfile recursively parse every file under it (res webp, *.kt) as ART profile rules, failing with "Illegal token". Use the default generated/baselineProfiles dir instead.
| jobs: | ||
| base-android-ci: | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/android-ci.yml@v0.13.1 | ||
| uses: GetStream/stream-build-conventions-android/.github/workflows/android-ci.yml@feature/rahullohra/build-on-sdk-37 |
| java-version: '21' # Paparazzi 2.0.0-alpha05 requires JDK 21. | ||
| distribution: temurin | ||
| - name: Setup Gradle | ||
| uses: gradle/actions/setup-gradle@v4 |
| 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.yml@feature/rahullohra/build-on-sdk-37 |
|
WalkthroughThe PR upgrades Gradle, AGP, Android SDK, dependencies, convention plugins, managed devices, CI Java versions, and Paparazzi support. It also adds a workflow for recording and uploading Paparazzi snapshots. ChangesAndroid build and validation upgrade
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant Gradle
participant Paparazzi
participant ArtifactStorage
GitHubActions->>Gradle: Run cleanRecordPaparazziDebug
Gradle->>Paparazzi: Generate golden snapshots
Paparazzi-->>Gradle: Write snapshot files
GitHubActions->>ArtifactStorage: Upload snapshot artifact
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 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: 2
🤖 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.
Inline comments:
In `@gradle/libs.versions.toml`:
- Line 11: Update gradle/libs.versions.toml:11 so streamConventions uses the
approved published AGP 9-compatible version instead of a SNAPSHOT. Update
settings.gradle.kts:8-21 to remove local-first/unrestricted snapshot plugin
resolution from the default merge path, or restrict it to an explicit
developer-only override.
In
`@stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/notifications/internal/receivers/GenericCallActionBroadcastReceiver.kt`:
- Line 85: Ensure the async broadcast is completed when streamCallId is missing:
update the handling around the streamCallId check in
GenericCallActionBroadcastReceiver so the pending result is finished before
logging and returning, or only invoke goAsync() in the branch that launches the
coroutine and finishes it.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 337ffc27-e2b9-46b4-9d66-3c0a1d16e0a0
⛔ Files ignored due to path filters (138)
stream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioCallContentTest_snapshot AudioCallContent in default state.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioCallContentTest_snapshot AudioCallContent without header.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioCallContentTest_snapshot AudioOnlyCallContent in default state.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioCallContentTest_snapshot AudioOnlyCallContent without header.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioCallContentTest_snapshot_AudioCallContent_in_default_state.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioCallContentTest_snapshot_AudioCallContent_without_header.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot AudioAppBar composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot AudioControlActions composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot AudioParticipantsGrid composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot AudioRoom DarkMode composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot AudioRoom composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot_AudioAppBar_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot_AudioControlActions_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AudioRoomTest_snapshot_AudioParticipantsGrid_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AvatarTest_snapshot AvatarInitial composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AvatarTest_snapshot UserAvatar composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AvatarTest_snapshot_AvatarInitial_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_AvatarTest_snapshot_UserAvatar_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Badges with buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Badges_with_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Button with icons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Button_with_icons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Different size buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Different_size_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Generic container (for info messages).pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Generic_container_(for_info_messages).pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Input fields.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Input_fields.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Regular buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Regular icon buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Regular_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Regular_icon_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Show progress into icon buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Show_progress_into_icon_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Toggle buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Toggle icon buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Toggle_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_BaseComponentsTest_Toggle_icon_buttons.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_snapshot CallAppBar composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_snapshot CallControls composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_snapshot RegularCallControls composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_snapshot_CallAppBar_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_snapshot_CallControls_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallComponentsPortraitTest_snapshot_RegularCallControls_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot CallContent with multiple participants composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot IncomingCallContent Video type with multiple participants composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot IncomingCallContent with minimum parameters.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot IncomingCallContent with one participant composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot IncomingCallContentDetails Audio composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot IncomingCallContentDetails Video composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot IncomingCallOptions composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallContent with minimum parameters and audio type.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallContent with minimum parameters and video type.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallContent with multiple participants composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallContent with one participant composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallDetails Audio composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallDetails Video composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot OutgoingCallOptions composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_CallContent_with_multiple_participants_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_IncomingCallContentDetails_Audio_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_IncomingCallContentDetails_Video_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_IncomingCallContent_Video_type_with_multiple_participants_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_IncomingCallContent_with_minimum_parameters.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_IncomingCallContent_with_one_participant_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_IncomingCallOptions_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallContent_with_minimum_parameters_and_audio_type.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallContent_with_minimum_parameters_and_video_type.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallContent_with_multiple_participants_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallContent_with_one_participant_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallDetails_Audio_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallDetails_Video_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallContentTest_snapshot_OutgoingCallOptions_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallControlsTest_snapshot CallControls Actions composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallControlsTest_snapshot CallControls composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallControlsTest_snapshot_CallControls_Actions_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallControlsTest_snapshot_CallControls_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallLobbyTest_snapshot CallLobby composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_CallLobbyTest_snapshot_CallLobby_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_IndicatorsTest_snapshot Connection ConnectionQualityIndicator composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_IndicatorsTest_snapshot Connection ParticipantLabel composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_IndicatorsTest_snapshot SoundIndicator composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_IndicatorsTest_snapshot_Connection_ConnectionQualityIndicator_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_IndicatorsTest_snapshot_Connection_ParticipantLabel_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_IndicatorsTest_snapshot_SoundIndicator_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_LivestreamTest_snapshot Livestream Player Overlay composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_LivestreamTest_snapshot Livestream Player composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_LivestreamTest_snapshot_Livestream_Player_Overlay_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_LivestreamTest_snapshot_Livestream_Player_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeParticipants1 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeParticipants2 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeParticipants3 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeParticipants4 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeParticipants5 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeParticipants6 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeScreenSharingContent for myself composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot LandscapeScreenSharingContent for other participant composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot ParticipantsRow composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot_LandscapeParticipants4_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot_LandscapeParticipants5_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot_LandscapeParticipants6_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot_LandscapeScreenSharingContent_for_myself_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot_LandscapeScreenSharingContent_for_other_participant_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantLandscapeTest_snapshot_ParticipantsRow_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot CallParticipant a local call composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot CallParticipant a remote call composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot CallParticipantsInfoAppBar composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot CallParticipantsInfoOptions composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot CallParticipantsList composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot InviteUserList composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot LocalVideoContent composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot ParticipantAvatars composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot ParticipantInformation composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot ParticipantVideo composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot ParticipantsColumn composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitParticipants1 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitParticipants2 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitParticipants3 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitParticipants4 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitParticipants5 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitParticipants6 composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitScreenSharingContent for myself composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot PortraitScreenSharingContent for other participant composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_CallParticipant_a_local_call_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_CallParticipant_a_remote_call_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_CallParticipantsInfoAppBar_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_CallParticipantsInfoOptions_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_CallParticipantsList_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_InviteUserList_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_LocalVideoContent_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_ParticipantAvatars_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_ParticipantInformation_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_ParticipantVideo_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_ParticipantsColumn_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_PortraitParticipants4_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_PortraitParticipants5_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_PortraitParticipants6_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_PortraitScreenSharingContent_for_myself_composable.pngis excluded by!**/*.pngstream-video-android-ui-compose/src/test/snapshots/images/io.getstream.video.android.compose_ParticipantsPortraitTest_snapshot_PortraitScreenSharingContent_for_other_participant_composable.pngis excluded by!**/*.png
📒 Files selected for processing (29)
.github/workflows/android.yml.github/workflows/app-distribute.yml.github/workflows/e2e-build.yml.github/workflows/e2e-test-cron.yml.github/workflows/e2e-test.yml.github/workflows/internal-app-distribute.yml.github/workflows/record-paparazzi.yml.github/workflows/sdk-size-checks.ymlbenchmark/build.gradle.ktsbuild-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.ktbuild-logic/convention/src/main/kotlin/io/getstream/video/AndroidCompose.ktbuild-logic/convention/src/main/kotlin/io/getstream/video/DemoFlavor.ktbuild-logic/convention/src/main/kotlin/io/getstream/video/KotlinAndroid.ktbuild.gradle.ktsdemo-app/build.gradle.ktsgradle.propertiesgradle/libs.versions.tomlgradle/wrapper/gradle-wrapper.propertiesmetrics/stream-video-android-metrics/build.gradle.ktssettings.gradle.ktsstream-video-android-core/build.gradle.ktsstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoClient.ktstream-video-android-core/src/main/kotlin/io/getstream/video/android/core/notifications/internal/receivers/GenericCallActionBroadcastReceiver.ktstream-video-android-core/src/test/resources/robolectric.propertiesstream-video-android-ui-compose/api/stream-video-android-ui-compose.apistream-video-android-ui-compose/build.gradle.ktsstream-video-android-ui-compose/src/debug/java/com/android/org/conscrypt/TrustManagerImpl.javastream-video-android-ui-compose/src/test/java/com/android/org/conscrypt/TrustManagerImpl.javastream-video-android-ui-compose/src/test/resources/robolectric.properties
| cameraCamera2 = "1.3.4" | ||
| spotless = "6.21.0" | ||
| streamConventions = "0.13.1" | ||
| streamConventions = "0.13.2-SNAPSHOT" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🌐 Web query:
What published non-SNAPSHOT version of the io.getstream.projectGradle plugin is compatible with Android Gradle Plugin 9.1.1? Confirm whether version0.13.2 is published.
💡 Result:
The io.getstream.project Gradle plugin version 0.13.2 is not confirmed to be published; search results only verify the existence and publication of versions up to 0.13.1 [1]. There is no publicly documented information specifying a direct compatibility mapping between specific versions of the io.getstream.project plugin and Android Gradle Plugin (AGP) 9.1.1. The plugin, which serves as a collection of build conventions (stream-build-conventions-android), is typically updated by the Stream team to support newer AGP versions as they are released [2][3][4]. To use the latest available features or compatibility, it is recommended to check the official GetStream GitHub repository for the most recent releases [2][5][6].
Citations:
- 1: GetStream/stream-chat-android-ai@1180798
- 2: https://github.com/GetStream/stream-build-conventions-android
- 3: Configure publishing through convention plugins stream-chat-android#6129
- 4: Bump Android Gradle Plugin to 8.10.1 and Gradle wrapper to 8.11.1 #1723
- 5: Bump the stream-conventions group and update dependabot config stream-core-android#70
- 6: Bump streamConventions from 0.11.0 to 0.12.1 stream-core-android#67
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== git status =="
git status --short
echo "== gradle/libs.versions.toml relevant lines =="
nl -ba gradle/libs.versions.toml | sed -n '1,35p;235,255p'
echo "== settings.gradle.kts relevant lines =="
nl -ba settings.gradle.kts | sed -n '1,45p'
echo "== declarations / usages of streamConventions =="
rg -n "streamConventions|gradlePluginPortal|mavenLocal|io\.getstream|AGP 9|androidGradlePlugin|agp" -S --glob '!build/**' --glob '!**/build/**' .
echo "== repository availability checks without executing repo code =="
python3 - <<'PY'
import urllib.request, urllib.error
for url in [
"https://plugins.gradle.org/m2/io/getstream/project/io.getstream.project.gradle.plugin/0.13.2/",
"https://plugins.gradle.org/m2/io/getstream/project/io.getstream.project.gradle.plugin/0.13.1/",
"https://repo1.maven.org/maven2/io/getstream/stream-build-conventions-android/0.13.2/",
"https://central.sonatype.com/repository/maven-snapshots/io/getstream/stream-build-conventions-android/0.13.2-SNAPSHOT/",
]:
req = urllib.request.Request(url, method="HEAD")
try:
with urllib.request.urlopen(req, timeout=20) as r:
print(url, r.status, r.headers.get("Content-Type"))
except urllib.error.HTTPError as e:
print(url, e.code, e.reason)
except Exception as e:
print(url, type(e).__name__, e)
PYRepository: GetStream/stream-video-android
Length of output: 272
🌐 Web query:
GetStream stream-build-conventions-android 0.13.2 published Gradle plugin
💡 Result:
The GetStream stream-build-conventions-android Gradle plugin version 0.13.2 does not appear to be a published release. Publicly available information and dependency update records (such as those from Dependabot and repository pull requests) indicate that the project release series reached at least version 0.13.1 [1][2], but there is no verified evidence of a 0.13.2 version being published or tagged [3][1]. Development activity on the repository shows subsequent commits following 0.13.1, but these have not culminated in a 0.13.2 release in the public ecosystem [3][1].
Citations:
- 1: Bump GetStream/stream-build-conventions-android/.github/workflows/release.yml from 0.12.1 to 0.13.1 stream-chat-android-ai#33
- 2: https://github.com/GetStream/stream-feeds-android/blob/develop/.github/workflows/publish-snapshot.yml
- 3: Bump the stream-conventions group and update dependabot config stream-core-android#70
🏁 Script executed:
#!/bin/bash
set -euo pipefail
pwd
echo "== available repo files =="
test -f gradle/libs.versions.toml && echo "gradle/libs.versions.toml exists" || echo "gradle/libs.versions.toml missing"
test -f settings.gradle.kts && echo "settings.gradle.kts exists" || echo "settings.gradle.kts missing"
echo "== gradle/libs.versions.toml relevant lines =="
awk 'NR>=1 && NR<=35 || NR>=235 && NR<=255 { printf "%3d\t%s\n", NR, $0 }' gradle/libs.versions.toml || true
echo "== settings.gradle.kts relevant lines =="
awk 'NR>=1 && NR<=45 { printf "%3d\t%s\n", NR, $0 }' settings.gradle.kts || true
echo "== relevant declarations/usages =="
rg -n "streamConventions|gradlePluginPortal|mavenLocal|io\.getstream|androidGradlePlugin|agp" gradle/libs.versions.toml settings.gradle.kts -S || true
echo "== repository artifact availability checks =="
python3 - <<'PY'
import urllib.request, urllib.error
for url in [
"https://plugins.gradle.org/m2/io/getstream/project/io.getstream.project.gradle.plugin/0.13.2/",
"https://plugins.gradle.org/m2/io/getstream/project/io.getstream.project.gradle.plugin/0.13.1/",
"https://repo1.maven.org/maven2/io/getstream/stream-build-conventions-android/0.13.2/",
"https://central.sonatype.com/repository/maven-snapshots/io/getstream/stream-build-conventions-android/0.13.2-SNAPSHOT/maven-metadata.xml",
]:
req = urllib.request.Request(url, method="HEAD", headers={"User-Agent":"coderbob/verification"})
try:
with urllib.request.urlopen(req, timeout=20) as r:
print(url, r.status, r.headers.get("Content-Type"))
except urllib.error.HTTPError as e:
print(url, e.code, e.reason)
except Exception as e:
print(url, type(e).__name__, e)
PYRepository: GetStream/stream-video-android
Length of output: 9671
🌐 Web query:
"streamConventions" "gradle/libs.versions.toml"
💡 Result:
In the context of projects maintained by GetStream (such as stream-video-android and stream-chat-android), streamConventions is a version variable defined within the Gradle version catalog (gradle/libs.versions.toml) [1][2]. It serves as the centralized versioning reference for a suite of internal Gradle convention plugins [2][3]. These plugins are designed to standardize build configurations—such as SDK versions, publishing settings, and linting—across various modules to avoid duplication and ensure consistency [2][3][4]. Key details regarding its usage include: 1. Centralized Versioning: By declaring streamConventions = "" in the [versions] table of libs.versions.toml, the project maintains a single source of truth for the plugin suite version [2]. 2. Plugin Mapping: In the [plugins] table of the same file, multiple convention plugins are referenced using this version key [1][5]: - stream-project (id = "io.getstream.project") - stream-android-application (id = "io.getstream.android.application") - stream-android-library (id = "io.getstream.android.library") - stream-android-test (id = "io.getstream.android.test") - stream-java-library (id = "io.getstream.java.library") - stream-java-platform (id = "io.getstream.java.platform") 3. Implementation: These plugins are typically developed within an included build (often located in a build-logic/ directory) [2][4]. They are not intended for general-purpose use by external projects, as they contain specific configurations tailored to GetStream's internal workflows [3].
Citations:
- 1: https://github.com/GetStream/stream-video-android/blob/94feaeaf/gradle/libs.versions.toml
- 2: https://deepwiki.com/GetStream/stream-video-android/5-build-system-and-configuration
- 3: https://github.com/GetStream/stream-build-conventions-android
- 4: https://deepwiki.com/GetStream/stream-video-android/5.1-module-structure-and-dependencies
- 5: GetStream/stream-core-android@db8e7e0
🌐 Web query:
"streamConventions" "0.13.2-SNAPSHOT"
💡 Result:
The term streamConventions refers to a suite of Gradle build convention plugins and shared GitHub Actions workflows maintained by GetStream, located in the repository GetStream/stream-build-conventions-android [1][2][3]. These plugins are used to standardize build configurations, dependency management, publishing, and CI/CD pipelines across various GetStream Android and Java projects [3][4][5]. The version string 0.13.2-SNAPSHOT represents a development (snapshot) build of this library, which typically follows the release of version 0.13.0 [1][6]. Developers commonly reference these conventions in their projects using version catalogs (e.g., gradle/libs.versions.toml) and by referencing the reusable workflow actions in their.github/workflows/ directory [3][7]. As of August 2026, these conventions are actively used to manage tasks such as Maven publishing, spotless code formatting, and automated dependency updates via Dependabot [1][3][5].
Citations:
- 1: Bump the stream-conventions group and update dependabot config stream-chat-android-ai#32
- 2: Bump the stream-conventions group and update dependabot config stream-core-android#70
- 3: Bump Stream conventions to v0.12.1 stream-core-android#64
- 4: Configure publishing through convention plugins stream-chat-android#6129
- 5: Upgrade streamConventions to 0.10.0 stream-chat-android-ai#17
- 6: Chore(deps): Bump the stream-conventions group and update dependabot config #1692
- 7: GetStream/stream-core-android@65197f8
Use a published Stream Conventions version for merge builds.
This catalog entry points Stream plugins to a non-public SNAPSHOT, and settings.gradle.kts makes local io.getstream artifacts take precedence over resolved builds. Use the approved published AGP 9-compatible version for streamConventions, and remove local-first/unrestricted snapshot resolution from the default merge path.
gradle/libs.versions.toml#L11: setstreamConventionsto a published compatible version.settings.gradle.kts#L8-L21: remove local-first plugin resolution for merge builds, or make it an explicit developer-only override.
📍 Affects 2 files
gradle/libs.versions.toml#L11-L11(this comment)settings.gradle.kts#L8-L21
🤖 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 `@gradle/libs.versions.toml` at line 11, Update gradle/libs.versions.toml:11 so
streamConventions uses the approved published AGP 9-compatible version instead
of a SNAPSHOT. Update settings.gradle.kts:8-21 to remove
local-first/unrestricted snapshot plugin resolution from the default merge path,
or restrict it to an explicit developer-only override.
| } | ||
| } else { | ||
| logger.w(createMessage(intentAction, "Stream call ID is not provided.")) | ||
| logger.w(message = createMessage(intentAction, "Stream call ID is not provided.")) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 10 'goAsync\(\)|pendingResult\.finish\(\)|streamCallId != null' \
stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/notifications/internal/receivers/GenericCallActionBroadcastReceiver.ktRepository: GetStream/stream-video-android
Length of output: 2373
🌐 Web query:
Android BroadcastReceiver goAsync finish pending result documentation
💡 Result:
The goAsync method in an Android BroadcastReceiver allows you to defer the completion of a broadcast beyond the return of the onReceive method [1][2]. This is useful for moving long-running operations off the main thread to avoid UI jank [1][3]. When you call goAsync, it returns a BroadcastReceiver.PendingResult object [1][4]. This object represents the active broadcast and must be held until your background work is complete [4][5]. Once your processing is finished, you must call the PendingResult.finish method to inform the system that the broadcast is done and the receiver can be recycled [4][6]. Key considerations include: 1. Time Limits: Even when using goAsync, the broadcast execution time is still limited. The system generally allows up to 10 seconds for the entire operation (including the time spent inside onReceive before calling goAsync and the time until finish is called) [1][2][3]. 2. Threading: The BroadcastReceiver.PendingResult object is not thread-safe, but you can safely pass it to another thread to perform work [4][5]. That thread becomes responsible for calling finish [4][5]. 3. Best Practices: Because of the strict time limits, goAsync is intended for short, immediate tasks. For longer-running background work, the system recommends using other facilities like WorkManager, JobScheduler, or a Service instead [2][3]. Example usage pattern: val pendingResult = goAsync Thread { try { // Perform background work here } finally { pendingResult.finish } }.start
Citations:
- 1: https://developer.android.com/reference/kotlin/android/content/BroadcastReceiver
- 2: https://developer.android.com/reference/android/content/BroadcastReceiver
- 3: https://developer.android.com/develop/background-work/background-tasks/broadcasts
- 4: https://developer.android.com/reference/kotlin/android/content/BroadcastReceiver.PendingResult
- 5: https://android.googlesource.com/platform/frameworks/base/+/HEAD/core/java/android/content/BroadcastReceiver.java
- 6: https://stackoverflow.com/questions/22741202/how-to-use-goasync-for-broadcastreceiver
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,110p' stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/notifications/internal/receivers/GenericCallActionBroadcastReceiver.ktRepository: GetStream/stream-video-android
Length of output: 4552
Finish the async broadcast also when the call ID is missing.
goAsync() is called before the streamCallId != null check, but the else branch at line 85 only logs and returns without calling pendingResult.finish(). Move goAsync() into the branch where the coroutine finishes the result, or finish the pending result before logging this branch.
🤖 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/notifications/internal/receivers/GenericCallActionBroadcastReceiver.kt`
at line 85, Ensure the async broadcast is completed when streamCallId is
missing: update the handling around the streamCallId check in
GenericCallActionBroadcastReceiver so the pending result is finished before
logging and returning, or only invoke goAsync() in the branch that launches the
coroutine and finishes it.




Goal
Closes #AND-1342
Raise compileSdk/targetSdk from 35 → 37 (Android 17). The installed platform is the stable, minor-versioned android-37.0, which the old toolchain (AGP 8.5.2) cannot even resolve (Failed to find Platform SDK … android-37). API 37 has a hard floor of AGP 9.1, and AGP 9 drops Kotlin 1.9 — so this is necessarily a full toolchain upgrade, not a one-line SDK bump.
Note: this PR depends on the GetStream/stream-build-conventions-android#70 — streamConventions must point at a published version that supports AGP 9 (currently 0.13.2-SNAPSHOT in the catalog; pin to the released version before merge).
Implementation
Toolchain Updates
compileSdk/targetSdkandroid.suppressUnsupportedCompileSdkDependency bumps forced by Gradle 9 / AGP 9
TestExtensionstreamConventions(build-conventions plugin)CommonExtensionstream-log-androidio.getstream.logas AGP 9 gives hard error if two different libraries share same namespaceDependent Stream Repositories
CommonExtension.We need support for Java 21 (the version will be updated soon)Library Specific Updates
Paparazzi
Robolectric
🎨 UI Changes
None
Testing
WIP
Summary by CodeRabbit
New Features
Bug Fixes
Chores